X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dd36b5a3e54168c3bf8c809f0db613c000ae7e50..931d6a47c32a5b4c283243cb553ce71ee2b535d5:/include/wx/datetime.h?ds=inline diff --git a/include/wx/datetime.h b/include/wx/datetime.h index 351ced98ea..f500985f28 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -5,7 +5,6 @@ // Author: Vadim Zeitlin // Modified by: // Created: 10.02.99 -// RCS-ID: $Id$ // Copyright: (c) 1998 Vadim Zeitlin // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -19,7 +18,7 @@ #ifdef __WXWINCE__ #include "wx/msw/wince/time.h" -#elif !defined(__WXPALMOS5__) +#else #include #endif // OS @@ -31,7 +30,7 @@ class WXDLLIMPEXP_FWD_BASE wxDateTime; class WXDLLIMPEXP_FWD_BASE wxTimeSpan; class WXDLLIMPEXP_FWD_BASE wxDateSpan; -#ifdef __WXMSW__ +#ifdef __WINDOWS__ struct _SYSTEMTIME; #endif @@ -53,27 +52,6 @@ struct _SYSTEMTIME; * 5. wxDateTimeHolidayAuthority for Easter and other christian feasts */ -/* Two wrapper functions for thread safety */ -#ifdef HAVE_LOCALTIME_R -#define wxLocaltime_r localtime_r -#else -WXDLLIMPEXP_BASE struct tm *wxLocaltime_r(const time_t*, struct tm*); -#if wxUSE_THREADS && !defined(__WINDOWS__) && !defined(__WATCOMC__) - // On Windows, localtime _is_ threadsafe! -#warning using pseudo thread-safe wrapper for localtime to emulate localtime_r -#endif -#endif - -#ifdef HAVE_GMTIME_R -#define wxGmtime_r gmtime_r -#else -WXDLLIMPEXP_BASE struct tm *wxGmtime_r(const time_t*, struct tm*); -#if wxUSE_THREADS && !defined(__WINDOWS__) && !defined(__WATCOMC__) - // On Windows, gmtime _is_ threadsafe! -#warning using pseudo thread-safe wrapper for gmtime to emulate gmtime_r -#endif -#endif - /* The three (main) classes declared in this header represent: @@ -128,8 +106,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 @@ -173,7 +151,7 @@ public: // the time in the current time zone Local, - // zones from GMT (= Greenwhich Mean Time): they're guaranteed to be + // zones from GMT (= Greenwich Mean Time): they're guaranteed to be // consequent numbers, so writing something like `GMT0 + offset' is // safe if abs(offset) <= 12 @@ -243,124 +221,6 @@ public: // TODO Hebrew, Chinese, Maya, ... (just kidding) (or then may be not?) }; - // these values only are used to identify the different dates of - // 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 - // except for the comments "we take". - // - // Symbol "->" should be read as "was followed by" in the comments - // which follow. - enum GregorianAdoption - { - Gr_Unknown, // no data for this country or it's too uncertain to use - Gr_Standard, // on the day 0 of Gregorian calendar: 15 Oct 1582 - - Gr_Alaska, // Oct 1867 when Alaska became part of the USA - Gr_Albania, // Dec 1912 - - Gr_Austria = Gr_Unknown, // Different regions on different dates - Gr_Austria_Brixen, // 5 Oct 1583 -> 16 Oct 1583 - Gr_Austria_Salzburg = Gr_Austria_Brixen, - Gr_Austria_Tyrol = Gr_Austria_Brixen, - Gr_Austria_Carinthia, // 14 Dec 1583 -> 25 Dec 1583 - Gr_Austria_Styria = Gr_Austria_Carinthia, - - Gr_Belgium, // Then part of the Netherlands - - Gr_Bulgaria = Gr_Unknown, // Unknown precisely (from 1915 to 1920) - Gr_Bulgaria_1, // 18 Mar 1916 -> 1 Apr 1916 - Gr_Bulgaria_2, // 31 Mar 1916 -> 14 Apr 1916 - Gr_Bulgaria_3, // 3 Sep 1920 -> 17 Sep 1920 - - Gr_Canada = Gr_Unknown, // Different regions followed the changes in - // Great Britain or France - - Gr_China = Gr_Unknown, // Different authorities say: - Gr_China_1, // 18 Dec 1911 -> 1 Jan 1912 - Gr_China_2, // 18 Dec 1928 -> 1 Jan 1929 - - Gr_Czechoslovakia, // (Bohemia and Moravia) 6 Jan 1584 -> 17 Jan 1584 - Gr_Denmark, // (including Norway) 18 Feb 1700 -> 1 Mar 1700 - Gr_Egypt, // 1875 - Gr_Estonia, // 1918 - Gr_Finland, // Then part of Sweden - - Gr_France, // 9 Dec 1582 -> 20 Dec 1582 - Gr_France_Alsace, // 4 Feb 1682 -> 16 Feb 1682 - Gr_France_Lorraine, // 16 Feb 1760 -> 28 Feb 1760 - Gr_France_Strasbourg, // February 1682 - - Gr_Germany = Gr_Unknown, // Different states on different dates: - Gr_Germany_Catholic, // 1583-1585 (we take 1584) - Gr_Germany_Prussia, // 22 Aug 1610 -> 2 Sep 1610 - Gr_Germany_Protestant, // 18 Feb 1700 -> 1 Mar 1700 - - Gr_GreatBritain, // 2 Sep 1752 -> 14 Sep 1752 (use 'cal(1)') - - Gr_Greece, // 9 Mar 1924 -> 23 Mar 1924 - Gr_Hungary, // 21 Oct 1587 -> 1 Nov 1587 - Gr_Ireland = Gr_GreatBritain, - Gr_Italy = Gr_Standard, - - Gr_Japan = Gr_Unknown, // Different authorities say: - Gr_Japan_1, // 19 Dec 1872 -> 1 Jan 1873 - Gr_Japan_2, // 19 Dec 1892 -> 1 Jan 1893 - Gr_Japan_3, // 18 Dec 1918 -> 1 Jan 1919 - - Gr_Latvia, // 1915-1918 (we take 1915) - Gr_Lithuania, // 1915 - Gr_Luxemburg, // 14 Dec 1582 -> 25 Dec 1582 - Gr_Netherlands = Gr_Belgium, // (including Belgium) 1 Jan 1583 - - // this is too weird to take into account: the Gregorian calendar was - // introduced twice in Groningen, first time 28 Feb 1583 was followed - // by 11 Mar 1583, then it has gone back to Julian in the summer of - // 1584 and then 13 Dec 1700 -> 12 Jan 1701 - which is - // the date we take here - Gr_Netherlands_Groningen, // 13 Dec 1700 -> 12 Jan 1701 - Gr_Netherlands_Gelderland, // 30 Jun 1700 -> 12 Jul 1700 - Gr_Netherlands_Utrecht, // (and Overijssel) 30 Nov 1700->12 Dec 1700 - Gr_Netherlands_Friesland, // (and Drenthe) 31 Dec 1700 -> 12 Jan 1701 - - Gr_Norway = Gr_Denmark, // Then part of Denmark - Gr_Poland = Gr_Standard, - Gr_Portugal = Gr_Standard, - Gr_Romania, // 31 Mar 1919 -> 14 Apr 1919 - Gr_Russia, // 31 Jan 1918 -> 14 Feb 1918 - Gr_Scotland = Gr_GreatBritain, - Gr_Spain = Gr_Standard, - - // Sweden has a curious history. Sweden decided to make a gradual - // change from the Julian to the Gregorian calendar. By dropping every - // leap year from 1700 through 1740 the eleven superfluous days would - // be omitted and from 1 Mar 1740 they would be in sync with the - // Gregorian calendar. (But in the meantime they would be in sync with - // nobody!) - // - // So 1700 (which should have been a leap year in the Julian calendar) - // was not a leap year in Sweden. However, by mistake 1704 and 1708 - // became leap years. This left Sweden out of synchronisation with - // both the Julian and the Gregorian world, so they decided to go back - // to the Julian calendar. In order to do this, they inserted an extra - // day in 1712, making that year a double leap year! So in 1712, - // February had 30 days in Sweden. - // - // Later, in 1753, Sweden changed to the Gregorian calendar by - // dropping 11 days like everyone else. - Gr_Sweden = Gr_Finland, // 17 Feb 1753 -> 1 Mar 1753 - - Gr_Switzerland = Gr_Unknown,// Different cantons used different dates - Gr_Switzerland_Catholic, // 1583, 1584 or 1597 (we take 1584) - Gr_Switzerland_Protestant, // 31 Dec 1700 -> 12 Jan 1701 - - Gr_Turkey, // 1 Jan 1927 - Gr_USA = Gr_GreatBritain, - Gr_Wales = Gr_GreatBritain, - Gr_Yugoslavia // 1919 - }; - // the country parameter is used so far for calculating the start and // the end of DST period and for deciding whether the date is a work // day or not @@ -429,7 +289,7 @@ public: // helper classes // ------------------------------------------------------------------------ - // a class representing a time zone: basicly, this is just an offset + // a class representing a time zone: basically, this is just an offset // (in seconds) from GMT class WXDLLIMPEXP_BASE TimeZone { @@ -462,7 +322,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; @@ -497,9 +359,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 @@ -624,7 +487,7 @@ public: wxDateTime_t minute = 0, wxDateTime_t second = 0, wxDateTime_t millisec = 0); -#ifdef __WXMSW__ +#ifdef __WINDOWS__ wxDateTime(const struct _SYSTEMTIME& st) { SetFromMSWSysTime(st); @@ -711,7 +574,7 @@ public: // default assignment operator is ok // calendar calculations (functions which set the date only leave the time - // unchanged, e.g. don't explictly zero it): SetXXX() functions modify the + // unchanged, e.g. don't explicitly zero it): SetXXX() functions modify the // object itself, GetXXX() ones return a new object. // ------------------------------------------------------------------------ @@ -927,14 +790,6 @@ public: // because the holidays are different in different countries bool IsWorkDay(Country country = Country_Default) const; - // is this date later than Gregorian calendar introduction for the - // given country (see enum GregorianAdoption)? - // - // NB: this function shouldn't be considered as absolute authority in - // the matter. Besides, for some countries the exact date of - // adoption of the Gregorian calendar is simply unknown. - bool IsGregorianDate(GregorianAdoption country = Gr_Standard) const; - // dos date and time format // ------------------------------------------------------------------------ @@ -946,14 +801,17 @@ public: // SYSTEMTIME format // ------------------------------------------------------------------------ -#ifdef __WXMSW__ - +#ifdef __WINDOWS__ // convert SYSTEMTIME to wxDateTime - wxDateTime& SetFromMSWSysTime(const struct _SYSTEMTIME&); + wxDateTime& SetFromMSWSysTime(const struct _SYSTEMTIME& st); // convert wxDateTime to SYSTEMTIME - void GetAsMSWSysTime(struct _SYSTEMTIME*) const; -#endif // __WXMSW__ + 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 // __WINDOWS__ // comparison (see also functions below for operator versions) // ------------------------------------------------------------------------ @@ -985,37 +843,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(); } @@ -1078,6 +936,8 @@ public: inline wxTimeSpan Subtract(const wxDateTime& dt) const; inline wxTimeSpan operator-(const wxDateTime& dt2) const; + wxDateSpan DiffAsDateSpan(const wxDateTime& dt) const; + // conversion to/from text // ------------------------------------------------------------------------ @@ -1220,6 +1080,52 @@ public: : wxAnyStrPtr(); } + // In addition to wxAnyStrPtr versions above we also must provide the + // overloads for C strings as we must return a pointer into the original + // string and not inside a temporary wxString which would have been created + // if the overloads above were used. + // + // And then we also have to provide the overloads for wxCStrData, as usual. + // Unfortunately those ones can't return anything as we don't have any + // sufficiently long-lived wxAnyStrPtr to return from them: any temporary + // strings it would point to would be destroyed when this function returns + // making it impossible to dereference the return value. So we just don't + // return anything from here which at least allows to keep compatibility + // with the code not testing the return value. Other uses of this method + // need to be converted to use one of the new bool-returning overloads + // above. + void ParseRfc822Date(const wxCStrData& date) + { ParseRfc822Date(wxString(date)); } + const char* ParseRfc822Date(const char* date); + const wchar_t* ParseRfc822Date(const wchar_t* date); + + void ParseFormat(const wxCStrData& date, + const wxString& format = wxDefaultDateTimeFormat, + const wxDateTime& dateDef = wxDefaultDateTime) + { ParseFormat(wxString(date), format, dateDef); } + const char* ParseFormat(const char* date, + const wxString& format = wxDefaultDateTimeFormat, + const wxDateTime& dateDef = wxDefaultDateTime); + const wchar_t* ParseFormat(const wchar_t* date, + const wxString& format = wxDefaultDateTimeFormat, + const wxDateTime& dateDef = wxDefaultDateTime); + + void ParseDateTime(const wxCStrData& datetime) + { ParseDateTime(wxString(datetime)); } + const char* ParseDateTime(const char* datetime); + const wchar_t* ParseDateTime(const wchar_t* datetime); + + void ParseDate(const wxCStrData& date) + { ParseDate(wxString(date)); } + const char* ParseDate(const char* date); + const wchar_t* ParseDate(const wchar_t* date); + + void ParseTime(const wxCStrData& time) + { ParseTime(wxString(time)); } + const char* ParseTime(const char* time); + const wchar_t* ParseTime(const wchar_t* time); + + // implementation // ------------------------------------------------------------------------ @@ -1546,6 +1452,8 @@ public: int GetYears() const { return m_years; } // get number of months int GetMonths() const { return m_months; } + // returns 12*GetYears() + GetMonths() + int GetTotalMonths() const { return 12*m_years + m_months; } // get number of weeks int GetWeeks() const { return m_weeks; } // get number of days @@ -1722,7 +1630,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 */ @@ -1744,9 +1654,16 @@ inline wxDateTime wxDateTime::Today() #if (!(defined(__VISAGECPP__) && __IBMCPP__ >= 400)) inline wxDateTime& wxDateTime::Set(time_t timet) { - // assign first to avoid long multiplication overflow! - m_time = timet - WX_TIME_BASE_OFFSET ; - m_time *= TIME_T_FACTOR; + if ( timet == (time_t)-1 ) + { + m_time = wxInvalidDateTime.m_time; + } + else + { + // assign first to avoid long multiplication overflow! + m_time = timet - WX_TIME_BASE_OFFSET; + m_time *= TIME_T_FACTOR; + } return *this; } @@ -1782,7 +1699,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); @@ -1813,14 +1730,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; @@ -1888,21 +1805,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; } @@ -1959,14 +1876,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(); @@ -1980,14 +1897,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(); @@ -2001,7 +1918,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()); } @@ -2082,9 +1999,9 @@ inline wxLongLong wxTimeSpan::GetSeconds() const inline int wxTimeSpan::GetMinutes() const { - // explicit cast to int suppresses a warning with CodeWarrior and possibly - // others (changing the return type to long from int is impossible in 2.8) - return (int)((GetSeconds() / 60l).GetLo()); + // For compatibility, this method (and the other accessors) return int, + // even though GetLo() actually returns unsigned long with greater range. + return static_cast((GetSeconds() / 60l).GetLo()); } inline int wxTimeSpan::GetHours() const