Jump to content

Get Date from Week Number


yodasoja
 Share

Recommended Posts

I am trying to use some code that asks for the year and week number, then the program is supposed to subtract 26 weeks from the current week (that the user input) and find the Sunday date of that week (first day of week).

I'd like this date so I can report the range from 26 weeks ago to the week the user input.

The end product would be something in the format of "Jan 08 - Jun 12" Where the year isn't important, so this can work even when the current week is < the 26th week of the current year.

I know the Date.au3 has a _WeekNumberISO() function, but I'd like exactly the opposite of that. I'd like to input the week number and get the date.
Does anyone know if such a method already exists?

 

I figured out I could use the _DateAdd() function and just say _DateAdd('w', -26) to go back 26 weeks, but I still need a way of converting the week number that was input by the user to a Date that I can use for thie _DateAdd() function.

Edited by yodasoja
Link to comment
Share on other sites

$ weeks = guictrlread ($ userinput)
$ newdate = _dateadd ('w', ($ weeks - 26) )

That would be my best guess. Here's example from help document

 

#include <Date.au3>
$day =  ""
$week = guictrlread($userinputweek)
$month = ""
$year = ""
$newdate = _DateAdd('w',($week - 26), $year & "/" & $month & "/" & $day)

func FindLastSunday()

;add script here lol


endfunc





; Add 5 days to today
Local $sNewDate = _DateAdd('d', 5, _NowCalcDate())
MsgBox(4096, "", "Today + 5 days:" & $sNewDate)

; Subtract 2 weeks from today
$sNewDate = _DateAdd('w', -2, _NowCalcDate())
MsgBox(4096, "", "Today minus 2 weeks: " & $sNewDate)

; Add 15 minutes to current time
$sNewDate = _DateAdd('n', 15, _NowCalc())
MsgBox(4096, "", "Current time +15 minutes: " & $sNewDate)

; Calculated eventlogdate which returns second since 1970/01/01 00:00:00
$sNewDate = _DateAdd('s', 1087497645, "1970/01/01 00:00:00")
MsgBox(4096, "", "Date: " & $sNewDate) 

as far as finding the last sunday...... thats kinda difficult if you want to be 100% accurate.  there are roundabout methods that would get you there quickly but its not really something that I want to mess around with atm  found this it may help you http://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week

Edited by markyrocks
Link to comment
Share on other sites

this is completely untested and may not work at all and its really not ment to be a functioning script just my best attempt to lay down a base of a script.  mind you it only took me like 20 min to come up with this so i'm sure theres errors in it and my logic may not  be 100% on point but check it out (I did this for my own learning experience)

#include <Date.au3>

$week = guictrlread($userinputweek)
$day = IsInt($week * 7)/12
$month = IsInt($week/4.25)
$monthLongName = _DateToMonth($monthnum)

$year = GUICtrlRead($userinputyear)
$newdate = _DateAdd('w',($weeks - 26), $year & "/" & $month & "/" & $day)
$enteredDate = $year & "/" & $month & "/" & $day
func FindLastSunday()
 
   $diffday = _DateDiff('D', $newdate, $enteredDate)
   if $diffday > 365 Then
   $dayOfYear = $day - (mod($diffday,365))
ElseIf $diffday < 365 Then
   $dayOfYear = $day - $diffday
