X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e538985edcc645878a1bbeb3dc3e898e9d29ad11..fd5907ffd9b0785bb6eb6f2546101623b23827c5:/include/wx/datetime.h diff --git a/include/wx/datetime.h b/include/wx/datetime.h index bf1b58444c..286155f29f 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -26,6 +26,7 @@ #include // for INT_MIN #include "wx/longlong.h" +#include "wx/anystr.h" class WXDLLIMPEXP_FWD_BASE wxDateTime; class WXDLLIMPEXP_FWD_BASE wxTimeSpan; @@ -127,8 +128,8 @@ WXDLLIMPEXP_BASE struct tm *wxGmtime_r(const time_t*, struct tm*); // wxInvalidDateTime) class WXDLLIMPEXP_FWD_BASE wxDateTime; -extern WXDLLIMPEXP_DATA_BASE(const char *) wxDefaultDateTimeFormat; -extern WXDLLIMPEXP_DATA_BASE(const char *) wxDefaultTimeSpanFormat; +extern WXDLLIMPEXP_DATA_BASE(const char) wxDefaultDateTimeFormat[]; +extern WXDLLIMPEXP_DATA_BASE(const char) wxDefaultTimeSpanFormat[]; extern WXDLLIMPEXP_DATA_BASE(const wxDateTime) wxDefaultDateTime; #define wxInvalidDateTime wxDefaultDateTime @@ -138,33 +139,12 @@ extern WXDLLIMPEXP_DATA_BASE(const wxDateTime) wxDefaultDateTime; // 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 - -// everyone has strftime except Win CE unless VC8 is used -#if !defined(__WXWINCE__) || defined(__VISUALC8__) - #define HAVE_STRFTIME +// if configure detected strftime(), we have it too +#ifdef HAVE_STRFTIME + #define wxHAS_STRFTIME +// suppose everyone else has strftime except Win CE unless VC8 is used +#elif !defined(__WXWINCE__) || defined(__VISUALC8__) + #define wxHAS_STRFTIME #endif // ---------------------------------------------------------------------------- @@ -267,7 +247,7 @@ public: // adoption of the Gregorian calendar (see IsGregorian()) // // All data and comments taken verbatim from "The Calendar FAQ (v 2.0)" - // by Claus T�ndering, http://www.pip.dknet.dk/~c-t/calendar.html + // by Claus Tøndering, http://www.pip.dknet.dk/~c-t/calendar.html // except for the comments "we take". // // Symbol "->" should be read as "was followed by" in the comments @@ -482,7 +462,9 @@ public: // instead of modifying the member fields directly! struct WXDLLIMPEXP_BASE Tm { - wxDateTime_t msec, sec, min, hour, mday; + wxDateTime_t msec, sec, min, hour, + mday, // Day of the month in 1..31 range. + yday; // Day of the year in 0..365 range. Month mon; int year; @@ -517,9 +499,10 @@ public: // the timezone we correspond to TimeZone m_tz; - // these values can't be accessed directly because they're not always - // computed and we calculate them on demand - wxDateTime_t wday, yday; + // This value can only be accessed via GetWeekDay() and not directly + // because it's not always computed when creating this object and may + // need to be calculated on demand. + wxDateTime_t wday; }; // static methods @@ -967,12 +950,15 @@ public: // SYSTEMTIME format // ------------------------------------------------------------------------ #ifdef __WXMSW__ - // convert SYSTEMTIME to wxDateTime - wxDateTime& SetFromMSWSysTime(const struct _SYSTEMTIME&); + wxDateTime& SetFromMSWSysTime(const struct _SYSTEMTIME& st); // convert wxDateTime to SYSTEMTIME - void GetAsMSWSysTime(struct _SYSTEMTIME*) const; + void GetAsMSWSysTime(struct _SYSTEMTIME* st) const; + + // same as above but only take date part into account, time is always zero + wxDateTime& SetFromMSWSysDate(const struct _SYSTEMTIME& st); + void GetAsMSWSysDate(struct _SYSTEMTIME* st) const; #endif // __WXMSW__ // comparison (see also functions below for operator versions) @@ -1005,37 +991,37 @@ public: inline bool operator<(const wxDateTime& dt) const { - wxASSERT_MSG( IsValid() && dt.IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid() && dt.IsValid(), wxT("invalid wxDateTime") ); return GetValue() < dt.GetValue(); } inline bool operator<=(const wxDateTime& dt) const { - wxASSERT_MSG( IsValid() && dt.IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid() && dt.IsValid(), wxT("invalid wxDateTime") ); return GetValue() <= dt.GetValue(); } inline bool operator>(const wxDateTime& dt) const { - wxASSERT_MSG( IsValid() && dt.IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid() && dt.IsValid(), wxT("invalid wxDateTime") ); return GetValue() > dt.GetValue(); } inline bool operator>=(const wxDateTime& dt) const { - wxASSERT_MSG( IsValid() && dt.IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid() && dt.IsValid(), wxT("invalid wxDateTime") ); return GetValue() >= dt.GetValue(); } inline bool operator==(const wxDateTime& dt) const { - wxASSERT_MSG( IsValid() && dt.IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid() && dt.IsValid(), wxT("invalid wxDateTime") ); return GetValue() == dt.GetValue(); } inline bool operator!=(const wxDateTime& dt) const { - wxASSERT_MSG( IsValid() && dt.IsValid(), _T("invalid wxDateTime") ); + wxASSERT_MSG( IsValid() && dt.IsValid(), wxT("invalid wxDateTime") ); return GetValue() != dt.GetValue(); } @@ -1098,104 +1084,42 @@ public: inline wxTimeSpan Subtract(const wxDateTime& dt) const; inline wxTimeSpan operator-(const wxDateTime& dt2) const; - // conversion to/from text: all conversions from text return the pointer to - // the next character following the date specification (i.e. the one where - // the scan had to stop) or NULL on failure; for the versions taking - // wxString or wxCStrData, we don't know if the user code needs char* or - // wchar_t* pointer and so we return char* one for compatibility with the - // existing ANSI code and also return iterator in another output parameter - // (it will be equal to end if the entire string was parsed) + // conversion to/from text // ------------------------------------------------------------------------ + // all conversions functions return true to indicate whether parsing + // succeeded or failed and fill in the provided end iterator, which must + // not be NULL, with the location of the character where the parsing + // stopped (this will be end() of the passed string if everything was + // parsed) + // parse a string in RFC 822 format (found e.g. in mail headers and // having the form "Wed, 10 Feb 1999 19:07:07 +0100") - const char *ParseRfc822Date(const wxString& date, - wxString::const_iterator *end = NULL); - const char *ParseRfc822Date(const wxCStrData& date, - wxString::const_iterator *end = NULL) - { - return ParseRfc822Date(date.AsString(), end); - } - - const wchar_t *ParseRfc822Date(const wchar_t* date) - { - return ReturnEndAsWidePtr(&wxDateTime::ParseRfc822Date, date); - } - - const char *ParseRfc822Date(const char* date) - { - return ParseRfc822Date(wxString(date)); - } + bool ParseRfc822Date(const wxString& date, + wxString::const_iterator *end); // parse a date/time in the given format (see strptime(3)), fill in // the missing (in the string) fields with the values of dateDef (by // default, they will not change if they had valid values or will // default to Today() otherwise) - - // notice that we unfortunately need all those overloads because we use - // the type of the date string to select the return value of the - // function: it's wchar_t if a wide string is passed for compatibility - // with the code doing "const wxChar *p = dt.ParseFormat(_T("..."))", - // but char* in all other cases for compatibility with ANSI build which - // allowed code like "const char *p = dt.ParseFormat("...")" - // - // so we need wchar_t overload and now passing s.c_str() as first - // argument is ambiguous because it's convertible to both wxString and - // wchar_t* and now it's passing char* which becomes ambiguous as it is - // convertible to both wxString and wxCStrData hence we need char* - // overload too - // - // and to make our life more miserable we also pay for having the - // optional dateDef parameter: as it's almost never used, we want to - // allow people to omit it when specifying the end iterator output - // parameter but we still have to allow specifying dateDef too, so we - // need another overload for this - // - // FIXME: all this mess could be avoided by using some class similar to - // wxFormatString, i.e. remembering string [pointer] of any type - // and convertible to either char* or wchar_t* as wxCStrData and - // having only 1 (or 2, because of the last paragraph above) - // overload taking it, see #9560 - const char *ParseFormat(const wxString& date, - const wxString& format = wxDefaultDateTimeFormat, - const wxDateTime& dateDef = wxDefaultDateTime, - wxString::const_iterator *end = NULL); - - const char *ParseFormat(const wxString& date, - const wxString& format, - wxString::const_iterator *end) + bool ParseFormat(const wxString& date, + const wxString& format, + const wxDateTime& dateDef, + wxString::const_iterator *end); + + bool ParseFormat(const wxString& date, + const wxString& format, + wxString::const_iterator *end) { return ParseFormat(date, format, wxDefaultDateTime, end); } - const char *ParseFormat(const wxCStrData& date, - const wxString& format = wxDefaultDateTimeFormat, - const wxDateTime& dateDef = wxDefaultDateTime, - wxString::const_iterator *end = NULL) + bool ParseFormat(const wxString& date, + wxString::const_iterator *end) { - return ParseFormat(date.AsString(), format, dateDef, end); + return ParseFormat(date, wxDefaultDateTimeFormat, wxDefaultDateTime, end); } - const wchar_t *ParseFormat(const wchar_t *date, - const wxString& format = wxDefaultDateTimeFormat, - const wxDateTime& dateDef = wxDefaultDateTime) - { - const wxString datestr(date); - wxString::const_iterator end; - if ( !ParseFormat(datestr, format, dateDef, &end) ) - return NULL; - - return date + (end - datestr.begin()); - } - - const char *ParseFormat(const char *date, - const wxString& format = "%c", - const wxDateTime& dateDef = wxDefaultDateTime) - { - return ParseFormat(wxString(date), format, dateDef); - } - - // parse a string containing date, time or both in ISO 8601 format // // notice that these functions are new in wx 3.0 and so we don't @@ -1221,65 +1145,18 @@ public: // parse a string containing the date/time in "free" format, this // function will try to make an educated guess at the string contents - const char *ParseDateTime(const wxString& datetime, - wxString::const_iterator *end = NULL); - - const char *ParseDateTime(const wxCStrData& datetime, - wxString::const_iterator *end = NULL) - { - return ParseDateTime(datetime.AsString(), end); - } - - const wchar_t *ParseDateTime(const wchar_t *datetime) - { - return ReturnEndAsWidePtr(&wxDateTime::ParseDateTime, datetime); - } - - const char *ParseDateTime(const char *datetime) - { - return ParseDateTime(wxString(datetime)); - } + bool ParseDateTime(const wxString& datetime, + wxString::const_iterator *end); // parse a string containing the date only in "free" format (less // flexible than ParseDateTime) - const char *ParseDate(const wxString& date, - wxString::const_iterator *end = NULL); - - const char *ParseDate(const wxCStrData& date, - wxString::const_iterator *end = NULL) - { - return ParseDate(date.AsString(), end); - } - - const wchar_t *ParseDate(const wchar_t *date) - { - return ReturnEndAsWidePtr(&wxDateTime::ParseDate, date); - } - - const char *ParseDate(const char *date) - { - return ParseDate(wxString(date)); - } + bool ParseDate(const wxString& date, + wxString::const_iterator *end); // parse a string containing the time only in "free" format - const char *ParseTime(const wxString& time, - wxString::const_iterator *end = NULL); - - const char *ParseTime(const wxCStrData& time, - wxString::const_iterator *end = NULL) - { - return ParseTime(time.AsString(), end); - } - - const wchar_t *ParseTime(const wchar_t *time) - { - return ReturnEndAsWidePtr(&wxDateTime::ParseTime, time); - } + bool ParseTime(const wxString& time, + wxString::const_iterator *end); - const char *ParseTime(const char *time) - { - return ParseTime(wxString(time)); - } // this function accepts strftime()-like format string (default // argument corresponds to the preferred date and time representation @@ -1303,6 +1180,52 @@ public: wxString FormatISOCombined(char sep = 'T') const { return FormatISODate() + sep + FormatISOTime(); } + + // backwards compatible versions of the parsing functions: they return an + // object representing the next character following the date specification + // (i.e. the one where the scan had to stop) or a special NULL-like object + // on failure + // + // they're not deprecated because a lot of existing code uses them and + // there is no particular harm in keeping them but you should still prefer + // the versions above in the new code + wxAnyStrPtr ParseRfc822Date(const wxString& date) + { + wxString::const_iterator end; + return ParseRfc822Date(date, &end) ? wxAnyStrPtr(date, end) + : wxAnyStrPtr(); + } + + wxAnyStrPtr ParseFormat(const wxString& date, + const wxString& format = wxDefaultDateTimeFormat, + const wxDateTime& dateDef = wxDefaultDateTime) + { + wxString::const_iterator end; + return ParseFormat(date, format, dateDef, &end) ? wxAnyStrPtr(date, end) + : wxAnyStrPtr(); + } + + wxAnyStrPtr ParseDateTime(const wxString& datetime) + { + wxString::const_iterator end; + return ParseDateTime(datetime, &end) ? wxAnyStrPtr(datetime, end) + : wxAnyStrPtr(); + } + + wxAnyStrPtr ParseDate(const wxString& date) + { + wxString::const_iterator end; + return ParseDate(date, &end) ? wxAnyStrPtr(date, end) + : wxAnyStrPtr(); + } + + wxAnyStrPtr ParseTime(const wxString& time) + { + wxString::const_iterator end; + return ParseTime(time, &end) ? wxAnyStrPtr(time, end) + : wxAnyStrPtr(); + } + // implementation // ------------------------------------------------------------------------ @@ -1326,23 +1249,6 @@ public: static struct tm *GetTmNow(struct tm *tmstruct); private: - // helper function for defining backward-compatible wrappers for code - // using wchar_t* pointer instead of wxString iterators - typedef - const char *(wxDateTime::*StringMethod)(const wxString& s, - wxString::const_iterator *end); - - const wchar_t *ReturnEndAsWidePtr(StringMethod func, const wchar_t *p) - { - const wxString s(p); - wxString::const_iterator end; - if ( !(this->*func)(s, &end) ) - return NULL; - - return p + (end - s.begin()); - } - - // the current country - as it's the same for all program objects (unless // it runs on a _really_ big cluster system :-), this is a static member: // see SetCountry() and GetCountry() @@ -1822,7 +1728,9 @@ protected: inline bool wxDateTime::IsInStdRange() const { - return m_time >= 0l && (m_time / TIME_T_FACTOR) < LONG_MAX; + // currently we don't know what is the real type of time_t so prefer to err + // on the safe side and limit it to 32 bit values which is safe everywhere + return m_time >= 0l && (m_time / TIME_T_FACTOR) < wxINT32_MAX; } /* static */ @@ -1882,7 +1790,7 @@ inline wxDateTime::wxDateTime(double jdn) inline wxDateTime& wxDateTime::Set(const Tm& tm) { - wxASSERT_MSG( tm.IsValid(), _T("invalid broken down date/time") ); + wxASSERT_MSG( tm.IsValid(), wxT("invalid broken down date/time") ); return Set(tm.mday, (Month)tm.mon, tm.year, tm.hour, tm.min, tm.sec, tm.msec); @@ -1913,14 +1821,14 @@ inline wxDateTime::wxDateTime(wxDateTime_t day, inline wxLongLong wxDateTime::GetValue() const { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime")); return m_time; } inline time_t wxDateTime::GetTicks() const { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime")); if ( !IsInStdRange() ) { return (time_t)-1; @@ -1988,21 +1896,21 @@ inline wxDateTime wxDateTime::GetYearDay(wxDateTime_t yday) const inline bool wxDateTime::IsEqualTo(const wxDateTime& datetime) const { - wxASSERT_MSG( IsValid() && datetime.IsValid(), _T("invalid wxDateTime")); + wxASSERT_MSG( IsValid() && datetime.IsValid(), wxT("invalid wxDateTime")); return m_time == datetime.m_time; } inline bool wxDateTime::IsEarlierThan(const wxDateTime& datetime) const { - wxASSERT_MSG( IsValid() && datetime.IsValid(), _T("invalid wxDateTime")); + wxASSERT_MSG( IsValid() && datetime.IsValid(), wxT("invalid wxDateTime")); return m_time < datetime.m_time; } inline bool wxDateTime::IsLaterThan(const wxDateTime& datetime) const { - wxASSERT_MSG( IsValid() && datetime.IsValid(), _T("invalid wxDateTime")); + wxASSERT_MSG( IsValid() && datetime.IsValid(), wxT("invalid wxDateTime")); return m_time > datetime.m_time; } @@ -2059,14 +1967,14 @@ inline bool wxDateTime::IsEqualUpTo(const wxDateTime& dt, inline wxDateTime wxDateTime::Add(const wxTimeSpan& diff) const { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime")); return wxDateTime(m_time + diff.GetValue()); } inline wxDateTime& wxDateTime::Add(const wxTimeSpan& diff) { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime")); m_time += diff.GetValue(); @@ -2080,14 +1988,14 @@ inline wxDateTime& wxDateTime::operator+=(const wxTimeSpan& diff) inline wxDateTime wxDateTime::Subtract(const wxTimeSpan& diff) const { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime")); return wxDateTime(m_time - diff.GetValue()); } inline wxDateTime& wxDateTime::Subtract(const wxTimeSpan& diff) { - wxASSERT_MSG( IsValid(), _T("invalid wxDateTime")); + wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime")); m_time -= diff.GetValue(); @@ -2101,7 +2009,7 @@ inline wxDateTime& wxDateTime::operator-=(const wxTimeSpan& diff) inline wxTimeSpan wxDateTime::Subtract(const wxDateTime& datetime) const { - wxASSERT_MSG( IsValid() && datetime.IsValid(), _T("invalid wxDateTime")); + wxASSERT_MSG( IsValid() && datetime.IsValid(), wxT("invalid wxDateTime")); return wxTimeSpan(GetValue() - datetime.GetValue()); }