|
Dealing with Calendar Weeks in WinDev Overview: WinDev offers the command WeekNumber(Date) which returns the calendar week number by old French standards. Those old standards were used from Napoleonic times after the French Revolution until 1992, when the ISO 8601 standard became law under the name EN 28601:1992. Interestingly, WeekNumber(Function) is correct for most dates (exceptions around year’s end!) calculated according to the ISO 8601 standard. The returned integer is between 0 to 53 as WD-Help says. The WeekNumber(Function) examples in WD-Help show erroneous result cases but do not explicitely say that there’s something wrong! * - There’s no such thing like a calendar week zero in ISO 8601! WeekNumber(“20100101”) will show week #0 as a result, which is correct by the old French standard. A weeknumber calculation using ISO 8601 / EN28601:1992 should show week #53. * - Weekdays in partial weeks with less then 4 days at the end of a year shall be attributed to the first partial week of the next year! WeekNumber(Function) results in wrong week numbers for days in partial weeks with less than 4 weekdays at the end of the year. Example: WeekNumber(“20131230”) result #53 is wrong by ISO 8601 standard, it should be #1. ISO 8601 defines the week #1: the first week of a given year is that one which has at least 4 or more days in the new year. All days before week 1 are attributed to the last week of the preceding year. Or: January 4th will always be in calendar week #1 !! Or: the first Thursday of the year is a Thursday of week #1 !! As a logical result, calendar week #1 can start with a maximum of three days in the preceding year (29th, 30th and 31st of December). All ISO calendar weeks start on Mondays! All ISO calendar week consist of 7 days! Most European countries - with only a few exceptions (e.g. Hungary?) - are using ISO 8601 for their calendar week definition. See for ISO week numbering: http://www.proesite.com/timex/wkcalc.htm and ISO 8601 in general: http://www.dmoz.org/Science/Reference/Standards/Individual_Standards/ISO/ISO_8601/ US-rules: All full calendar weeks start on Sundays. At the start and at the end of a year there may be shorter calendar weeks. The first calendar week of a year begins with January 1st - indepedently of its day of week! As a result, there is nearly no equivalence between ISO 8601 and US calendar week numbering! Every 24th year is a year with 54 calendar weeks by US standard! So, there’s plenty of problems waiting for the unaware programmer. There are different definitions for many countries! For a certain country, see: http://www.pjh2.de/datetime/weeknumber/wnd.php?l=en There are even different rules to calculate week numbers for fiscal years and for certain institutions, organisations and companies. Mostly, rules for calculation are published. Be aware that there’s an Islamic year (a moon year), the Jewish year, the Thai-Buddhistic year, the Iranian year and the Chinese Year too. It seems that the only common consensus is that a week has 7 days. 1 - Correction of erroneous results from WeekNumber(..)Though W-Language WeekNumber(Function) results in some errors it works for Europe (= ISO 8601) and can be corrected using the code below: IF DateValid(MyDate) THEN SWITCH WeekNumber(MyDate) CASE 0 MyWeek = WeekNumber(NumToString(Val(Left(MyDate,4)) - 1, "4d")+"1231") CASE 53 IF DateToDay(Left(MyDate,4)+"1231") < 4 THEN MyWeek = 1 ELSE MyWeek = 53 END OTHER CASE MyWeek = WeekNumber(MyDate) ENDEND Ambiguity issues: Be aware of the fact that the week number alone doesn’t define much. Just like the sentence ‘I’ll come on Monday!’. This may mean ‘next Monday’, but there’s no certainty at all that next Monday is really meant! Could be any Monday in the future. Same goes with week numbers. The unambiguous definition of a calendar week needs the addition of the year’s number! (some calendar years even contain two ISO calendar weeks #52 ! e.g. 2012) ISO 8601 defines the notation of the calendar week (and a day within) to be YYYY-Www-D and YYYY-Www. As an example: 2010-W12-3 would point to day 3 (Wednesday) of calendar week 12 of year 2010 - it is the 2010-03-24. The abridged format allows for definition of the week. 2010-W12 means the week from 2010-03-22 until 2010-03-28. Bottom line: Any calendar week calculation (ISO + US) should result in YEAR + WEEK# . Calendar weeks calculated by US rules will always show the calendar year in the year/week notation - unlike ISO weeks. So, let’s do an additional fix of the W-Language WeekNumber(Function) in regards to the year: MyWeek, MyYear are 4-byte intMyISOYearAndWeek is string IF DateValid(MyDate) THEN // show corrected result of WeekNumber(Function) SWITCH WeekNumber(MyDate) CASE 0 // WeekNumber(Function) returns week #0 as a partial week with less than 4 days // in the beginning of a year. The week# should be propagated from the previous year MyWeek = WeekNumber(NumToString(Val(Left(MyDate,4)) - 1, "4d")+"1231") MyYear = Val(Left(MyDate,4))-1 CASE 53 // WeekNumber(Function) erroneously returns week #53 on partial weeks with // less than 4 days at the end of the year. Result should be week #1 IF DateToDay(Left(MyDate,4)+"1231") < 4 THEN MyWeek = 1 MyYear = Val(Left(MyDate,4))+1 ELSE // week #53 is correct because 4 or more days of the week are in that year MyWeek = 53 MyYear = Val(Left(MyDate,4)) END OTHER CASE // Results from WeekNumber(Function) <> 0 and <> 53 are generally OK MyWeek = WeekNumber(MyDate) MyYear = Val(Left(MyDate,4)) END MyISOYearAndWeek = NumToString(MyYear,"04d")+"-W"+NumToString(MyWeek,"02d")END
There is another challenge: calculate the start date of a given week number! |