#include "wx/datetime.h"
-const long wxDateTime::TIME_T_FACTOR = 1000l;
+// ----------------------------------------------------------------------------
+// wxXTI
+// ----------------------------------------------------------------------------
#if wxUSE_EXTENDED_RTTI
#endif // wxUSE_EXTENDED_RTTI
-//
+
// ----------------------------------------------------------------------------
// conditional compilation
// ----------------------------------------------------------------------------
-#if defined(HAVE_STRPTIME) && defined(__GLIBC__) && \
- ((__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0))
- // glibc 2.0.7 strptime() is broken - the following snippet causes it to
- // crash (instead of just failing):
- //
- // strncpy(buf, "Tue Dec 21 20:25:40 1999", 128);
- // strptime(buf, "%x", &tm);
- //
- // so don't use it
- #undef HAVE_STRPTIME
-#endif // broken strptime()
-
-#if defined(HAVE_STRPTIME) && defined(__DARWIN__) && defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS
- // configure detects strptime as linkable because it's in the OS X
- // System library but MSL headers don't declare it.
-
-// char *strptime(const char *, const char *, struct tm *);
- // However, we DON'T want to just provide it here because we would
- // crash and/or overwrite data when strptime from OS X tries
- // to fill in MW's struct tm which is two fields shorter (no TZ stuff)
- // So for now let's just say we don't have strptime
- #undef HAVE_STRPTIME
-#endif
-
#if defined(__MWERKS__) && wxUSE_UNICODE
#include <wtime.h>
#endif
#endif
#endif // !WX_TIMEZONE && !WX_GMTOFF_IN_TM
-// everyone has strftime except Win CE unless VC8 is used
-#if !defined(__WXWINCE__) || defined(__VISUALC8__)
- #define HAVE_STRFTIME
-#endif
-
// NB: VC8 safe time functions could/should be used for wxMSW as well probably
#if defined(__WXWINCE__) && defined(__VISUALC8__)
// (i.e. JDN(Jan 1, 1970) = 2440587.5)
static const long EPOCH_JDN = 2440587l;
-// used only in asserts
-#ifdef __WXDEBUG__
+// these values are only used in asserts so don't define them if asserts are
+// disabled to avoid warnings about unused static variables
+#if wxDEBUG_LEVEL
// 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__
+#endif // wxDEBUG_LEVEL
// the constants used for JDN calculations
static const long JDN_OFFSET = 32046l;
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
};
+const long wxDateTime::TIME_T_FACTOR = 1000l;
+
// ----------------------------------------------------------------------------
// global data
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------
-// debugger helper: shows what the date really is
-#ifdef __WXDEBUG__
+// debugger helper: this function can be called from a debugger to show what
+// the date really is
extern const char *wxDumpDate(const wxDateTime* dt)
{
static char buf[128];
return buf;
}
-#endif // Debug
// get the number of days in the given month of the given year
-// NOTE: not static because required by datetimefmt.cpp, too
-inline
+static inline
wxDateTime::wxDateTime_t GetNumOfDaysInMonth(int year, wxDateTime::Month month)
{
// the number of days in month in Julian/Gregorian calendar: the first line
// returns the time zone in the C sense, i.e. the difference UTC - local
// (in seconds)
-static int GetTimeZone()
+// NOTE: not static because used by datetimefmt.cpp
+int GetTimeZone()
{
// set to true when the timezone is set
static bool s_timezoneSet = false;
#ifdef HAVE_STRFTIME
// this function is a wrapper around strftime(3) adding error checking
-static wxString CallStrftime(const wxString& format, const tm* tm)
+// NOTE: not static because used by datetimefmt.cpp
+wxString CallStrftime(const wxString& format, const tm* tm)
{
wxChar buf[4096];
// Create temp wxString here to work around mingw/cygwin bug 1046059
#endif // HAVE_STRFTIME
-#ifdef HAVE_STRPTIME
-
-#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
-
-// Unicode-friendly strptime() wrapper
-static const wxStringCharType *
-CallStrptime(const wxStringCharType *input, const char *fmt, tm *tm)
-{
- // the problem here is that strptime() returns pointer into the string we
- // passed to it while we're really interested in the pointer into the
- // original, Unicode, string so we try to transform the pointer back
-#if wxUSE_UNICODE_WCHAR
- wxCharBuffer inputMB(wxConvertWX2MB(input));
-#else // ASCII
- const char * const inputMB = input;
-#endif // Unicode/Ascii
-
- const char *result = strptime(inputMB, fmt, tm);
- if ( !result )
- return NULL;
-
-#if wxUSE_UNICODE_WCHAR
- // FIXME: this is wrong in presence of surrogates &c
- return input + (result - inputMB.data());
-#else // ASCII
- return result;
-#endif // Unicode/Ascii
-}
-
-#endif // HAVE_STRPTIME
-
// if year and/or month have invalid values, replace them with the current ones
static void ReplaceDefaultYearMonthWithCurrent(int *year,
wxDateTime::Month *month)
}
}
-// fll the struct tm with default values
-static void InitTm(struct tm& tm)
+// fill the struct tm with default values
+// NOTE: not static because used by datetimefmt.cpp
+void InitTm(struct tm& tm)
{
// struct tm may have etxra fields (undocumented and with unportable
// names) which, nevertheless, must be set to 0
// static functions
// ----------------------------------------------------------------------------
+/* static */
+struct tm *wxDateTime::GetTmNow(struct tm *tmstruct)
+{
+ time_t t = GetTimeNow();
+ return wxLocaltime_r(&t, tmstruct);
+}
+
/* static */
bool wxDateTime::IsLeapYear(int year, wxDateTime::Calendar cal)
{
}
}
+namespace
+{
+
+// helper function used by GetEnglish/WeekDayName(): returns 0 if flags is
+// Name_Full and 1 if it is Name_Abbr or -1 if the flags is incorrect (and
+// asserts in this case)
+//
+// the return value of this function is used as an index into 2D array
+// containing full names in its first row and abbreviated ones in the 2nd one
+int NameArrayIndexFromFlag(wxDateTime::NameFlags flags)
+{
+ switch ( flags )
+ {
+ case wxDateTime::Name_Full:
+ return 0;
+
+ case wxDateTime::Name_Abbr:
+ return 1;
+
+ default:
+ wxFAIL_MSG( "unknown wxDateTime::NameFlags value" );
+ }
+
+ return -1;
+}
+
+} // anonymous namespace
+
+/* static */
+wxString wxDateTime::GetEnglishMonthName(Month month, NameFlags flags)
+{
+ wxCHECK_MSG( month != Inv_Month, wxEmptyString, "invalid month" );
+
+ static const char *monthNames[2][MONTHS_IN_YEAR] =
+ {
+ { "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December" },
+ { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }
+ };
+
+ const int idx = NameArrayIndexFromFlag(flags);
+ if ( idx == -1 )
+ return wxString();
+
+ return monthNames[idx][month];
+}
+
/* static */
wxString wxDateTime::GetMonthName(wxDateTime::Month month,
wxDateTime::NameFlags flags)
{
- wxCHECK_MSG( month != Inv_Month, wxEmptyString, _T("invalid month") );
#ifdef HAVE_STRFTIME
+ wxCHECK_MSG( month != Inv_Month, wxEmptyString, _T("invalid month") );
+
// notice that we must set all the fields to avoid confusing libc (GNU one
// gets confused to a crash if we don't do this)
tm tm;
return CallStrftime(flags == Name_Abbr ? _T("%b") : _T("%B"), &tm);
#else // !HAVE_STRFTIME
- wxString ret;
- switch(month)
- {
- case Jan:
- ret = (flags == Name_Abbr ? wxT("Jan"): wxT("January"));
- break;
- case Feb:
- ret = (flags == Name_Abbr ? wxT("Feb"): wxT("Febuary"));
- break;
- case Mar:
- ret = (flags == Name_Abbr ? wxT("Mar"): wxT("March"));
- break;
- case Apr:
- ret = (flags == Name_Abbr ? wxT("Apr"): wxT("April"));
- break;
- case May:
- ret = (flags == Name_Abbr ? wxT("May"): wxT("May"));
- break;
- case Jun:
- ret = (flags == Name_Abbr ? wxT("Jun"): wxT("June"));
- break;
- case Jul:
- ret = (flags == Name_Abbr ? wxT("Jul"): wxT("July"));
- break;
- case Aug:
- ret = (flags == Name_Abbr ? wxT("Aug"): wxT("August"));
- break;
- case Sep:
- ret = (flags == Name_Abbr ? wxT("Sep"): wxT("September"));
- break;
- case Oct:
- ret = (flags == Name_Abbr ? wxT("Oct"): wxT("October"));
- break;
- case Nov:
- ret = (flags == Name_Abbr ? wxT("Nov"): wxT("November"));
- break;
- case Dec:
- ret = (flags == Name_Abbr ? wxT("Dec"): wxT("December"));
- break;
- }
- return ret;
+ return GetEnglishMonthName(month, flags);
#endif // HAVE_STRFTIME/!HAVE_STRFTIME
}
+/* static */
+wxString wxDateTime::GetEnglishWeekDayName(WeekDay wday, NameFlags flags)
+{
+ wxCHECK_MSG( wday != Inv_WeekDay, wxEmptyString, _T("invalid weekday") );
+
+ static const char *weekdayNames[2][DAYS_PER_400_YEARS] =
+ {
+ { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
+ "Saturday" },
+ { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" },
+ };
+
+ const int idx = NameArrayIndexFromFlag(flags);
+ if ( idx == -1 )
+ return wxString();
+
+ return weekdayNames[idx][wday];
+}
+
/* static */
wxString wxDateTime::GetWeekDayName(wxDateTime::WeekDay wday,
wxDateTime::NameFlags flags)
{
- wxCHECK_MSG( wday != Inv_WeekDay, wxEmptyString, _T("invalid weekday") );
#ifdef HAVE_STRFTIME
+ wxCHECK_MSG( wday != Inv_WeekDay, wxEmptyString, _T("invalid weekday") );
+
// take some arbitrary Sunday (but notice that the day should be such that
// after adding wday to it below we still have a valid date, e.g. don't
// take 28 here!)
// ... and call strftime()
return CallStrftime(flags == Name_Abbr ? _T("%a") : _T("%A"), &tm);
#else // !HAVE_STRFTIME
- wxString ret;
- switch(wday)
- {
- case Sun:
- ret = (flags == Name_Abbr ? wxT("Sun") : wxT("Sunday"));
- break;
- case Mon:
- ret = (flags == Name_Abbr ? wxT("Mon") : wxT("Monday"));
- break;
- case Tue:
- ret = (flags == Name_Abbr ? wxT("Tue") : wxT("Tuesday"));
- break;
- case Wed:
- ret = (flags == Name_Abbr ? wxT("Wed") : wxT("Wednesday"));
- break;
- case Thu:
- ret = (flags == Name_Abbr ? wxT("Thu") : wxT("Thursday"));
- break;
- case Fri:
- ret = (flags == Name_Abbr ? wxT("Fri") : wxT("Friday"));
- break;
- case Sat:
- ret = (flags == Name_Abbr ? wxT("Sat") : wxT("Saturday"));
- break;
- }
- return ret;
+ return GetEnglishWeekDayName(wday, flags);
#endif // HAVE_STRFTIME/!HAVE_STRFTIME
}