Add support for "%V" and "%G" to wxDateTime::Format().

This is useful for creating ISO 8601 week number based stamps.

Closes #11857.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76988 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2014-08-03 12:47:36 +00:00
parent db65392b95
commit 29b68052bb
3 changed files with 147 additions and 7 deletions

View File

@@ -271,6 +271,30 @@ GetWeekDayFromName(wxString::const_iterator& p,
return wd;
}
// return the year of the Monday of the week containing the given date
int
GetWeekBasedYear(const wxDateTime& dt)
{
const wxDateTime::Tm tm = dt.GetTm();
int year = tm.year;
// The week-based year can only be different from the normal year for few
// days in the beginning and the end of the year.
if ( tm.yday > 361 )
{
if ( dt.GetWeekOfYear() == 1 )
year++;
}
else if ( tm.yday < 5 )
{
if ( dt.GetWeekOfYear() == 53 )
year--;
}
return year;
}
// parses string starting at given iterator using the specified format and,
// optionally, a fall back format (and optionally another one... but it stops
// there, really)
@@ -321,17 +345,38 @@ wxString wxDateTime::Format(const wxString& formatp, const TimeZone& tz) const
format.Replace("%X",wxLocale::GetInfo(wxLOCALE_TIME_FMT));
#endif
// we have to use our own implementation if the date is out of range of
// strftime() or if we use non standard specifiers (notice that "%z" is
// special because it is de facto standard under Unix but is not supported
// under Windows)
// strftime()
#ifdef wxHAS_STRFTIME
time_t time = GetTicks();
if ( (time != (time_t)-1) && !wxStrstr(format, wxT("%l"))
bool canUseStrftime = time != (time_t)-1;
// We also can't use strftime() if we use non standard specifier: either
// our own extension "%l" or one of "%g", "%G", "%V", "%z" which are POSIX
// but not supported under Windows.
for ( wxString::const_iterator p = format.begin();
canUseStrftime && p != format.end();
++p )
{
if ( *p != '%' )
continue;
// set the default format
switch ( (*++p).GetValue() )
{
case 'l':
#ifdef __WINDOWS__
&& !wxStrstr(format, wxT("%z"))
#endif
)
case 'g':
case 'G':
case 'V':
case 'z':
#endif // __WINDOWS__
canUseStrftime = false;
break;
}
}
if ( canUseStrftime )
{
// use strftime()
struct tm tmstruct;
@@ -405,6 +450,7 @@ wxString wxDateTime::Format(const wxString& formatp, const TimeZone& tz) const
switch ( (*++p).GetValue() )
{
case wxT('Y'): // year has 4 digits
case wxT('G'): // (and ISO week year too)
case wxT('z'): // time zone as well
fmt = wxT("%04d");
break;
@@ -576,6 +622,14 @@ wxString wxDateTime::Format(const wxString& formatp, const TimeZone& tz) const
res += wxString::Format(fmt, tm.mday);
break;
case wxT('g'): // 2-digit week-based year
res += wxString::Format(fmt, GetWeekBasedYear(*this) % 100);
break;
case wxT('G'): // week-based year with century
res += wxString::Format(fmt, GetWeekBasedYear(*this));
break;
case wxT('H'): // hour in 24h format (00-23)
res += wxString::Format(fmt, tm.hour);
break;
@@ -621,6 +675,7 @@ wxString wxDateTime::Format(const wxString& formatp, const TimeZone& tz) const
res += wxString::Format(fmt, GetWeekOfYear(Sunday_First, tz));
break;
case wxT('V'): // ISO week number
case wxT('W'): // week number in the year (Monday 1st week day)
res += wxString::Format(fmt, GetWeekOfYear(Monday_First, tz));
break;