- case _T('a'): // a weekday name
- case _T('A'):
- // second parameter should be TRUE for abbreviated names
- res += GetWeekDayName(tm.GetWeekDay(),
- *p == _T('a') ? Name_Abbr : Name_Full);
- break;
-
- case _T('b'): // a month name
- case _T('B'):
- res += GetMonthName(tm.mon,
- *p == _T('b') ? Name_Abbr : Name_Full);
- break;
-
- case _T('c'): // locale default date and time representation
- case _T('x'): // locale default date representation
- //
- // the problem: there is no way to know what do these format
- // specifications correspond to for the current locale.
- //
- // the solution: use a hack and still use strftime(): first
- // find the YEAR which is a year in the strftime() range (1970
- // - 2038) whose Jan 1 falls on the same week day as the Jan 1
- // of the real year. Then make a copy of the format and
- // replace all occurences of YEAR in it with some unique
- // string not appearing anywhere else in it, then use
- // strftime() to format the date in year YEAR and then replace
- // YEAR back by the real year and the unique replacement
- // string back with YEAR. Notice that "all occurences of YEAR"
- // means all occurences of 4 digit as well as 2 digit form!
- //
- // the bugs: we assume that neither of %c nor %x contains any
- // fields which may change between the YEAR and real year. For
- // example, the week number (%U, %W) and the day number (%j)
- // will change if one of these years is leap and the other one
- // is not!
- {
- // find the YEAR: normally, for any year X, Jan 1 or the
- // year X + 28 is the same weekday as Jan 1 of X (because
- // the weekday advances by 1 for each normal X and by 2
- // for each leap X, hence by 5 every 4 years or by 35
- // which is 0 mod 7 every 28 years) but this rule breaks
- // down if there are years between X and Y which are
- // divisible by 4 but not leap (i.e. divisible by 100 but
- // not 400), hence the correction.
-
- int yearReal = GetYear(tz);
- int mod28 = yearReal % 28;
-
- // be careful to not go too far - we risk to leave the
- // supported range
- int year;
- if ( mod28 < 10 )
- {
- year = 1988 + mod28; // 1988 == 0 (mod 28)
- }
- else
- {
- year = 1970 + mod28 - 10; // 1970 == 10 (mod 28)
- }