Implement support for "%z" in wxDateTime::Format() and Parse().

"%z" specifier can now be used when printing the dates out to specify the time
zone and is also recognized when parsing dates.

Closes #1215.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70268 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2012-01-05 00:47:10 +00:00
parent cd72035387
commit 444bc2b24d
3 changed files with 181 additions and 63 deletions

View File

@@ -319,11 +319,17 @@ 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
// 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)
#ifdef wxHAS_STRFTIME
time_t time = GetTicks();
if ( (time != (time_t)-1) && !wxStrstr(format, wxT("%l")) )
if ( (time != (time_t)-1) && !wxStrstr(format, wxT("%l"))
#ifdef __WXMSW__
&& !wxStrstr(format, wxT("%z"))
#endif
)
{
// use strftime()
struct tm tmstruct;
@@ -397,6 +403,7 @@ wxString wxDateTime::Format(const wxString& formatp, const TimeZone& tz) const
switch ( (*++p).GetValue() )
{
case wxT('Y'): // year has 4 digits
case wxT('z'): // time zone as well
fmt = wxT("%04d");
break;
@@ -639,6 +646,25 @@ wxString wxDateTime::Format(const wxString& formatp, const TimeZone& tz) const
res += wxString::Format(fmt, tm.year);
break;
case wxT('z'): // time zone as [-+]HHMM
{
int ofs = tz.GetOffset();
if ( ofs < 0 )
{
res += '-';
ofs = -ofs;
}
else
{
res += '+';
}
// Converts seconds to HHMM representation.
res += wxString::Format(fmt,
100*(ofs/3600) + (ofs/60)%60);
}
break;
case wxT('Z'): // timezone name
#ifdef wxHAS_STRFTIME
res += CallStrftime(wxT("%Z"), &tmTimeOnly);
@@ -929,6 +955,8 @@ wxDateTime::ParseFormat(const wxString& date,
bool hourIsIn12hFormat = false, // or in 24h one?
isPM = false; // AM by default
bool haveTimeZone = false;
// and the value of the items we have (init them to get rid of warnings)
wxDateTime_t msec = 0,
sec = 0,
@@ -939,6 +967,7 @@ wxDateTime::ParseFormat(const wxString& date,
mday = 0;
wxDateTime::Month mon = Inv_Month;
int year = 0;
long timeZone = 0; // time zone in seconds as expected in Tm structure
wxString::const_iterator input = date.begin();
const wxString::const_iterator end = date.end();
@@ -1377,6 +1406,36 @@ wxDateTime::ParseFormat(const wxString& date,
year = (wxDateTime_t)num;
break;
case wxT('z'):
{
bool minusFound;
if ( *input == wxT('-') )
minusFound = true;
else if ( *input == wxT('+') )
minusFound = false;
else
return false; // no match
// here should follow 4 digits HHMM
++input;
unsigned long tzHourMin;
if ( !GetNumericToken(4, input, end, &tzHourMin) )
return false; // no match
const unsigned hours = tzHourMin / 100;
const unsigned minutes = tzHourMin % 100;
if ( hours > 12 || minutes > 59 )
return false; // bad format
timeZone = 3600*hours + 60*minutes;
if ( minusFound )
timeZone = -timeZone;
haveTimeZone = true;
}
break;
case wxT('Z'): // timezone name
// FIXME: currently we just ignore everything that looks like a
// time zone here
@@ -1482,6 +1541,14 @@ wxDateTime::ParseFormat(const wxString& date,
Set(tm);
// If a time zone was specified and it is not the local time zone, we need
// to shift the time accordingly.
//
// Note that avoiding the call to MakeFromTimeZone is necessary to avoid
// DST problems.
if ( haveTimeZone && timeZone != -wxGetTimeZone() )
MakeFromTimezone(timeZone);
// finally check that the week day is consistent -- if we had it
if ( haveWDay && GetWeekDay() != wday )
return false;