Task log - AutoHotkey Community

https://autohotkey.com/boards/viewtopic.php?f=5&t=45410

AutoHotkey has one way to do date to week number using YWeek:

FormatTime

https://autohotkey.com/docs/commands/FormatTime.htm

YWeek is a good system, although one disadvantage is that it may state that the 1 Jan this year, is part of the last week of last year.

For me the most intuitive system would be: for a year that starts on a Friday.

Week 1 of year: Fri Sat Sun. [Fri 1 Jan]

Week 2 of year: MTWTFSS.

Week 3 of year: MTWTFSS. Etc.

I might make use of both systems for record-keeping. But I would use the more 'intuitive' system, if someone simply asked me, what week is it.

I've tried to write a function to do this, where you can specify any day you like as the 'first day of the week', it assumes Monday. I've also written a function that tries to do date to week number, that only allows Monday as the first day of the week, and which is based on YWeek. (One reason for two functions, is to use the simpler function to check that the more complex function is working correctly.)

Do notify of any issues, or any better alternative ideas (which there may well be).

Btw you might find this quite(/very) fiddly to get your head around, if you try to write a function from scratch, without looking at my attempt.

Code: Select all

```
q:: ;list dates with week numbers and weekdays
vDate := 20000101
vOutput := ""
Loop, % 366*20
{
vOutput .= SubStr(vDate, 1, 8) " " JEE_DateGetWeek(vDate) " " FormatTime(vDate, "ddd") "`r`n"
vDate := DateAdd(vDate, 1, "D")
}
Clipboard := vOutput
MsgBox, % "done"
return
;w:: ;test the functions
vDate := 2000
Loop, % 366*20
{
vWeek1 := JEE_DateGetWeek(vDate)
vWeek2 := JEE_DateGetWeekAlt(vDate)
if !(vWeek1 = vWeek2)
MsgBox, % SubStr(vDate, 1, 8) " " vWeek1 " " vWeek2 " " FormatTime(vDate, "ddd") "`r`n"
vDate := DateAdd(vDate, 1, "D")
}
MsgBox, % "done"
return
e:: ;test the functions
oXl := ComObjCreate("Excel.Application")
vDate := 2000
vDateXl := 36526 ;2000-01-01
Loop, % 366*20
{
;vWeek1 := JEE_DateGetWeek(vDate) ;week starts on Mon
;vWeek2 := Round(oXl.WeekNum(vDateXl, 2)) ;week starts on Mon
vWeek1 := JEE_DateGetWeek(vDate, 1) ;week starts on Sun
vWeek2 := Round(oXl.WeekNum(vDateXl)) ;week starts on Sun
;MsgBox, % vWeek1 " " vWeek2
if !(vWeek1 = vWeek2)
MsgBox, % SubStr(vDate, 1, 8) " " vWeek1 " " vWeek2 " " FormatTime(vDate, "ddd") "`r`n"
vDate := DateAdd(vDate, 1, "D")
vDateXl++
}
MsgBox, % "done"
oXl.Quit()
oXl := ""
return
'==================================================
;e.g. vWeek := JEE_DateGetWeek(A_Now)
;e.g. if the first day of the week is defined as Monday,
;'week 1' is from 1 Jan to the first Sunday of the year
;1 Jan is always in 'week 1'
;vWeekStart: 1 (Sun), 7 (Sat)
;SMTWTFS
;1234567
;e.g. vWeek := JEE_DateGetWeek(A_Now)
;e.g. if the first day of the week is defined as Monday,
;'week 1' is from 1 Jan to the first Sunday of the year
;1 Jan is always in 'week 1'
;vWeekStart: 1 (Sun), 7 (Sat)
;SMTWTFS
;1234567
JEE_DateGetWeek(vDate:="", vWeekStart:=2)
{
if (vDate = "")
vDate := A_Now
vWDay := FormatTime(SubStr(vDate, 1, 4), "WDay")
vDays := DateDiff(vDate, SubStr(vDate, 1, 4), "D") + Mod(7+vWDay-vWeekStart, 7)
;find the Monday in the period 26 Dec to 1 Jan,
;count the weeks between the requested date and that Monday
return Format("{:02}", 1 + vDays//7)
}
'==================================================
JEE_DateGetWeekAlt2(vDate:="", vWeekStart:=2)
{
vWeekEnd := Mod(vWeekStart+7-1, 7)
if (vDate = "")
vDate := A_Now
vDays := DateDiff(vDate, SubStr(vDate, 1, 4), "D")
vWeeks := vDays//7
vDaysX := Mod(vDays, 7)
vWDay := FormatTime(vDate, "WDay")
;where Monday is the first day of the week,
;within the first 7 days of the year,
;if the day is after a Sunday, it's in the second week of the year
if (vDaysX = 0)
return Format("{:02}", 1 + vWeeks)
vRange1 := vWDay-vDaysX
vRange2 := vWDay-1
if ((vWeekEnd >= vRange1) && (vWeekEnd <= vRange2))
|| ((vWeekEnd-7 >= vRange1) && (vWeekEnd-7 <= vRange2))
return Format("{:02}", 2 + vWeeks)
else
return Format("{:02}", 1 + vWeeks)
}
;==================================================
;e.g. vWeek := JEE_DateGetWeekAlt(A_Now)
;uses YWeek where Monday is the first day of week
JEE_DateGetWeekAlt(vDate:="")
{
if (vDate = "")
vDate := A_Now
vYWeek := FormatTime(vDate, "YWeek")
if !(SubStr(vDate, 1, 4) = SubStr(vYWeek, 1, 4))
if (SubStr(vDate, 5, 2) = 12)
return Format("{:02}", %A_ThisFunc%(DateAdd(vDate, -7, "D"))+1)
else
return Format("{:02}", 1)
vYWeekX := FormatTime(SubStr(vDate, 1, 4), "YWeek")
vWeek := SubStr(vYWeek, 5)
if (SubStr(vDate, 1, 4) = SubStr(vYWeekX, 1, 4))
return Format("{:02}", vWeek)
else
return Format("{:02}", vWeek+1)
}
;==================================================
;commands as functions (AHK v2 functions for AHK v1) - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=37&t=29689
DateAdd(DateTime, Time, TimeUnits)
{
EnvAdd DateTime, %Time%, %TimeUnits%
return DateTime
}
DateDiff(DateTime1, DateTime2, TimeUnits)
{
EnvSub DateTime1, %DateTime2%, %TimeUnits%
return DateTime1
}
FormatTime(YYYYMMDDHH24MISS:="", Format:="")
{
local OutputVar
FormatTime OutputVar, %YYYYMMDDHH24MISS%, %Format%
return OutputVar
}
;==================================================
```

[EDIT:] Added Excel tests. Functions now always return two-digit numbers. Replaced JEE_DateGetWeek with a far simpler algorithm, original function is now called JEE_DateGetWeekAlt2.