| 41 | |
| 42 | |
| 43 | int GetISOWeekNumber(LPTSTR aBuf, int aYear, int aYDay, int aWDay) |
| 44 | // Caller must ensure that aBuf is of size 7 or greater, that aYear is a valid year (e.g. 2005), |
| 45 | // that aYDay is between 1 and 366, and that aWDay is between 0 and 6 (day of the week). |
| 46 | // Produces the week number in YYYYNN format, e.g. 200501. |
| 47 | // Note that year is also returned because it isn't necessarily the same as aTime's calendar year. |
| 48 | // Based on Linux glibc source code (GPL). |
| 49 | { |
| 50 | --aYDay; // Convert to zero based. |
| 51 | #define ISO_WEEK_START_WDAY 1 // Monday |
| 52 | #define ISO_WEEK1_WDAY 4 // Thursday |
| 53 | #define ISO_WEEK_DAYS(yday, wday) (yday - (yday - wday + ISO_WEEK1_WDAY + ((366 / 7 + 2) * 7)) % 7 \ |
| 54 | + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY); |
| 55 | |
| 56 | int year = aYear; |
| 57 | int days = ISO_WEEK_DAYS(aYDay, aWDay); |
| 58 | |
| 59 | if (days < 0) // This ISO week belongs to the previous year. |
| 60 | { |
| 61 | --year; |
| 62 | days = ISO_WEEK_DAYS(aYDay + (365 + IS_LEAP_YEAR(year)), aWDay); |
| 63 | } |
| 64 | else |
| 65 | { |
| 66 | int d = ISO_WEEK_DAYS(aYDay - (365 + IS_LEAP_YEAR(year)), aWDay); |
| 67 | if (0 <= d) // This ISO week belongs to the next year. |
| 68 | { |
| 69 | ++year; |
| 70 | days = d; |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | // Use sntprintf() for safety; that is, in case year contains a value longer than 4 digits. |
| 75 | // This also adds the leading zeros in front of year and week number, if needed. |
| 76 | return sntprintf(aBuf, 7, _T("%04d%02d"), year, (days / 7) + 1); // Return the length of the string produced. |
| 77 | } |
| 78 | |
| 79 | |
| 80 |
no test coverage detected