yodasoja Posted December 19, 2013 Posted December 19, 2013 (edited) 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 December 19, 2013 by yodasoja
markyrocks Posted December 19, 2013 Posted December 19, 2013 (edited) $ 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 December 20, 2013 by markyrocks Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning"
markyrocks Posted December 20, 2013 Posted December 20, 2013 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) expandcollapse popup#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 Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning"
Malkey Posted December 20, 2013 Posted December 20, 2013 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. expandcollapse popup#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
Rogue5099 Posted December 20, 2013 Posted December 20, 2013 (edited) 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. expandcollapse popup#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: expandcollapse popup#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 December 20, 2013 by Rogue5099 My projects: Inventory / Mp3 Inventory, Computer Stats
markyrocks Posted December 20, 2013 Posted December 20, 2013 (edited) 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. expandcollapse popup#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 December 21, 2013 by markyrocks Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning"
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now