endif
$diffmon = _DateDiff('M', $newdate, $enteredDate)
if $diffmon > 12 Then
   $sMonth = $month - (mod($diffmon,12)
elseif $diffmon < 12 Then
   $sMonth = $month - $diffmon
EndIf
$diffyear = _DateDiff('Y',$newdate,$enteredDate)
if $year > @YEAR Then
$sYear = $sYear + $diffyear
elseif $year < @YEAR Then
   $sYear = $sYear - $diffyear
   EndIf

$dayOfWeekNumber = _DateToDayOfWeek($sYear, $sMonth, $dayOfYear)
$difference = 0
do 
if $dayOfWeekNumber > 1 Then
$dayOfWeekNumber -= 1
$difference += 1
EndIf


until $dayOfWeekNumber = 1
$dayOfYear = $dayOfYear - $difference      ;this day should be the previous sunday to the information entered by the uSer or 




endfunc
Link to comment
Share on other sites

From here we have, "The first week of a year is the week that contains the first Thursday of the year".

Using the AutoIt's _WeekNumberISO function, the first week appears to start on the  Monday before the first Thursday in the new year.

This means that Sunday is the last day of the week.

So the Sunday before the week number entered will be in the last day of the  previous week.

#include <Date.au3>

Local $iWeekNum = 1
Local $Year = 2014

Local $s = _DateFromWeekNumber($Year, $iWeekNum)
Local $sBefore = _DateAdd("D", -1, $s) ; First Sunday before first date of chosen week
Local $sDateMinus26W = _DateAdd("w", -26, $sBefore) ; 26 weeks before the $sBefore date. (another Sunday)

ConsoleWrite(_DateFormat($sDateMinus26W, "MMM dd") & " - " & _DateFormat($sBefore, "MMM dd") & @LF)
;Returns:- Jun 30 - Dec 29


; The week with the first Thursday of the year is week number 1.
Func _DateFromWeekNumber($iYear, $iWeekNum)
    Local $Date, $sFirstDate = _DateToDayOfWeek($iYear, 1, 1)
    If $sFirstDate < 6 Then
        $Date = _DateAdd("D", 2 - $sFirstDate, $iYear & "/01/01")
    ElseIf $sFirstDate = 6 Then
        $Date = _DateAdd("D", $sFirstDate - 3, $iYear & "/01/01")
    ElseIf $sFirstDate = 7 Then
        $Date = _DateAdd("D", $sFirstDate - 5, $iYear & "/01/01")
    EndIf
    ;ConsoleWrite(_DateToDayOfWeek($iYear, 1, 1) &"  ")
    Local $aDate = StringSplit($Date, "/", 2)
    Return _DateAdd("w", $iWeekNum - 1, $aDate[0] & "/" & $aDate[1] & "/" & $aDate[2])
EndFunc   ;==>_DateFromWeekNumber

; Format date
; $sDate, input date in the format yyyy/MM/dd[ hh:mm:ss]
Func _DateFormat($sDate, $sFormat)
    $hGui = GUICreate("")
    $idDate = GUICtrlCreateDate($sDate, 10, 10)
    GUICtrlSendMsg($idDate, 0x1032, 0, $sFormat) ; or "dddd, MMMM d, yyyy hh:mm:ss tt"); or "hh:mm tt"
    $FormatedDate = GUICtrlRead($idDate)
    GUIDelete($hGui)
    Return $FormatedDate
EndFunc   ;==>_FormatDate

I used this example to test the _DateFromWeekNumber($iYear, $iWeekNum) function.

#include <Date.au3>

Local $iWeekNum = 1
Local $Year ;= 2009
For $Year = 1990 To 2014
    Local $s = _DateFromWeekNumber($Year, $iWeekNum)
    ConsoleWrite("Start of week #" & $iWeekNum & " of year " & $Year & ' is "' & $s & '".  ')
    Local $sBefore = _DateAdd("D", -1, $s)
    Local $aBefore = StringSplit($sBefore, "/", 2)
    Local $a = StringSplit($s, "/", 2)
    Local $sAfter = _DateAdd("D", 1, $s)
    Local $aAfter = StringSplit($sAfter, "/", 2)

    ConsoleWrite('Day before, "' & $sBefore & '" is in Week #' & _WeekNumberISO($aBefore[0], $aBefore[1], $aBefore[2]) & "  " & _
            $s & " is in Week #" & _WeekNumberISO($a[0], $a[1], $a[2]) & "   " & _
            'Day after, "' & $sAfter & '" is in Week #' & _WeekNumberISO($aAfter[0], $aAfter[1], $aAfter[2]) & " " & _
            'Day of week, "' & _DateToDayOfWeek($a[0], $a[1], $a[2]) &@CRLF)
Next

; The week with the first Thursday of the year is week number 1.
Func _DateFromWeekNumber($iYear, $iWeekNum)
    Local $Date, $sFirstDate = _DateToDayOfWeek($iYear, 1, 1)
    If $sFirstDate < 6 Then
        $Date = _DateAdd("D", 2 - $sFirstDate, $iYear & "/01/01")
    ElseIf $sFirstDate = 6 Then
        $Date = _DateAdd("D", $sFirstDate - 3, $iYear & "/01/01")
    ElseIf $sFirstDate = 7 Then
        $Date = _DateAdd("D", $sFirstDate - 5, $iYear & "/01/01")
    EndIf
    ;ConsoleWrite(_DateToDayOfWeek($iYear, 1, 1) &"  ")
    Local $aDate = StringSplit($Date, "/", 2)
    Return _DateAdd("w", $iWeekNum - 1, $aDate[0] & "/" & $aDate[1] & "/" & $aDate[2])
