Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make week number parsing conform to ISO8601 when Datetime::weekstart …
…== 1 This is a duplicate of the changes from commit with same subject line in GothenburgBitFactory/libshared#81 and also duplicates the commit message below. Timewarrior has copies of many functions from libshared's Datetime class in its own DatetimeParser class, and until such time as these classes are integrated, we have to maintain copies of these functions here, and the changes need to be duplicated. See discussion in aforementioned PR. The one difference with the patch over there is, this one is using the public Datetime::dayOfWeek rather than its own implementation. The copy in Timewarrior already was doing this before, but it's worth noting it's the only difference with the corresponding patch in libshared PR 81. * * * This patch makes the parsing of week numbers in dates ISO-8601 compliant in the case that Datetime::weekstart == 1, while the existing behavior remains available if Datetime::weekstart == 0. The previous code parsed week numbers (given as "yyyy-Www") into dates starting on Sunday. Although the code had a "Datetime::weekstart" variable, and this value was initialized to 1 (which is Monday) in libshared, nonetheless week specifications would be parsed into calendar days starting on Sunday. Furthermore, week days in such given weeks ('d' in "yyyy-Www-d") used 0-6 for Sunday-Monday, while ISO8601 specifies 1-7 Monday-Sunday. Therefore, yyyy-Www-0 was treated as valid (and should not be), while yyyy-Www-7 was invalid (and should be valid). Note that neither Taskwarrior nor Timewarrior ever set the value of Datetime::weekstart. Taskwarrior has an rc.weekstart, but this is only used for "task calendar" output, not for parsing dates. The patch does the following: - Initialize "Datetime" instances with a weekday value from Datetime::weekstart. This helps the case when weekday is not supplied, it won't default to zero and fail validation (when weekstart is '1'). Note that mktime() is usually used in the code to convert populated "struct tm" broken-down times into epoch-times, and this operation does not use tm.tm_wday for input, only as an output field, recomputed as a normalized value, so it appears to be safe to initialize it with a 1 (which we might wonder about since .tm_wday is supposed to be 0-6 Sunday based). - Use the already-existing Datetime::parse_weekday() to parse the 'ww' in "yyyy-Www" input dates (the function was not used by any caller previously; guessing it may have been intended for eventual use in order to respect weekstart(?)) - Teach parse_weekday() about weekstart. Previously this assumed 1-7, which is the reason I'm guessing this was intended to be used for ISO weeks eventually. Now it can also use 0-6 if weekstart 0. - Teach Datetime::validate to respect Datetime::weekstart also. Previously only 0-6 Sunday-Monday was considered valid. - Default the weekday to Datetime::weekstart if not supplied, ie for "yyyy-Www-X" if the "-X" is not supplied, as recognized when Datetime::standaloneDateEnabled = true, which is the case for (1) tests, (2) timewarrior, but NOT for taskwarrior at this time (both the standalone 'calc' and 'task calc' (ie Context.cpp) set this to false). - Implement the complete ISO week calculation algorithm in Datetime::resolve() if weekstart is '1', and keeps the existing algorithm if weekstart is '0'. This will allow Taskwarrior and Timewarrior to offer the option of the old behavior for those who want to use Sunday-based weeks and ignore ISO week calculations (such as 2023-01-01 being in ISO week 2022-W52). Signed-off-by: Scott Mcdermott <[email protected]>
- Loading branch information