Here is my version.
Code: Select all
EnableExplicit
Procedure.i ISOdayOfWeek (date.i)
Protected d.i
d = DayOfWeek(date)
If d = 0
d = 7 ; for Sunday, return 7 instead of 0
EndIf
ProcedureReturn d
EndProcedure
Procedure.i ISOweek (date.i)
; The calculations are based on the fact that the first week of a year
; always contains January 4.
; [according to http://en.wikipedia.org/wiki/Seven-day_week#Week_numbering
; or better http://de.wikipedia.org/wiki/Woche#Kalenderwoche]
Protected doy.i=DayOfYear(date), year.i=Year(date)
Protected lastPrev.i ; last day of last week of previous year
Protected lastThis.i ; last day of last week of current year
lastPrev = 4 - ISOdayOfWeek(Date(year, 1, 4, 0,0,0))
lastThis = 4 - ISOdayOfWeek(Date(year,12,28, 0,0,0)) + DayOfYear(Date(year,12,31, 0,0,0))
If doy <= lastThis
If doy <= lastPrev
; The given day is in the last week of the previous year.
doy + DayOfYear(Date(year-1,12,31, 0,0,0))
lastPrev = 4 - ISOdayOfWeek(Date(year-1,1,4, 0,0,0))
EndIf
ProcedureReturn Round((doy-lastPrev)/7, #PB_Round_Up)
Else
; The given day is in the first week of the next year.
ProcedureReturn 1
EndIf
EndProcedure
; -- Demo
Debug ISOweek(Date(2009,12,31, 0,0,0)) ; 53
Debug ISOweek(Date(2010, 1, 1, 0,0,0)) ; 53
Debug ISOweek(Date(2010, 1, 2, 0,0,0)) ; 53
Debug ISOweek(Date(2010, 1, 3, 0,0,0)) ; 53
Debug ISOweek(Date(2010, 1, 4, 0,0,0)) ; 1
Debug ISOweek(Date(2010,12,31, 0,0,0)) ; 52
Debug ISOweek(Date(2011, 1, 1, 0,0,0)) ; 52
Debug ISOweek(Date(2011, 1, 2, 0,0,0)) ; 52
Debug ISOweek(Date(2011, 1, 3, 0,0,0)) ; 1
Debug ISOweek(Date(2011,12,31, 0,0,0)) ; 52
Debug ISOweek(Date(2012, 1, 1, 0,0,0)) ; 52
Debug ISOweek(Date(2012, 1, 2, 0,0,0)) ; 1
Debug ISOweek(Date(2012,12,30, 0,0,0)) ; 52
Debug ISOweek(Date(2012,12,31, 0,0,0)) ; 1