EndFunc   ;==>_DateFromWeek
Link to comment
Share on other sites

This is what I came up with.  Easily changed to add Sunday of current week.  All I was trying to do was get Sunday from 26 weeks ago. Should clean up the code a little cause I just kept throwing variables in and formatting date to get answer.

#include <DateTimeConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Date.au3>
GUICreate("Date", 236, 117)
$Date = GUICtrlCreateDate(_NowCalc(), 8, 8, 217, 33, $DTS_SHORTDATEFORMAT)
$Label = GUICtrlCreateLabel("", 0, 56, 235, 17, $SS_CENTER)
$Button = GUICtrlCreateButton("Find", 90, 80, 60)
GUISetState(@SW_SHOW)


While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button
            Local $DateFormat[4]
            $DateFormat = StringSplit(GUICtrlRead($Date), "/")
            $sNewDate = _DateAdd('w', -26, $DateFormat[3]&"/"&$DateFormat[1]&"/"&$DateFormat[2])
            $CurrentDayofWeek = _DateToDayOfWeek($DateFormat[3], $DateFormat[1], $DateFormat[2])
            If $CurrentDayofWeek > 1 Then
                For $i = 2 To 7
                    If $i = $CurrentDayofWeek Then
                        $subtract = $i - 1
                        ExitLoop
                    EndIf
                Next
            Else
                $subtract = 0
            EndIf
            $sNewDate = _DateAdd('d', $subtract*-1 , $sNewDate)
            $DateFormat = StringSplit($sNewDate, "/")
            GUICtrlSetData($Label, $DateFormat[2]&"/"&$DateFormat[3]&"/"&$DateFormat[1])
    EndSwitch
WEnd

Also while eating, watching TV and typing this, 2 others have posted which may be better but I already did this so thought I would share.

Edit: You can always change the format of the date to what you want the end to be. This is just to get you started on the right path.

Went ahead and finished it.... Wasn't too far away from finishing it anyways:

#include <DateTimeConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Date.au3>
GUICreate("Date", 236, 117)
$Date = GUICtrlCreateDate(_NowCalc(), 8, 8, 217, 33, $DTS_SHORTDATEFORMAT)
$Label = GUICtrlCreateLabel("", 0, 56, 235, 17, $SS_CENTER)
$Button = GUICtrlCreateButton("Find", 90, 80, 60)
GUISetState(@SW_SHOW)


While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button
            $FirstSunday = _FindSundays(GUICtrlRead($Date), -26)
            $LastSunday = _FindSundays(GUICtrlRead($Date), 0)
            GUICtrlSetData($Label, $FirstSunday & " - " & $LastSunday)
    EndSwitch
WEnd

Func _FindSundays($CurrentDate, $Week)
    $DateFormat = StringSplit(GUICtrlRead($Date), "/")
    $sNewDate = _DateAdd('w', $Week, $DateFormat[3]&"/"&$DateFormat[1]&"/"&$DateFormat[2])
    $CurrentDayofWeek = _DateToDayOfWeek($DateFormat[3], $DateFormat[1], $DateFormat[2])
    If $CurrentDayofWeek > 1 Then
        For $i = 2 To 7
            If $i = $CurrentDayofWeek Then
                $subtract = $i - 1
                ExitLoop
            EndIf
        Next
    Else
        $subtract = 0
    EndIf
    $sNewDate = _DateAdd('d', $subtract*-1 , $sNewDate)
    $DateFormat = StringSplit($sNewDate, "/")
    Return _DateToMonth($DateFormat[2], 1) & " " & $DateFormat[3] & ", " & $DateFormat[1]
EndFunc
Edited by Rogue5099
Link to comment
Share on other sites

Ok I had a lil time to refine this.  I thought about it during the day today and I realized My first attempt at the script was overly complicated.  But I figured out why and this is currently working.  So here goes dude.

#include <Date.au3>

$week = 13 ;this is obviously user input

$div = 365/12
 $day = Floor(($week * 7)/$div)
if $day < 1 Then
   $day = 1
EndIf

$month = Floor($week/4.25)
if $month < 1 Then
   $month = 1
EndIf

