///////////////////////////////////////////////////////////////////////////////
-// Name: wx/datetime.h
+// Name: src/common/datetime.cpp
// Purpose: implementation of time/date related classes
// Author: Vadim Zeitlin
// Modified by:
// headers
// ----------------------------------------------------------------------------
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
- #pragma implementation "datetime.h"
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
// (i.e. JDN(Jan 1, 1970) = 2440587.5)
static const long EPOCH_JDN = 2440587l;
+// used only in asserts
+#ifdef __WXDEBUG__
// the date of JDN -0.5 (as we don't work with fractional parts, this is the
// reference date for us) is Nov 24, 4714BC
static const int JDN_0_YEAR = -4713;
static const int JDN_0_MONTH = wxDateTime::Nov;
static const int JDN_0_DAY = 24;
+#endif // __WXDEBUG__
// the constants used for JDN calculations
static const long JDN_OFFSET = 32046l;
static wxString CallStrftime(const wxChar *format, const tm* tm)
{
wxChar buf[4096];
+ // Create temp wxString here to work around mingw/cygwin bug 1046059
+ // http://sourceforge.net/tracker/?func=detail&atid=102435&aid=1046059&group_id=2435
+ wxString s;
+
if ( !wxStrftime(buf, WXSIZEOF(buf), format, tm) )
{
// buffer is too small?
wxFAIL_MSG(_T("strftime() failed"));
}
- return wxString(buf);
+ s = buf;
+ return s;
}
#endif
#ifdef HAVE_STRPTIME
-// glibc2 doesn't define this in the headers unless _XOPEN_SOURCE is defined
-// which, unfortunately, wreaks havoc elsewhere
-#if defined(__GLIBC__) && (__GLIBC__ == 2)
+#if wxUSE_UNIX && !defined(HAVE_STRPTIME_DECL)
+ // configure detected that we had strptime() but not its declaration,
+ // provide it ourselves
extern "C" char *strptime(const char *, const char *, struct tm *);
#endif
case wxDateTime::A_CST:
// Central Standard Time in use in Australia = UTC + 9.5
- m_offset = 60l*(9*60 + 30);
+ m_offset = 60l*(9*MIN_PER_HOUR + MIN_PER_HOUR/2);
break;
default:
// EPOCH_JDN + 0.5
jdn -= EPOCH_JDN + 0.5;
- jdn *= MILLISECONDS_PER_DAY;
-
- m_time.Assign(jdn);
+ m_time.Assign(jdn*MILLISECONDS_PER_DAY);
- // JDNs always suppose an UTC date, so bring it back to local time zone
- // (also see GetJulianDayNumber() implementation)
- long tzDiff = GetTimeZone();
- if ( IsDST() == 1 )
- {
- // FIXME: again, we suppose that DST is always one hour
- tzDiff -= 3600;
- }
-
- m_time += tzDiff*1000; // tzDiff is in seconds
+ // JDNs always are in UTC, so we don't need any adjustments for time zone
return *this;
}
timeOnly -= tm.msec;
timeOnly /= 1000; // now we have time in seconds
- tm.sec = (wxDateTime_t)(timeOnly % 60);
+ tm.sec = (wxDateTime_t)(timeOnly % SEC_PER_MIN);
timeOnly -= tm.sec;
- timeOnly /= 60; // now we have time in minutes
+ timeOnly /= SEC_PER_MIN; // now we have time in minutes
- tm.min = (wxDateTime_t)(timeOnly % 60);
+ tm.min = (wxDateTime_t)(timeOnly % MIN_PER_HOUR);
timeOnly -= tm.min;
- tm.hour = (wxDateTime_t)(timeOnly / 60);
+ tm.hour = (wxDateTime_t)(timeOnly / MIN_PER_HOUR);
return tm;
}
double wxDateTime::GetJulianDayNumber() const
{
- // JDN are always expressed for the UTC dates
- Tm tm(ToTimezone(UTC).GetTm(UTC));
-
- double result = GetTruncatedJDN(tm.mday, tm.mon, tm.year);
-
- // add the part GetTruncatedJDN() neglected
- result += 0.5;
-
- // and now add the time: 86400 sec = 1 JDN
- return result + ((double)(60*(60*tm.hour + tm.min) + tm.sec)) / 86400;
+ return m_time.ToDouble() / MILLISECONDS_PER_DAY + EPOCH_JDN + 0.5;
}
double wxDateTime::GetRataDie() const
secDiff -= 3600;
}
+ return Add(wxTimeSpan::Seconds(secDiff));
+}
+
+wxDateTime& wxDateTime::MakeFromTimezone(const TimeZone& tz, bool noDST)
+{
+ long secDiff = GetTimeZone() + tz.GetOffset();
+
+ // we need to know whether DST is or not in effect for this date unless
+ // the test disabled by the caller
+ if ( !noDST && (IsDST() == 1) )
+ {
+ // FIXME we assume that the DST is always shifted by 1 hour
+ secDiff -= 3600;
+ }
+
return Subtract(wxTimeSpan::Seconds(secDiff));
}
// find two strings not occurring in format (this is surely
// not the optimal way of doing it... improvements welcome!)
- wxString fmt = format;
+ wxString fmt2 = format;
wxString replacement = (wxChar)-1;
- while ( fmt.Find(replacement) != wxNOT_FOUND )
+ while ( fmt2.Find(replacement) != wxNOT_FOUND )
{
replacement << (wxChar)-1;
}
wxString replacement2 = (wxChar)-2;
- while ( fmt.Find(replacement) != wxNOT_FOUND )
+ while ( fmt2.Find(replacement) != wxNOT_FOUND )
{
replacement << (wxChar)-2;
}
// replace all occurrences of year with it
- bool wasReplaced = fmt.Replace(strYear, replacement) > 0;
+ bool wasReplaced = fmt2.Replace(strYear, replacement) > 0;
if ( !wasReplaced )
- wasReplaced = fmt.Replace(strYear2, replacement2) > 0;
+ wasReplaced = fmt2.Replace(strYear2, replacement2) > 0;
// use strftime() to format the same date but in supported
// year
}
// hours
- offset = 60*(10*(*p - _T('0')) + (*(p + 1) - _T('0')));
+ offset = MIN_PER_HOUR*(10*(*p - _T('0')) + (*(p + 1) - _T('0')));
p += 2;
}
// make it minutes
- offset *= 60;
+ offset *= MIN_PER_HOUR;
}
- // the spec was correct
+ // the spec was correct, construct the date from the values we found
Set(day, mon, year, hour, min, sec);
- MakeTimezone((wxDateTime_t)(60*offset));
+ MakeFromTimezone(TimeZone((wxDateTime_t)(offset*SEC_PER_MIN)));
return p;
}
for ( size_t n = 0; n < WXSIZEOF(literalDates); n++ )
{
- wxString date = wxGetTranslation(literalDates[n].str);
- size_t len = date.length();
+ const wxString dateStr = wxGetTranslation(literalDates[n].str);
+ size_t len = dateStr.length();
if ( wxStrlen(p) >= len )
{
wxString str(p, len);
- if ( str.CmpNoCase(date) == 0 )
+ if ( str.CmpNoCase(dateStr) == 0 )
{
// nothing can follow this, so stop here
p += len;
#include "wx/arrimpl.cpp"
-WX_DEFINE_OBJARRAY(wxDateTimeArray);
+WX_DEFINE_OBJARRAY(wxDateTimeArray)
static int wxCMPFUNC_CONV
wxDateTimeCompareFunc(wxDateTime **first, wxDateTime **second)
holidays.Clear();
- size_t count = ms_authorities.size();
- for ( size_t nAuth = 0; nAuth < count; nAuth++ )
+ const size_t countAuth = ms_authorities.size();
+ for ( size_t nAuth = 0; nAuth < countAuth; nAuth++ )
{
ms_authorities[nAuth]->DoGetHolidaysInRange(dtStart, dtEnd, hol);