$year = 1976 ;userinput as well
$date = $year & "/" & $month & "/" & $day
MsgBox("","","(yyyy/mm/dd) Entered Date " & $date)

if $week < 26 Then
   $year -= 1
   $week = 52 - $week
Else
   $week = $week - 26
   EndIf



;~ MsgBox("","","week= " & $week)
$day = Floor(($week * 7)/$div)
if $day < 1 Then
   $day = 1
EndIf

$month = Floor($week/4.25)
;~ MsgBox("","","month " & $month)
if $month < 1 Then
   $month = 1
EndIf
$newdate = $year & "/" & $month & "/" & $day
MsgBox("","","(yyyy/mm/dd) newdate " & $newdate)


;~ MsgBox("","","newdate " & $newdate)
;~ $enteredDate = 
FindLastSunday($newdate)
func FindLastSunday($newdate)
   $sString = StringSplit($newdate,"/")
 Do
$valid = _DateIsValid($newdate)
if $valid = 0 Then
   $sString[3] -= 1
EndIf
Until $valid = 1   ;then we have a valid date



$dayOfWeekNumber = _DateToDayOfWeek($sString[1], $sString[2], $sString[3])
$difference = 0
do 
if $dayOfWeekNumber > 1 Then
$dayOfWeekNumber -= 1
$difference += 1
EndIf
until $dayOfWeekNumber = 1

$sString[3] = $sString[3] - $difference     

;contingency plan if the above calculation makes the day <= 0
if $sString[3] = 0 Then
   $sString[2] -= 1
   $sString[3] = 31
  elseif $sString[3] = -1 Then
   $sString[2] -= 1
   $sString[3] = 30
    elseif $sString[3] = -2 Then
   $sString[2] -= 1
   $sString[3] = 29
    elseif $sString[3] = -3 Then
   $sString[2] -= 1
   $sString[3] = 28
    elseif $sString[3] = -4 Then
   $sString[2] -= 1
   $sString[3] = 27
    elseif $sString[3] = -5 Then
   $sString[2] -= 1
   $sString[3] = 26
    elseif $sString[3] = -6 Then
   $sString[2] -= 1
   $sString[3] = 25
EndIf
;make sure we have a valid date.....
$LastSundayDate = $sString[1] & "/" & $sString[2] & "/" & $sString[3]
Do
$valid = _DateIsValid($LastSundayDate)
if $valid = 0 Then
   $sString[3] -= 1
EndIf
Until $valid = 1   ;then we have a valid date

;now after all that we need to reconfirm that the day is actually sunday........!BULLSHIT
$dayOfWeekNumber = _DateToDayOfWeek($sString[1], $sString[2], $sString[3])
$difference = 0
do 
if $dayOfWeekNumber > 1 Then
$dayOfWeekNumber -= 1
$difference += 1
EndIf
until $dayOfWeekNumber = 1
$sString[3] = $sString[3] - $difference

$LastSundayDate = $sString[1] & "/" & $sString[2] & "/" & $sString[3]
Do
$valid = _DateIsValid($LastSundayDate)
if $valid = 0 Then
   $sString[3] -= 1
EndIf
Until $valid = 1   ;then we have a valid date
$LastSundayDate = $sString[2] & "/" & $sString[3] & "/" & $sString[1]    ;rearrange

MsgBox("","Sunday Date","(mm/dd/yyyy) Sunday = " & $LastSundayDate)



endfunc
 

O the only thing that is weird here is the function _DateAdd() returns a result that is like this yyyy/mm/dd so i kinda kept that format till the end and when the $LastSundayDate is displayed it uses that format but it could easily be switched to mm/dd/yyyy by making $LastSundayDate = $sString[2] & "/" & $sString[3] & "/" & $sString[1]

edit.  I realized wasn't working right with the _DateAdd function.  Doesnt seem to work well it reverse so I just eliminated it entirely that and i realized isint() was only returning like a 1 or a 0 not an actual integer...

edit ... added contingency for the $sString[3] (day) <= 0 but i  just realized thats still not right because it could potentially be down to -6 so my fix here is wrong.  Also I added in to validate the actual results so that it actualy returns a valid date

edit fixed the contingency mentioned above.  I've tested this in a variety of ways and I checked this against this website http://www.historyorb.com/     and it is in fact subtracting 26 weeks from a week number and year entered (*no gui) and is infact returning valid dates and returning valid sunday's.  Sweet

Edited by markyrocks
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...