1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/datetime.h
3 // Purpose:     declarations of time/date related classes (wxDateTime,
4 //              wxTimeSpan)
5 // Author:      Vadim Zeitlin
6 // Modified by:
7 // Created:     10.02.99
8 // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef _WX_DATETIME_H
13 #define _WX_DATETIME_H
14 
15 #include "wx/defs.h"
16 
17 #if wxUSE_DATETIME
18 
19 #include <time.h>
20 
21 #include <limits.h>             // for INT_MIN
22 
23 #include "wx/longlong.h"
24 #include "wx/anystr.h"
25 
26 class WXDLLIMPEXP_FWD_BASE wxDateTime;
27 class WXDLLIMPEXP_FWD_BASE wxTimeSpan;
28 class WXDLLIMPEXP_FWD_BASE wxDateSpan;
29 #ifdef __WINDOWS__
30 struct _SYSTEMTIME;
31 #endif
32 
33 #include "wx/dynarray.h"
34 
35 // not all c-runtimes are based on 1/1/1970 being (time_t) 0
36 // set this to the corresponding value in seconds 1/1/1970 has on your
37 // systems c-runtime
38 
39 #define WX_TIME_BASE_OFFSET 0
40 
41 /*
42  * TODO
43  *
44  * + 1. Time zones with minutes (make TimeZone a class)
45  * ? 2. getdate() function like under Solaris
46  * + 3. text conversion for wxDateSpan
47  * + 4. pluggable modules for the workdays calculations
48  *   5. wxDateTimeHolidayAuthority for Easter and other christian feasts
49  */
50 
51 /*
52   The three (main) classes declared in this header represent:
53 
54   1. An absolute moment in the time (wxDateTime)
55   2. A difference between two moments in the time, positive or negative
56      (wxTimeSpan)
57   3. A logical difference between two dates expressed in
58      years/months/weeks/days (wxDateSpan)
59 
60   The following arithmetic operations are permitted (all others are not):
61 
62   addition
63   --------
64 
65   wxDateTime + wxTimeSpan = wxDateTime
66   wxDateTime + wxDateSpan = wxDateTime
67   wxTimeSpan + wxTimeSpan = wxTimeSpan
68   wxDateSpan + wxDateSpan = wxDateSpan
69 
70   subtraction
71   ------------
72   wxDateTime - wxDateTime = wxTimeSpan
73   wxDateTime - wxTimeSpan = wxDateTime
74   wxDateTime - wxDateSpan = wxDateTime
75   wxTimeSpan - wxTimeSpan = wxTimeSpan
76   wxDateSpan - wxDateSpan = wxDateSpan
77 
78   multiplication
79   --------------
80   wxTimeSpan * number = wxTimeSpan
81   number * wxTimeSpan = wxTimeSpan
82   wxDateSpan * number = wxDateSpan
83   number * wxDateSpan = wxDateSpan
84 
85   unitary minus
86   -------------
87   -wxTimeSpan = wxTimeSpan
88   -wxDateSpan = wxDateSpan
89 
90   For each binary operation OP (+, -, *) we have the following operatorOP=() as
91   a method and the method with a symbolic name OPER (Add, Subtract, Multiply)
92   as a synonym for it and another const method with the same name which returns
93   the changed copy of the object and operatorOP() as a global function which is
94   implemented in terms of the const version of OPEN. For the unary - we have
95   operator-() as a method, Neg() as synonym for it and Negate() which returns
96   the copy of the object with the changed sign.
97 */
98 
99 // an invalid/default date time object which may be used as the default
100 // argument for arguments of type wxDateTime; it is also returned by all
101 // functions returning wxDateTime on failure (this is why it is also called
102 // wxInvalidDateTime)
103 class WXDLLIMPEXP_FWD_BASE wxDateTime;
104 
105 extern WXDLLIMPEXP_DATA_BASE(const char) wxDefaultDateTimeFormat[];
106 extern WXDLLIMPEXP_DATA_BASE(const char) wxDefaultTimeSpanFormat[];
107 extern WXDLLIMPEXP_DATA_BASE(const wxDateTime) wxDefaultDateTime;
108 
109 #define wxInvalidDateTime wxDefaultDateTime
110 
111 
112 // ----------------------------------------------------------------------------
113 // conditional compilation
114 // ----------------------------------------------------------------------------
115 
116 // if configure detected strftime(), we have it too
117 #ifdef HAVE_STRFTIME
118     #define wxHAS_STRFTIME
119 // suppose everyone else has strftime
120 #else
121     #define wxHAS_STRFTIME
122 #endif
123 
124 // ----------------------------------------------------------------------------
125 // wxDateTime represents an absolute moment in the time
126 // ----------------------------------------------------------------------------
127 
128 class WXDLLIMPEXP_BASE wxDateTime
129 {
130 public:
131     // types
132     // ------------------------------------------------------------------------
133 
134         // a small unsigned integer type for storing things like minutes,
135         // seconds &c. It should be at least short (i.e. not char) to contain
136         // the number of milliseconds - it may also be 'int' because there is
137         // no size penalty associated with it in our code, we don't store any
138         // data in this format
139     typedef unsigned short wxDateTime_t;
140 
141     // constants
142     // ------------------------------------------------------------------------
143 
144         // the timezones
145     enum TZ
146     {
147         // the time in the current time zone
148         Local,
149 
150         // zones from GMT (= Greenwich Mean Time): they're guaranteed to be
151         // consequent numbers, so writing something like `GMT0 + offset' is
152         // safe if abs(offset) <= 12
153 
154         // underscore stands for minus
155         GMT_12, GMT_11, GMT_10, GMT_9, GMT_8, GMT_7,
156         GMT_6, GMT_5, GMT_4, GMT_3, GMT_2, GMT_1,
157         GMT0,
158         GMT1, GMT2, GMT3, GMT4, GMT5, GMT6,
159         GMT7, GMT8, GMT9, GMT10, GMT11, GMT12, GMT13,
160         // Note that GMT12 and GMT_12 are not the same: there is a difference
161         // of exactly one day between them
162 
163         // some symbolic names for TZ
164 
165         // Europe
166         WET = GMT0,                         // Western Europe Time
167         WEST = GMT1,                        // Western Europe Summer Time
168         CET = GMT1,                         // Central Europe Time
169         CEST = GMT2,                        // Central Europe Summer Time
170         EET = GMT2,                         // Eastern Europe Time
171         EEST = GMT3,                        // Eastern Europe Summer Time
172         MSK = GMT3,                         // Moscow Time
173         MSD = GMT4,                         // Moscow Summer Time
174 
175         // US and Canada
176         AST = GMT_4,                        // Atlantic Standard Time
177         ADT = GMT_3,                        // Atlantic Daylight Time
178         EST = GMT_5,                        // Eastern Standard Time
179         EDT = GMT_4,                        // Eastern Daylight Saving Time
180         CST = GMT_6,                        // Central Standard Time
181         CDT = GMT_5,                        // Central Daylight Saving Time
182         MST = GMT_7,                        // Mountain Standard Time
183         MDT = GMT_6,                        // Mountain Daylight Saving Time
184         PST = GMT_8,                        // Pacific Standard Time
185         PDT = GMT_7,                        // Pacific Daylight Saving Time
186         HST = GMT_10,                       // Hawaiian Standard Time
187         AKST = GMT_9,                       // Alaska Standard Time
188         AKDT = GMT_8,                       // Alaska Daylight Saving Time
189 
190         // Australia
191 
192         A_WST = GMT8,                       // Western Standard Time
193         A_CST = GMT13 + 1,                  // Central Standard Time (+9.5)
194         A_EST = GMT10,                      // Eastern Standard Time
195         A_ESST = GMT11,                     // Eastern Summer Time
196 
197         // New Zealand
198         NZST = GMT12,                       // Standard Time
199         NZDT = GMT13,                       // Daylight Saving Time
200 
201         // TODO add more symbolic timezone names here
202 
203         // Universal Coordinated Time = the new and politically correct name
204         // for GMT
205         UTC = GMT0
206     };
207 
208         // the calendar systems we know about: notice that it's valid (for
209         // this classes purpose anyhow) to work with any of these calendars
210         // even with the dates before the historical appearance of the
211         // calendar
212     enum Calendar
213     {
214         Gregorian,  // current calendar
215         Julian      // calendar in use since -45 until the 1582 (or later)
216 
217         // TODO Hebrew, Chinese, Maya, ... (just kidding) (or then may be not?)
218     };
219 
220         // the country parameter is used so far for calculating the start and
221         // the end of DST period and for deciding whether the date is a work
222         // day or not
223         //
224         // TODO move this to intl.h
225 
226     enum Country
227     {
228         Country_Unknown, // no special information for this country
229         Country_Default, // set the default country with SetCountry() method
230                          // or use the default country with any other
231 
232         // TODO add more countries (for this we must know about DST and/or
233         //      holidays for this country)
234 
235         // Western European countries: we assume that they all follow the same
236         // DST rules (true or false?)
237         Country_WesternEurope_Start,
238         Country_EEC = Country_WesternEurope_Start,
239         France,
240         Germany,
241         UK,
242         Country_WesternEurope_End = UK,
243 
244         Russia,
245         USA
246     };
247         // symbolic names for the months
248     enum Month
249     {
250         Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec, Inv_Month
251     };
252 
253         // symbolic names for the weekdays
254     enum WeekDay
255     {
256         Sun, Mon, Tue, Wed, Thu, Fri, Sat, Inv_WeekDay
257     };
258 
259         // invalid value for the year
260     enum Year
261     {
262         Inv_Year = SHRT_MIN    // should hold in wxDateTime_t
263     };
264 
265         // flags for GetWeekDayName and GetMonthName
266     enum NameFlags
267     {
268         Name_Full = 0x01,       // return full name
269         Name_Abbr = 0x02        // return abbreviated name
270     };
271 
272         // flags for GetWeekOfYear and GetWeekOfMonth
273     enum WeekFlags
274     {
275         Default_First,   // Sunday_First for US, Monday_First for the rest
276         Monday_First,    // week starts with a Monday
277         Sunday_First     // week starts with a Sunday
278     };
279 
280     // Currently we assume that DST is always shifted by 1 hour, this seems to
281     // be always true in practice. If this ever needs to change, search for all
282     // places using DST_OFFSET and update them.
283     enum
284     {
285         DST_OFFSET = 3600
286     };
287 
288 
289     // helper classes
290     // ------------------------------------------------------------------------
291 
292         // a class representing a time zone: basically, this is just an offset
293         // (in seconds) from GMT
294     class WXDLLIMPEXP_BASE TimeZone
295     {
296     public:
297         TimeZone(TZ tz);
298 
299         // create time zone object with the given offset
300         TimeZone(long offset = 0) { m_offset = offset; }
301 
Make(long offset)302         static TimeZone Make(long offset)
303         {
304             TimeZone tz;
305             tz.m_offset = offset;
306             return tz;
307         }
308 
IsLocal()309         bool IsLocal() const { return m_offset == -1; }
310 
311         long GetOffset() const;
312 
313     private:
314         // offset for this timezone from GMT in seconds
315         long m_offset;
316     };
317 
318         // standard struct tm is limited to the years from 1900 (because
319         // tm_year field is the offset from 1900), so we use our own struct
320         // instead to represent broken down time
321         //
322         // NB: this struct should always be kept normalized (i.e. mon should
323         //     be < 12, 1 <= day <= 31 &c), so use AddMonths(), AddDays()
324         //     instead of modifying the member fields directly!
325     struct WXDLLIMPEXP_BASE Tm
326     {
327         wxDateTime_t msec, sec, min, hour,
328                      mday,  // Day of the month in 1..31 range.
329                      yday;  // Day of the year in 0..365 range.
330         Month mon;
331         int year;
332 
333         // default ctor inits the object to an invalid value
334         Tm();
335 
336         // ctor from struct tm and the timezone
337         Tm(const struct tm& tm, const TimeZone& tz);
338 
339         // check that the given date/time is valid (in Gregorian calendar)
340         bool IsValid() const;
341 
342         // get the week day
GetWeekDayTm343         WeekDay GetWeekDay() // not const because wday may be changed
344         {
345             if ( wday == Inv_WeekDay )
346                 ComputeWeekDay();
347 
348             return (WeekDay)wday;
349         }
350 
351         // add the given number of months to the date keeping it normalized
352         void AddMonths(int monDiff);
353 
354         // add the given number of months to the date keeping it normalized
355         void AddDays(int dayDiff);
356 
357     private:
358         // compute the weekday from other fields
359         void ComputeWeekDay();
360 
361         // the timezone we correspond to
362         TimeZone m_tz;
363 
364         // This value can only be accessed via GetWeekDay() and not directly
365         // because it's not always computed when creating this object and may
366         // need to be calculated on demand.
367         wxDateTime_t wday;
368     };
369 
370     // static methods
371     // ------------------------------------------------------------------------
372 
373         // set the current country
374     static void SetCountry(Country country);
375         // get the current country
376     static Country GetCountry();
377 
378         // return true if the country is a West European one (in practice,
379         // this means that the same DST rules as for EEC apply)
380     static bool IsWestEuropeanCountry(Country country = Country_Default);
381 
382         // return the current year
383     static int GetCurrentYear(Calendar cal = Gregorian);
384 
385         // convert the year as returned by wxDateTime::GetYear() to a year
386         // suitable for BC/AD notation. The difference is that BC year 1
387         // corresponds to the year 0 (while BC year 0 didn't exist) and AD
388         // year N is just year N.
389     static int ConvertYearToBC(int year);
390 
391         // return the current month
392     static Month GetCurrentMonth(Calendar cal = Gregorian);
393 
394         // returns true if the given year is a leap year in the given calendar
395     static bool IsLeapYear(int year = Inv_Year, Calendar cal = Gregorian);
396 
397         // acquires the first day of week based on locale and/or OS settings
398     static bool GetFirstWeekDay(WeekDay *firstDay);
399 
400         // get the century (19 for 1999, 20 for 2000 and -5 for 492 BC)
401     static int GetCentury(int year);
402 
403         // returns the number of days in this year (356 or 355 for Gregorian
404         // calendar usually :-)
405     static wxDateTime_t GetNumberOfDays(int year, Calendar cal = Gregorian);
406 
407         // get the number of the days in the given month (default value for
408         // the year means the current one)
409     static wxDateTime_t GetNumberOfDays(Month month,
410                                         int year = Inv_Year,
411                                         Calendar cal = Gregorian);
412 
413 
414         // get the full (default) or abbreviated month name in the current
415         // locale, returns empty string on error
416     static wxString GetMonthName(Month month,
417                                  NameFlags flags = Name_Full);
418 
419         // get the standard English full (default) or abbreviated month name
420     static wxString GetEnglishMonthName(Month month,
421                                         NameFlags flags = Name_Full);
422 
423         // get the full (default) or abbreviated weekday name in the current
424         // locale, returns empty string on error
425     static wxString GetWeekDayName(WeekDay weekday,
426                                    NameFlags flags = Name_Full);
427 
428         // get the standard English full (default) or abbreviated weekday name
429     static wxString GetEnglishWeekDayName(WeekDay weekday,
430                                           NameFlags flags = Name_Full);
431 
432         // get the AM and PM strings in the current locale (may be empty)
433     static void GetAmPmStrings(wxString *am, wxString *pm);
434 
435         // return true if the given country uses DST for this year
436     static bool IsDSTApplicable(int year = Inv_Year,
437                                 Country country = Country_Default);
438 
439         // get the beginning of DST for this year, will return invalid object
440         // if no DST applicable in this year. The default value of the
441         // parameter means to take the current year.
442     static wxDateTime GetBeginDST(int year = Inv_Year,
443                                   Country country = Country_Default);
444         // get the end of DST for this year, will return invalid object
445         // if no DST applicable in this year. The default value of the
446         // parameter means to take the current year.
447     static wxDateTime GetEndDST(int year = Inv_Year,
448                                 Country country = Country_Default);
449 
450         // return the wxDateTime object for the current time
451     static inline wxDateTime Now();
452 
453         // return the wxDateTime object for the current time with millisecond
454         // precision (if available on this platform)
455     static wxDateTime UNow();
456 
457         // return the wxDateTime object for today midnight: i.e. as Now() but
458         // with time set to 0
459     static inline wxDateTime Today();
460 
461     // constructors: you should test whether the constructor succeeded with
462     // IsValid() function. The values Inv_Month and Inv_Year for the
463     // parameters mean take current month and/or year values.
464     // ------------------------------------------------------------------------
465 
466         // default ctor does not initialize the object, use Set()!
wxDateTime()467     wxDateTime() : m_time(wxINT64_MIN) { }
468 
469         // from time_t: seconds since the Epoch 00:00:00 UTC, Jan 1, 1970)
470     inline wxDateTime(time_t timet);
471         // from broken down time/date (only for standard Unix range)
472     inline wxDateTime(const struct tm& tm);
473         // from broken down time/date (any range)
474     inline wxDateTime(const Tm& tm);
475 
476         // from JDN (beware of rounding errors)
477     inline wxDateTime(double jdn);
478 
479         // from separate values for each component, date set to today
480     inline wxDateTime(wxDateTime_t hour,
481                       wxDateTime_t minute = 0,
482                       wxDateTime_t second = 0,
483                       wxDateTime_t millisec = 0);
484         // from separate values for each component with explicit date
485     inline wxDateTime(wxDateTime_t day,             // day of the month
486                       Month        month,
487                       int          year = Inv_Year, // 1999, not 99 please!
488                       wxDateTime_t hour = 0,
489                       wxDateTime_t minute = 0,
490                       wxDateTime_t second = 0,
491                       wxDateTime_t millisec = 0);
492 #ifdef __WINDOWS__
wxDateTime(const struct _SYSTEMTIME & st)493     wxDateTime(const struct _SYSTEMTIME& st)
494     {
495         SetFromMSWSysTime(st);
496     }
497 #endif
498 
499         // default copy ctor ok
500 
501         // no dtor
502 
503     // assignment operators and Set() functions: all non const methods return
504     // the reference to this object. IsValid() should be used to test whether
505     // the function succeeded.
506     // ------------------------------------------------------------------------
507 
508         // set to the current time
509     inline wxDateTime& SetToCurrent();
510 
511         // set to given time_t value
512     inline wxDateTime& Set(time_t timet);
513 
514         // set to given broken down time/date
515     wxDateTime& Set(const struct tm& tm);
516 
517         // set to given broken down time/date
518     inline wxDateTime& Set(const Tm& tm);
519 
520         // set to given JDN (beware of rounding errors)
521     wxDateTime& Set(double jdn);
522 
523         // set to given time, date = today
524     wxDateTime& Set(wxDateTime_t hour,
525                     wxDateTime_t minute = 0,
526                     wxDateTime_t second = 0,
527                     wxDateTime_t millisec = 0);
528 
529         // from separate values for each component with explicit date
530         // (defaults for month and year are the current values)
531     wxDateTime& Set(wxDateTime_t day,
532                     Month        month,
533                     int          year = Inv_Year, // 1999, not 99 please!
534                     wxDateTime_t hour = 0,
535                     wxDateTime_t minute = 0,
536                     wxDateTime_t second = 0,
537                     wxDateTime_t millisec = 0);
538 
539         // resets time to 00:00:00, doesn't change the date
540     wxDateTime& ResetTime();
541 
542         // get the date part of this object only, i.e. the object which has the
543         // same date as this one but time of 00:00:00
544     wxDateTime GetDateOnly() const;
545 
546         // the following functions don't change the values of the other
547         // fields, i.e. SetMinute() won't change either hour or seconds value
548 
549         // set the year
550     wxDateTime& SetYear(int year);
551         // set the month
552     wxDateTime& SetMonth(Month month);
553         // set the day of the month
554     wxDateTime& SetDay(wxDateTime_t day);
555         // set hour
556     wxDateTime& SetHour(wxDateTime_t hour);
557         // set minute
558     wxDateTime& SetMinute(wxDateTime_t minute);
559         // set second
560     wxDateTime& SetSecond(wxDateTime_t second);
561         // set millisecond
562     wxDateTime& SetMillisecond(wxDateTime_t millisecond);
563 
564         // assignment operator from time_t
565     wxDateTime& operator=(time_t timet) { return Set(timet); }
566 
567         // assignment operator from broken down time/date
568     wxDateTime& operator=(const struct tm& tm) { return Set(tm); }
569 
570         // assignment operator from broken down time/date
571     wxDateTime& operator=(const Tm& tm) { return Set(tm); }
572 
573         // default assignment operator is ok
574 
575     // calendar calculations (functions which set the date only leave the time
576     // unchanged, e.g. don't explicitly zero it): SetXXX() functions modify the
577     // object itself, GetXXX() ones return a new object.
578     // ------------------------------------------------------------------------
579 
580         // set to the given week day in the same week as this one
581     wxDateTime& SetToWeekDayInSameWeek(WeekDay weekday,
582                                        WeekFlags flags = Monday_First);
583     inline wxDateTime GetWeekDayInSameWeek(WeekDay weekday,
584                                            WeekFlags flags = Monday_First) const;
585 
586         // set to the next week day following this one
587     wxDateTime& SetToNextWeekDay(WeekDay weekday);
588     inline wxDateTime GetNextWeekDay(WeekDay weekday) const;
589 
590         // set to the previous week day before this one
591     wxDateTime& SetToPrevWeekDay(WeekDay weekday);
592     inline wxDateTime GetPrevWeekDay(WeekDay weekday) const;
593 
594         // set to Nth occurrence of given weekday in the given month of the
595         // given year (time is set to 0), return true on success and false on
596         // failure. n may be positive (1..5) or negative to count from the end
597         // of the month (see helper function SetToLastWeekDay())
598     bool SetToWeekDay(WeekDay weekday,
599                       int n = 1,
600                       Month month = Inv_Month,
601                       int year = Inv_Year);
602     inline wxDateTime GetWeekDay(WeekDay weekday,
603                                  int n = 1,
604                                  Month month = Inv_Month,
605                                  int year = Inv_Year) const;
606 
607         // sets to the last weekday in the given month, year
608     inline bool SetToLastWeekDay(WeekDay weekday,
609                                  Month month = Inv_Month,
610                                  int year = Inv_Year);
611     inline wxDateTime GetLastWeekDay(WeekDay weekday,
612                                      Month month = Inv_Month,
613                                      int year = Inv_Year);
614 
615         // returns the date corresponding to the given week day of the given
616         // week (in ISO notation) of the specified year
617     static wxDateTime SetToWeekOfYear(int year,
618                                       wxDateTime_t numWeek,
619                                       WeekDay weekday = Mon);
620 
621         // sets the date to the last day of the given (or current) month or the
622         // given (or current) year
623     wxDateTime& SetToLastMonthDay(Month month = Inv_Month,
624                                   int year = Inv_Year);
625     inline wxDateTime GetLastMonthDay(Month month = Inv_Month,
626                                       int year = Inv_Year) const;
627 
628         // sets to the given year day (1..365 or 366)
629     wxDateTime& SetToYearDay(wxDateTime_t yday);
630     inline wxDateTime GetYearDay(wxDateTime_t yday) const;
631 
632         // The definitions below were taken verbatim from
633         //
634         //      http://www.capecod.net/~pbaum/date/date0.htm
635         //
636         // (Peter Baum's home page)
637         //
638         // definition: The Julian Day Number, Julian Day, or JD of a
639         // particular instant of time is the number of days and fractions of a
640         // day since 12 hours Universal Time (Greenwich mean noon) on January
641         // 1 of the year -4712, where the year is given in the Julian
642         // proleptic calendar. The idea of using this reference date was
643         // originally proposed by Joseph Scalizer in 1582 to count years but
644         // it was modified by 19th century astronomers to count days. One
645         // could have equivalently defined the reference time to be noon of
646         // November 24, -4713 if were understood that Gregorian calendar rules
647         // were applied. Julian days are Julian Day Numbers and are not to be
648         // confused with Julian dates.
649         //
650         // definition: The Rata Die number is a date specified as the number
651         // of days relative to a base date of December 31 of the year 0. Thus
652         // January 1 of the year 1 is Rata Die day 1.
653 
654         // get the Julian Day number (the fractional part specifies the time of
655         // the day, related to noon - beware of rounding errors!)
656     double GetJulianDayNumber() const;
GetJDN()657     double GetJDN() const { return GetJulianDayNumber(); }
658 
659         // get the Modified Julian Day number: it is equal to JDN - 2400000.5
660         // and so integral MJDs correspond to the midnights (and not noons).
661         // MJD 0 is Nov 17, 1858
GetModifiedJulianDayNumber()662     double GetModifiedJulianDayNumber() const { return GetJDN() - 2400000.5; }
GetMJD()663     double GetMJD() const { return GetModifiedJulianDayNumber(); }
664 
665         // get the Rata Die number
666     double GetRataDie() const;
667 
668         // TODO algorithms for calculating some important dates, such as
669         //      religious holidays (Easter...) or moon/solar eclipses? Some
670         //      algorithms can be found in the calendar FAQ
671 
672 
673     // Timezone stuff: a wxDateTime object constructed using given
674     // day/month/year/hour/min/sec values is interpreted as this moment in
675     // local time. Using the functions below, it may be converted to another
676     // time zone (e.g., the Unix epoch is wxDateTime(1, Jan, 1970).ToGMT()).
677     //
678     // These functions try to handle DST internally, but there is no magical
679     // way to know all rules for it in all countries in the world, so if the
680     // program can handle it itself (or doesn't want to handle it at all for
681     // whatever reason), the DST handling can be disabled with noDST.
682     // ------------------------------------------------------------------------
683 
684         // transform to any given timezone
685     inline wxDateTime ToTimezone(const TimeZone& tz, bool noDST = false) const;
686     wxDateTime& MakeTimezone(const TimeZone& tz, bool noDST = false);
687 
688         // interpret current value as being in another timezone and transform
689         // it to local one
690     inline wxDateTime FromTimezone(const TimeZone& tz, bool noDST = false) const;
691     wxDateTime& MakeFromTimezone(const TimeZone& tz, bool noDST = false);
692 
693         // transform to/from GMT/UTC
694     wxDateTime ToUTC(bool noDST = false) const { return ToTimezone(UTC, noDST); }
695     wxDateTime& MakeUTC(bool noDST = false) { return MakeTimezone(UTC, noDST); }
696 
697     wxDateTime ToGMT(bool noDST = false) const { return ToUTC(noDST); }
698     wxDateTime& MakeGMT(bool noDST = false) { return MakeUTC(noDST); }
699 
700     wxDateTime FromUTC(bool noDST = false) const
701         { return FromTimezone(UTC, noDST); }
702     wxDateTime& MakeFromUTC(bool noDST = false)
703         { return MakeFromTimezone(UTC, noDST); }
704 
705         // is daylight savings time in effect at this moment according to the
706         // rules of the specified country?
707         //
708         // Return value is > 0 if DST is in effect, 0 if it is not and -1 if
709         // the information is not available (this is compatible with ANSI C)
710     int IsDST(Country country = Country_Default) const;
711 
712 
713     // accessors: many of them take the timezone parameter which indicates the
714     // timezone for which to make the calculations and the default value means
715     // to do it for the current timezone of this machine (even if the function
716     // only operates with the date it's necessary because a date may wrap as
717     // result of timezone shift)
718     // ------------------------------------------------------------------------
719 
720         // is the date valid?
IsValid()721     inline bool IsValid() const { return m_time != wxLongLong(wxINT64_MIN); }
722 
723         // get the broken down date/time representation in the given timezone
724         //
725         // If you wish to get several time components (day, month and year),
726         // consider getting the whole Tm structure first and retrieving the
727         // value from it - this is much more efficient
728     Tm GetTm(const TimeZone& tz = Local) const;
729 
730         // get the number of seconds since the Unix epoch - returns (time_t)-1
731         // if the value is out of range
732     inline time_t GetTicks() const;
733 
734         // get the century, same as GetCentury(GetYear())
735     int GetCentury(const TimeZone& tz = Local) const
736             { return GetCentury(GetYear(tz)); }
737         // get the year (returns Inv_Year if date is invalid)
738     int GetYear(const TimeZone& tz = Local) const
739             { return GetTm(tz).year; }
740         // get the month (Inv_Month if date is invalid)
741     Month GetMonth(const TimeZone& tz = Local) const
742             { return (Month)GetTm(tz).mon; }
743         // get the month day (in 1..31 range, 0 if date is invalid)
744     wxDateTime_t GetDay(const TimeZone& tz = Local) const
745             { return GetTm(tz).mday; }
746         // get the day of the week (Inv_WeekDay if date is invalid)
747     WeekDay GetWeekDay(const TimeZone& tz = Local) const
748             { return GetTm(tz).GetWeekDay(); }
749         // get the hour of the day
750     wxDateTime_t GetHour(const TimeZone& tz = Local) const
751             { return GetTm(tz).hour; }
752         // get the minute
753     wxDateTime_t GetMinute(const TimeZone& tz = Local) const
754             { return GetTm(tz).min; }
755         // get the second
756     wxDateTime_t GetSecond(const TimeZone& tz = Local) const
757             { return GetTm(tz).sec; }
758         // get milliseconds
759     wxDateTime_t GetMillisecond(const TimeZone& tz = Local) const
760             { return GetTm(tz).msec; }
761 
762         // get the day since the year start (1..366, 0 if date is invalid)
763     wxDateTime_t GetDayOfYear(const TimeZone& tz = Local) const;
764         // get the week number since the year start (1..52 or 53, 0 if date is
765         // invalid)
766     wxDateTime_t GetWeekOfYear(WeekFlags flags = Monday_First,
767                                const TimeZone& tz = Local) const;
768         // get the year to which the number returned from GetWeekOfYear()
769         // belongs
770     int GetWeekBasedYear(const TimeZone& tz = Local) const;
771         // get the week number since the month start (1..5, 0 if date is
772         // invalid)
773     wxDateTime_t GetWeekOfMonth(WeekFlags flags = Monday_First,
774                                 const TimeZone& tz = Local) const;
775 
776         // is this date a work day? This depends on a country, of course,
777         // because the holidays are different in different countries
778     bool IsWorkDay(Country country = Country_Default) const;
779 
780     // dos date and time format
781     // ------------------------------------------------------------------------
782 
783         // set from the DOS packed format
784     wxDateTime& SetFromDOS(unsigned long ddt);
785 
786         // pack the date in DOS format
787     unsigned long GetAsDOS() const;
788 
789     // SYSTEMTIME format
790     // ------------------------------------------------------------------------
791 #ifdef __WINDOWS__
792     // convert SYSTEMTIME to wxDateTime
793     wxDateTime& SetFromMSWSysTime(const struct _SYSTEMTIME& st);
794 
795     // convert wxDateTime to SYSTEMTIME
796     void GetAsMSWSysTime(struct _SYSTEMTIME* st) const;
797 
798     // same as above but only take date part into account, time is always zero
799     wxDateTime& SetFromMSWSysDate(const struct _SYSTEMTIME& st);
800     void GetAsMSWSysDate(struct _SYSTEMTIME* st) const;
801 #endif // __WINDOWS__
802 
803     // comparison (see also functions below for operator versions)
804     // ------------------------------------------------------------------------
805 
806         // returns true if the two moments are strictly identical
807     inline bool IsEqualTo(const wxDateTime& datetime) const;
808 
809         // returns true if the date is strictly earlier than the given one
810     inline bool IsEarlierThan(const wxDateTime& datetime) const;
811 
812         // returns true if the date is strictly later than the given one
813     inline bool IsLaterThan(const wxDateTime& datetime) const;
814 
815         // returns true if the date is strictly in the given range
816     inline bool IsStrictlyBetween(const wxDateTime& t1,
817                                   const wxDateTime& t2) const;
818 
819         // returns true if the date is in the given range
820     inline bool IsBetween(const wxDateTime& t1, const wxDateTime& t2) const;
821 
822         // do these two objects refer to the same date?
823     inline bool IsSameDate(const wxDateTime& dt) const;
824 
825         // do these two objects have the same time?
826     inline bool IsSameTime(const wxDateTime& dt) const;
827 
828         // are these two objects equal up to given timespan?
829     inline bool IsEqualUpTo(const wxDateTime& dt, const wxTimeSpan& ts) const;
830 
831     inline bool operator<(const wxDateTime& dt) const
832     {
833         return GetValue() < dt.GetValue();
834     }
835 
836     inline bool operator<=(const wxDateTime& dt) const
837     {
838         return GetValue() <= dt.GetValue();
839     }
840 
841     inline bool operator>(const wxDateTime& dt) const
842     {
843         return GetValue() > dt.GetValue();
844     }
845 
846     inline bool operator>=(const wxDateTime& dt) const
847     {
848         return GetValue() >= dt.GetValue();
849     }
850 
851     inline bool operator==(const wxDateTime& dt) const
852     {
853         // Intentionally do not call GetValue() here, in order that
854         // invalid wxDateTimes may be compared for equality
855         return m_time == dt.m_time;
856     }
857 
858     inline bool operator!=(const wxDateTime& dt) const
859     {
860         // As above, don't use GetValue() here.
861         return m_time != dt.m_time;
862     }
863 
864     // arithmetic with dates (see also below for more operators)
865     // ------------------------------------------------------------------------
866 
867         // return the sum of the date with a time span (positive or negative)
868     inline wxDateTime Add(const wxTimeSpan& diff) const;
869         // add a time span (positive or negative)
870     inline wxDateTime& Add(const wxTimeSpan& diff);
871         // add a time span (positive or negative)
872     inline wxDateTime& operator+=(const wxTimeSpan& diff);
873     inline wxDateTime operator+(const wxTimeSpan& ts) const
874     {
875         wxDateTime dt(*this);
876         dt.Add(ts);
877         return dt;
878     }
879 
880         // return the difference of the date with a time span
881     inline wxDateTime Subtract(const wxTimeSpan& diff) const;
882         // subtract a time span (positive or negative)
883     inline wxDateTime& Subtract(const wxTimeSpan& diff);
884         // subtract a time span (positive or negative)
885     inline wxDateTime& operator-=(const wxTimeSpan& diff);
886     inline wxDateTime operator-(const wxTimeSpan& ts) const
887     {
888         wxDateTime dt(*this);
889         dt.Subtract(ts);
890         return dt;
891     }
892 
893         // return the sum of the date with a date span
894     inline wxDateTime Add(const wxDateSpan& diff) const;
895         // add a date span (positive or negative)
896     wxDateTime& Add(const wxDateSpan& diff);
897         // add a date span (positive or negative)
898     inline wxDateTime& operator+=(const wxDateSpan& diff);
899     inline wxDateTime operator+(const wxDateSpan& ds) const
900     {
901         wxDateTime dt(*this);
902         dt.Add(ds);
903         return dt;
904     }
905 
906         // return the difference of the date with a date span
907     inline wxDateTime Subtract(const wxDateSpan& diff) const;
908         // subtract a date span (positive or negative)
909     inline wxDateTime& Subtract(const wxDateSpan& diff);
910         // subtract a date span (positive or negative)
911     inline wxDateTime& operator-=(const wxDateSpan& diff);
912     inline wxDateTime operator-(const wxDateSpan& ds) const
913     {
914         wxDateTime dt(*this);
915         dt.Subtract(ds);
916         return dt;
917     }
918 
919         // return the difference between two dates
920     inline wxTimeSpan Subtract(const wxDateTime& dt) const;
921     inline wxTimeSpan operator-(const wxDateTime& dt2) const;
922 
923     wxDateSpan DiffAsDateSpan(const wxDateTime& dt) const;
924 
925     // conversion to/from text
926     // ------------------------------------------------------------------------
927 
928     // all conversions functions return true to indicate whether parsing
929     // succeeded or failed and fill in the provided end iterator, which must
930     // not be NULL, with the location of the character where the parsing
931     // stopped (this will be end() of the passed string if everything was
932     // parsed)
933 
934         // parse a string in RFC 822 format (found e.g. in mail headers and
935         // having the form "Wed, 10 Feb 1999 19:07:07 +0100")
936     bool ParseRfc822Date(const wxString& date,
937                          wxString::const_iterator *end);
938 
939         // parse a date/time in the given format (see strptime(3)), fill in
940         // the missing (in the string) fields with the values of dateDef (by
941         // default, they will not change if they had valid values or will
942         // default to Today() otherwise)
943     bool ParseFormat(const wxString& date,
944                      const wxString& format,
945                      const wxDateTime& dateDef,
946                      wxString::const_iterator *end);
947 
ParseFormat(const wxString & date,const wxString & format,wxString::const_iterator * end)948     bool ParseFormat(const wxString& date,
949                      const wxString& format,
950                      wxString::const_iterator *end)
951     {
952         return ParseFormat(date, format, wxDefaultDateTime, end);
953     }
954 
ParseFormat(const wxString & date,wxString::const_iterator * end)955     bool ParseFormat(const wxString& date,
956                      wxString::const_iterator *end)
957     {
958         return ParseFormat(date, wxASCII_STR(wxDefaultDateTimeFormat), wxDefaultDateTime, end);
959     }
960 
961         // parse a string containing date, time or both in ISO 8601 format
962         //
963         // notice that these functions are new in wx 3.0 and so we don't
964         // provide compatibility overloads for them
ParseISODate(const wxString & date)965     bool ParseISODate(const wxString& date)
966     {
967         wxString::const_iterator end;
968         return ParseFormat(date, wxS("%Y-%m-%d"), &end) && end == date.end();
969     }
970 
ParseISOTime(const wxString & time)971     bool ParseISOTime(const wxString& time)
972     {
973         wxString::const_iterator end;
974         return ParseFormat(time, wxS("%H:%M:%S"), &end) && end == time.end();
975     }
976 
977     bool ParseISOCombined(const wxString& datetime, char sep = 'T')
978     {
979         wxString::const_iterator end;
980         const wxString fmt = wxS("%Y-%m-%d") + wxString(sep) + wxS("%H:%M:%S");
981         return ParseFormat(datetime, fmt, &end) && end == datetime.end();
982     }
983 
984         // parse a string containing the date/time in "free" format, this
985         // function will try to make an educated guess at the string contents
986     bool ParseDateTime(const wxString& datetime,
987                        wxString::const_iterator *end);
988 
989         // parse a string containing the date only in "free" format (less
990         // flexible than ParseDateTime)
991     bool ParseDate(const wxString& date,
992                    wxString::const_iterator *end);
993 
994         // parse a string containing the time only in "free" format
995     bool ParseTime(const wxString& time,
996                    wxString::const_iterator *end);
997 
998 
999         // this function accepts strftime()-like format string (default
1000         // argument corresponds to the preferred date and time representation
1001         // for the current locale) and returns the string containing the
1002         // resulting text representation
1003     wxString Format(const wxString& format = wxASCII_STR(wxDefaultDateTimeFormat),
1004                     const TimeZone& tz = Local) const;
1005         // preferred date representation for the current locale
FormatDate()1006     wxString FormatDate() const { return Format(wxS("%x")); }
1007         // preferred time representation for the current locale
FormatTime()1008     wxString FormatTime() const { return Format(wxS("%X")); }
1009         // returns the string representing the date in ISO 8601 format
1010         // (YYYY-MM-DD)
FormatISODate()1011     wxString FormatISODate() const { return Format(wxS("%Y-%m-%d")); }
1012         // returns the string representing the time in ISO 8601 format
1013         // (HH:MM:SS)
FormatISOTime()1014     wxString FormatISOTime() const { return Format(wxS("%H:%M:%S")); }
1015         // return the combined date time representation in ISO 8601 format; the
1016         // separator character should be 'T' according to the standard but it
1017         // can also be useful to set it to ' '
1018     wxString FormatISOCombined(char sep = 'T') const
1019         { return FormatISODate() + sep + FormatISOTime(); }
1020 
1021 
1022     // backwards compatible versions of the parsing functions: they return an
1023     // object representing the next character following the date specification
1024     // (i.e. the one where the scan had to stop) or a special NULL-like object
1025     // on failure
1026     //
1027     // they're not deprecated because a lot of existing code uses them and
1028     // there is no particular harm in keeping them but you should still prefer
1029     // the versions above in the new code
ParseRfc822Date(const wxString & date)1030     wxAnyStrPtr ParseRfc822Date(const wxString& date)
1031     {
1032         wxString::const_iterator end;
1033         return ParseRfc822Date(date, &end) ? wxAnyStrPtr(date, end)
1034                                            : wxAnyStrPtr();
1035     }
1036 
1037     wxAnyStrPtr ParseFormat(const wxString& date,
1038                             const wxString& format = wxASCII_STR(wxDefaultDateTimeFormat),
1039                             const wxDateTime& dateDef = wxDefaultDateTime)
1040     {
1041         wxString::const_iterator end;
1042         return ParseFormat(date, format, dateDef, &end) ? wxAnyStrPtr(date, end)
1043                                                         : wxAnyStrPtr();
1044     }
1045 
ParseDateTime(const wxString & datetime)1046     wxAnyStrPtr ParseDateTime(const wxString& datetime)
1047     {
1048         wxString::const_iterator end;
1049         return ParseDateTime(datetime, &end) ? wxAnyStrPtr(datetime, end)
1050                                              : wxAnyStrPtr();
1051     }
1052 
ParseDate(const wxString & date)1053     wxAnyStrPtr ParseDate(const wxString& date)
1054     {
1055         wxString::const_iterator end;
1056         return ParseDate(date, &end) ? wxAnyStrPtr(date, end)
1057                                      : wxAnyStrPtr();
1058     }
1059 
ParseTime(const wxString & time)1060     wxAnyStrPtr ParseTime(const wxString& time)
1061     {
1062         wxString::const_iterator end;
1063         return ParseTime(time, &end) ? wxAnyStrPtr(time, end)
1064                                      : wxAnyStrPtr();
1065     }
1066 
1067     // In addition to wxAnyStrPtr versions above we also must provide the
1068     // overloads for C strings as we must return a pointer into the original
1069     // string and not inside a temporary wxString which would have been created
1070     // if the overloads above were used.
1071     //
1072     // And then we also have to provide the overloads for wxCStrData, as usual.
1073     // Unfortunately those ones can't return anything as we don't have any
1074     // sufficiently long-lived wxAnyStrPtr to return from them: any temporary
1075     // strings it would point to would be destroyed when this function returns
1076     // making it impossible to dereference the return value. So we just don't
1077     // return anything from here which at least allows to keep compatibility
1078     // with the code not testing the return value. Other uses of this method
1079     // need to be converted to use one of the new bool-returning overloads
1080     // above.
ParseRfc822Date(const wxCStrData & date)1081     void ParseRfc822Date(const wxCStrData& date)
1082         { ParseRfc822Date(wxString(date)); }
1083     const char* ParseRfc822Date(const char* date);
1084     const wchar_t* ParseRfc822Date(const wchar_t* date);
1085 
1086     void ParseFormat(const wxCStrData& date,
1087                      const wxString& format = wxASCII_STR(wxDefaultDateTimeFormat),
1088                      const wxDateTime& dateDef = wxDefaultDateTime)
1089         { ParseFormat(wxString(date), format, dateDef); }
1090     const char* ParseFormat(const char* date,
1091                             const wxString& format = wxASCII_STR(wxDefaultDateTimeFormat),
1092                             const wxDateTime& dateDef = wxDefaultDateTime);
1093     const wchar_t* ParseFormat(const wchar_t* date,
1094                                const wxString& format = wxASCII_STR(wxDefaultDateTimeFormat),
1095                                const wxDateTime& dateDef = wxDefaultDateTime);
1096 
ParseDateTime(const wxCStrData & datetime)1097     void ParseDateTime(const wxCStrData& datetime)
1098         { ParseDateTime(wxString(datetime)); }
1099     const char* ParseDateTime(const char* datetime);
1100     const wchar_t* ParseDateTime(const wchar_t* datetime);
1101 
ParseDate(const wxCStrData & date)1102     void ParseDate(const wxCStrData& date)
1103         { ParseDate(wxString(date)); }
1104     const char* ParseDate(const char* date);
1105     const wchar_t* ParseDate(const wchar_t* date);
1106 
ParseTime(const wxCStrData & time)1107     void ParseTime(const wxCStrData& time)
1108         { ParseTime(wxString(time)); }
1109     const char* ParseTime(const char* time);
1110     const wchar_t* ParseTime(const wchar_t* time);
1111 
1112 
1113     // implementation
1114     // ------------------------------------------------------------------------
1115 
1116         // construct from internal representation
wxDateTime(const wxLongLong & time)1117     wxDateTime(const wxLongLong& time) : m_time(time) { }
1118 
1119         // get the internal representation
1120     inline wxLongLong GetValue() const;
1121 
1122     // a helper function to get the current time_t
GetTimeNow()1123     static time_t GetTimeNow() { return time(NULL); }
1124 
1125     // another one to get the current time broken down
GetTmNow()1126     static struct tm *GetTmNow()
1127     {
1128         static struct tm l_CurrentTime;
1129         return GetTmNow(&l_CurrentTime);
1130     }
1131 
1132     // get current time using thread-safe function
1133     static struct tm *GetTmNow(struct tm *tmstruct);
1134 
1135 private:
1136     // the current country - as it's the same for all program objects (unless
1137     // it runs on a _really_ big cluster system :-), this is a static member:
1138     // see SetCountry() and GetCountry()
1139     static Country ms_country;
1140 
1141     // this constant is used to transform a time_t value to the internal
1142     // representation, as time_t is in seconds and we use milliseconds it's
1143     // fixed to 1000
1144     static const long TIME_T_FACTOR;
1145 
1146     // returns true if we fall in range in which we can use standard ANSI C
1147     // functions
1148     inline bool IsInStdRange() const;
1149 
1150     // assign the preferred first day of a week to flags, if necessary
1151     void UseEffectiveWeekDayFlags(WeekFlags &flags) const;
1152 
1153     // the internal representation of the time is the amount of milliseconds
1154     // elapsed since the origin which is set by convention to the UNIX/C epoch
1155     // value: the midnight of January 1, 1970 (UTC)
1156     wxLongLong m_time;
1157 };
1158 
1159 // ----------------------------------------------------------------------------
1160 // This class contains a difference between 2 wxDateTime values, so it makes
1161 // sense to add it to wxDateTime and it is the result of subtraction of 2
1162 // objects of that class. See also wxDateSpan.
1163 // ----------------------------------------------------------------------------
1164 
1165 class WXDLLIMPEXP_BASE wxTimeSpan
1166 {
1167 public:
1168     // constructors
1169     // ------------------------------------------------------------------------
1170 
1171         // return the timespan for the given number of milliseconds
Milliseconds(wxLongLong ms)1172     static wxTimeSpan Milliseconds(wxLongLong ms) { return wxTimeSpan(0, 0, 0, ms); }
Millisecond()1173     static wxTimeSpan Millisecond() { return Milliseconds(1); }
1174 
1175         // return the timespan for the given number of seconds
Seconds(wxLongLong sec)1176     static wxTimeSpan Seconds(wxLongLong sec) { return wxTimeSpan(0, 0, sec); }
Second()1177     static wxTimeSpan Second() { return Seconds(1); }
1178 
1179         // return the timespan for the given number of minutes
Minutes(long min)1180     static wxTimeSpan Minutes(long min) { return wxTimeSpan(0, min, 0 ); }
Minute()1181     static wxTimeSpan Minute() { return Minutes(1); }
1182 
1183         // return the timespan for the given number of hours
Hours(long hours)1184     static wxTimeSpan Hours(long hours) { return wxTimeSpan(hours, 0, 0); }
Hour()1185     static wxTimeSpan Hour() { return Hours(1); }
1186 
1187         // return the timespan for the given number of days
Days(long days)1188     static wxTimeSpan Days(long days) { return Hours(24 * days); }
Day()1189     static wxTimeSpan Day() { return Days(1); }
1190 
1191         // return the timespan for the given number of weeks
Weeks(long days)1192     static wxTimeSpan Weeks(long days) { return Days(7 * days); }
Week()1193     static wxTimeSpan Week() { return Weeks(1); }
1194 
1195         // default ctor constructs the 0 time span
wxTimeSpan()1196     wxTimeSpan() { }
1197 
1198         // from separate values for each component, date set to 0 (hours are
1199         // not restricted to 0..24 range, neither are minutes, seconds or
1200         // milliseconds)
1201     inline wxTimeSpan(long hours,
1202                       long minutes = 0,
1203                       wxLongLong seconds = 0,
1204                       wxLongLong milliseconds = 0);
1205 
1206         // default copy ctor is ok
1207 
1208         // no dtor
1209 
1210     // arithmetic with time spans (see also below for more operators)
1211     // ------------------------------------------------------------------------
1212 
1213         // return the sum of two timespans
1214     inline wxTimeSpan Add(const wxTimeSpan& diff) const;
1215         // add two timespans together
1216     inline wxTimeSpan& Add(const wxTimeSpan& diff);
1217         // add two timespans together
1218     wxTimeSpan& operator+=(const wxTimeSpan& diff) { return Add(diff); }
1219     inline wxTimeSpan operator+(const wxTimeSpan& ts) const
1220     {
1221         return wxTimeSpan(GetValue() + ts.GetValue());
1222     }
1223 
1224         // return the difference of two timespans
1225     inline wxTimeSpan Subtract(const wxTimeSpan& diff) const;
1226         // subtract another timespan
1227     inline wxTimeSpan& Subtract(const wxTimeSpan& diff);
1228         // subtract another timespan
1229     wxTimeSpan& operator-=(const wxTimeSpan& diff) { return Subtract(diff); }
1230     inline wxTimeSpan operator-(const wxTimeSpan& ts) const
1231     {
1232         return wxTimeSpan(GetValue() - ts.GetValue());
1233     }
1234 
1235         // multiply timespan by a scalar
1236     inline wxTimeSpan Multiply(int n) const;
1237         // multiply timespan by a scalar
1238     inline wxTimeSpan& Multiply(int n);
1239         // multiply timespan by a scalar
1240     wxTimeSpan& operator*=(int n) { return Multiply(n); }
1241     inline wxTimeSpan operator*(int n) const
1242     {
1243         return wxTimeSpan(*this).Multiply(n);
1244     }
1245 
1246         // return this timespan with opposite sign
Negate()1247     wxTimeSpan Negate() const { return wxTimeSpan(-GetValue()); }
1248         // negate the value of the timespan
Neg()1249     wxTimeSpan& Neg() { m_diff = -GetValue(); return *this; }
1250         // negate the value of the timespan
1251     wxTimeSpan& operator-() { return Neg(); }
1252 
1253         // return the absolute value of the timespan: does _not_ modify the
1254         // object
1255     inline wxTimeSpan Abs() const;
1256 
1257         // there is intentionally no division because we don't want to
1258         // introduce rounding errors in time calculations
1259 
1260     // comparison (see also operator versions below)
1261     // ------------------------------------------------------------------------
1262 
1263         // is the timespan null?
IsNull()1264     bool IsNull() const { return m_diff == 0l; }
1265         // returns true if the timespan is null
1266     bool operator!() const { return !IsNull(); }
1267 
1268         // is the timespan positive?
IsPositive()1269     bool IsPositive() const { return m_diff > 0l; }
1270 
1271         // is the timespan negative?
IsNegative()1272     bool IsNegative() const { return m_diff < 0l; }
1273 
1274         // are two timespans equal?
1275     inline bool IsEqualTo(const wxTimeSpan& ts) const;
1276         // compare two timestamps: works with the absolute values, i.e. -2
1277         // hours is longer than 1 hour. Also, it will return false if the
1278         // timespans are equal in absolute value.
1279     inline bool IsLongerThan(const wxTimeSpan& ts) const;
1280         // compare two timestamps: works with the absolute values, i.e. 1
1281         // hour is shorter than -2 hours. Also, it will return false if the
1282         // timespans are equal in absolute value.
1283     bool IsShorterThan(const wxTimeSpan& t) const;
1284 
1285     inline bool operator<(const wxTimeSpan &ts) const
1286     {
1287         return GetValue() < ts.GetValue();
1288     }
1289 
1290     inline bool operator<=(const wxTimeSpan &ts) const
1291     {
1292         return GetValue() <= ts.GetValue();
1293     }
1294 
1295     inline bool operator>(const wxTimeSpan &ts) const
1296     {
1297         return GetValue() > ts.GetValue();
1298     }
1299 
1300     inline bool operator>=(const wxTimeSpan &ts) const
1301     {
1302         return GetValue() >= ts.GetValue();
1303     }
1304 
1305     inline bool operator==(const wxTimeSpan &ts) const
1306     {
1307         return GetValue() == ts.GetValue();
1308     }
1309 
1310     inline bool operator!=(const wxTimeSpan &ts) const
1311     {
1312         return GetValue() != ts.GetValue();
1313     }
1314 
1315     // breaking into days, hours, minutes and seconds
1316     // ------------------------------------------------------------------------
1317 
1318         // get the max number of weeks in this timespan
1319     inline int GetWeeks() const;
1320         // get the max number of days in this timespan
1321     inline int GetDays() const;
1322         // get the max number of hours in this timespan
1323     inline int GetHours() const;
1324         // get the max number of minutes in this timespan
1325     inline int GetMinutes() const;
1326         // get the max number of seconds in this timespan
1327     inline wxLongLong GetSeconds() const;
1328         // get the number of milliseconds in this timespan
GetMilliseconds()1329     wxLongLong GetMilliseconds() const { return m_diff; }
1330 
1331     // conversion to text
1332     // ------------------------------------------------------------------------
1333 
1334         // this function accepts strftime()-like format string (default
1335         // argument corresponds to the preferred date and time representation
1336         // for the current locale) and returns the string containing the
1337         // resulting text representation. Notice that only some of format
1338         // specifiers valid for wxDateTime are valid for wxTimeSpan: hours,
1339         // minutes and seconds make sense, but not "PM/AM" string for example.
1340     wxString Format(const wxString& format = wxASCII_STR(wxDefaultTimeSpanFormat)) const;
1341 
1342     // implementation
1343     // ------------------------------------------------------------------------
1344 
1345         // construct from internal representation
wxTimeSpan(const wxLongLong & diff)1346     wxTimeSpan(const wxLongLong& diff) : m_diff(diff) { }
1347 
1348         // get the internal representation
GetValue()1349     wxLongLong GetValue() const { return m_diff; }
1350 
1351 private:
1352     // the (signed) time span in milliseconds
1353     wxLongLong m_diff;
1354 };
1355 
1356 // ----------------------------------------------------------------------------
1357 // This class is a "logical time span" and is useful for implementing program
1358 // logic for such things as "add one month to the date" which, in general,
1359 // doesn't mean to add 60*60*24*31 seconds to it, but to take the same date
1360 // the next month (to understand that this is indeed different consider adding
1361 // one month to Feb, 15 - we want to get Mar, 15, of course).
1362 //
1363 // When adding a month to the date, all lesser components (days, hours, ...)
1364 // won't be changed unless the resulting date would be invalid: for example,
1365 // Jan 31 + 1 month will be Feb 28, not (non existing) Feb 31.
1366 //
1367 // Because of this feature, adding and subtracting back again the same
1368 // wxDateSpan will *not*, in general give back the original date: Feb 28 - 1
1369 // month will be Jan 28, not Jan 31!
1370 //
1371 // wxDateSpan can be either positive or negative. They may be
1372 // multiplied by scalars which multiply all deltas by the scalar: i.e. 2*(1
1373 // month and 1 day) is 2 months and 2 days. They can be added together and
1374 // with wxDateTime or wxTimeSpan, but the type of result is different for each
1375 // case.
1376 //
1377 // Beware about weeks: if you specify both weeks and days, the total number of
1378 // days added will be 7*weeks + days! See also GetTotalDays() function.
1379 //
1380 // Equality operators are defined for wxDateSpans. Two datespans are equal if
1381 // they both give the same target date when added to *every* source date.
1382 // Thus wxDateSpan::Months(1) is not equal to wxDateSpan::Days(30), because
1383 // they not give the same date when added to 1 Feb. But wxDateSpan::Days(14) is
1384 // equal to wxDateSpan::Weeks(2)
1385 //
1386 // Finally, notice that for adding hours, minutes &c you don't need this
1387 // class: wxTimeSpan will do the job because there are no subtleties
1388 // associated with those.
1389 // ----------------------------------------------------------------------------
1390 
1391 class WXDLLIMPEXP_BASE wxDateSpan
1392 {
1393 public:
1394     // constructors
1395     // ------------------------------------------------------------------------
1396 
1397         // this many years/months/weeks/days
1398     wxDateSpan(int years = 0, int months = 0, int weeks = 0, int days = 0)
1399     {
1400         m_years = years;
1401         m_months = months;
1402         m_weeks = weeks;
1403         m_days = days;
1404     }
1405 
1406         // get an object for the given number of days
Days(int days)1407     static wxDateSpan Days(int days) { return wxDateSpan(0, 0, 0, days); }
Day()1408     static wxDateSpan Day() { return Days(1); }
1409 
1410         // get an object for the given number of weeks
Weeks(int weeks)1411     static wxDateSpan Weeks(int weeks) { return wxDateSpan(0, 0, weeks, 0); }
Week()1412     static wxDateSpan Week() { return Weeks(1); }
1413 
1414         // get an object for the given number of months
Months(int mon)1415     static wxDateSpan Months(int mon) { return wxDateSpan(0, mon, 0, 0); }
Month()1416     static wxDateSpan Month() { return Months(1); }
1417 
1418         // get an object for the given number of years
Years(int years)1419     static wxDateSpan Years(int years) { return wxDateSpan(years, 0, 0, 0); }
Year()1420     static wxDateSpan Year() { return Years(1); }
1421 
1422         // default copy ctor is ok
1423 
1424         // no dtor
1425 
1426     // accessors (all SetXXX() return the (modified) wxDateSpan object)
1427     // ------------------------------------------------------------------------
1428 
1429         // set number of years
SetYears(int n)1430     wxDateSpan& SetYears(int n) { m_years = n; return *this; }
1431         // set number of months
SetMonths(int n)1432     wxDateSpan& SetMonths(int n) { m_months = n; return *this; }
1433         // set number of weeks
SetWeeks(int n)1434     wxDateSpan& SetWeeks(int n) { m_weeks = n; return *this; }
1435         // set number of days
SetDays(int n)1436     wxDateSpan& SetDays(int n) { m_days = n; return *this; }
1437 
1438         // get number of years
GetYears()1439     int GetYears() const { return m_years; }
1440         // get number of months
GetMonths()1441     int GetMonths() const { return m_months; }
1442         // returns 12*GetYears() + GetMonths()
GetTotalMonths()1443     int GetTotalMonths() const { return 12*m_years + m_months; }
1444         // get number of weeks
GetWeeks()1445     int GetWeeks() const { return m_weeks; }
1446         // get number of days
GetDays()1447     int GetDays() const { return m_days; }
1448         // returns 7*GetWeeks() + GetDays()
GetTotalDays()1449     int GetTotalDays() const { return 7*m_weeks + m_days; }
1450 
1451     // arithmetic with date spans (see also below for more operators)
1452     // ------------------------------------------------------------------------
1453 
1454         // return sum of two date spans
1455     inline wxDateSpan Add(const wxDateSpan& other) const;
1456         // add another wxDateSpan to us
1457     inline wxDateSpan& Add(const wxDateSpan& other);
1458         // add another wxDateSpan to us
1459     inline wxDateSpan& operator+=(const wxDateSpan& other);
1460     inline wxDateSpan operator+(const wxDateSpan& ds) const
1461     {
1462         return wxDateSpan(GetYears() + ds.GetYears(),
1463                           GetMonths() + ds.GetMonths(),
1464                           GetWeeks() + ds.GetWeeks(),
1465                           GetDays() + ds.GetDays());
1466     }
1467 
1468         // return difference of two date spans
1469     inline wxDateSpan Subtract(const wxDateSpan& other) const;
1470         // subtract another wxDateSpan from us
1471     inline wxDateSpan& Subtract(const wxDateSpan& other);
1472         // subtract another wxDateSpan from us
1473     inline wxDateSpan& operator-=(const wxDateSpan& other);
1474     inline wxDateSpan operator-(const wxDateSpan& ds) const
1475     {
1476         return wxDateSpan(GetYears() - ds.GetYears(),
1477                           GetMonths() - ds.GetMonths(),
1478                           GetWeeks() - ds.GetWeeks(),
1479                           GetDays() - ds.GetDays());
1480     }
1481 
1482         // return a copy of this time span with changed sign
1483     inline wxDateSpan Negate() const;
1484         // inverse the sign of this timespan
1485     inline wxDateSpan& Neg();
1486         // inverse the sign of this timespan
1487     wxDateSpan& operator-() { return Neg(); }
1488 
1489         // return the date span proportional to this one with given factor
1490     inline wxDateSpan Multiply(int factor) const;
1491         // multiply all components by a (signed) number
1492     inline wxDateSpan& Multiply(int factor);
1493         // multiply all components by a (signed) number
1494     inline wxDateSpan& operator*=(int factor) { return Multiply(factor); }
1495     inline wxDateSpan operator*(int n) const
1496     {
1497         return wxDateSpan(*this).Multiply(n);
1498     }
1499 
1500     // ds1 == d2 if and only if for every wxDateTime t t + ds1 == t + ds2
1501     inline bool operator==(const wxDateSpan& ds) const
1502     {
1503         return GetYears() == ds.GetYears() &&
1504                GetMonths() == ds.GetMonths() &&
1505                GetTotalDays() == ds.GetTotalDays();
1506     }
1507 
1508     inline bool operator!=(const wxDateSpan& ds) const
1509     {
1510         return !(*this == ds);
1511     }
1512 
1513 private:
1514     int m_years,
1515         m_months,
1516         m_weeks,
1517         m_days;
1518 };
1519 
1520 // ----------------------------------------------------------------------------
1521 // wxDateTimeArray: array of dates.
1522 // ----------------------------------------------------------------------------
1523 
1524 WX_DECLARE_USER_EXPORTED_OBJARRAY(wxDateTime, wxDateTimeArray, WXDLLIMPEXP_BASE);
1525 
1526 // ----------------------------------------------------------------------------
1527 // wxDateTimeHolidayAuthority: an object of this class will decide whether a
1528 // given date is a holiday and is used by all functions working with "work
1529 // days".
1530 //
1531 // NB: the base class is an ABC, derived classes must implement the pure
1532 //     virtual methods to work with the holidays they correspond to.
1533 // ----------------------------------------------------------------------------
1534 
1535 class WXDLLIMPEXP_FWD_BASE wxDateTimeHolidayAuthority;
1536 WX_DEFINE_USER_EXPORTED_ARRAY_PTR(wxDateTimeHolidayAuthority *,
1537                               wxHolidayAuthoritiesArray,
1538                               class WXDLLIMPEXP_BASE);
1539 
1540 class wxDateTimeHolidaysModule;
1541 class WXDLLIMPEXP_BASE wxDateTimeHolidayAuthority
1542 {
1543 friend class wxDateTimeHolidaysModule;
1544 public:
1545     // returns true if the given date is a holiday
1546     static bool IsHoliday(const wxDateTime& dt);
1547 
1548     // fills the provided array with all holidays in the given range, returns
1549     // the number of them
1550     static size_t GetHolidaysInRange(const wxDateTime& dtStart,
1551                                      const wxDateTime& dtEnd,
1552                                      wxDateTimeArray& holidays);
1553 
1554     // clear the list of holiday authorities
1555     static void ClearAllAuthorities();
1556 
1557     // add a new holiday authority (the pointer will be deleted by
1558     // wxDateTimeHolidayAuthority)
1559     static void AddAuthority(wxDateTimeHolidayAuthority *auth);
1560 
1561     // the base class must have a virtual dtor
1562     virtual ~wxDateTimeHolidayAuthority();
1563 
1564 protected:
1565     // this function is called to determine whether a given day is a holiday
1566     virtual bool DoIsHoliday(const wxDateTime& dt) const = 0;
1567 
1568     // this function should fill the array with all holidays between the two
1569     // given dates - it is implemented in the base class, but in a very
1570     // inefficient way (it just iterates over all days and uses IsHoliday() for
1571     // each of them), so it must be overridden in the derived class where the
1572     // base class version may be explicitly used if needed
1573     //
1574     // returns the number of holidays in the given range and fills holidays
1575     // array
1576     virtual size_t DoGetHolidaysInRange(const wxDateTime& dtStart,
1577                                         const wxDateTime& dtEnd,
1578                                         wxDateTimeArray& holidays) const = 0;
1579 
1580 private:
1581     // all holiday authorities
1582     static wxHolidayAuthoritiesArray ms_authorities;
1583 };
1584 
1585 // the holidays for this class are all Saturdays and Sundays
1586 class WXDLLIMPEXP_BASE wxDateTimeWorkDays : public wxDateTimeHolidayAuthority
1587 {
1588 protected:
1589     virtual bool DoIsHoliday(const wxDateTime& dt) const wxOVERRIDE;
1590     virtual size_t DoGetHolidaysInRange(const wxDateTime& dtStart,
1591                                         const wxDateTime& dtEnd,
1592                                         wxDateTimeArray& holidays) const wxOVERRIDE;
1593 };
1594 
1595 // ============================================================================
1596 // inline functions implementation
1597 // ============================================================================
1598 
1599 // ----------------------------------------------------------------------------
1600 // private macros
1601 // ----------------------------------------------------------------------------
1602 
1603 #define MILLISECONDS_PER_DAY 86400000l
1604 
1605 // some broken compilers (HP-UX CC) refuse to compile the "normal" version, but
1606 // using a temp variable always might prevent other compilers from optimising
1607 // it away - hence use of this ugly macro
1608 #ifndef __HPUX__
1609     #define MODIFY_AND_RETURN(op) return wxDateTime(*this).op
1610 #else
1611     #define MODIFY_AND_RETURN(op) wxDateTime dt(*this); dt.op; return dt
1612 #endif
1613 
1614 // ----------------------------------------------------------------------------
1615 // wxDateTime construction
1616 // ----------------------------------------------------------------------------
1617 
IsInStdRange()1618 inline bool wxDateTime::IsInStdRange() const
1619 {
1620     // currently we don't know what is the real type of time_t so prefer to err
1621     // on the safe side and limit it to 32 bit values which is safe everywhere
1622     return m_time >= 0l && (m_time / TIME_T_FACTOR) < wxINT32_MAX;
1623 }
1624 
1625 /* static */
Now()1626 inline wxDateTime wxDateTime::Now()
1627 {
1628     struct tm tmstruct;
1629     return wxDateTime(*GetTmNow(&tmstruct));
1630 }
1631 
1632 /* static */
Today()1633 inline wxDateTime wxDateTime::Today()
1634 {
1635     wxDateTime dt(Now());
1636     dt.ResetTime();
1637 
1638     return dt;
1639 }
1640 
Set(time_t timet)1641 inline wxDateTime& wxDateTime::Set(time_t timet)
1642 {
1643     if ( timet == (time_t)-1 )
1644     {
1645         m_time = wxInvalidDateTime.m_time;
1646     }
1647     else
1648     {
1649         // assign first to avoid long multiplication overflow!
1650         m_time = timet - WX_TIME_BASE_OFFSET;
1651         m_time *= TIME_T_FACTOR;
1652     }
1653 
1654     return *this;
1655 }
1656 
SetToCurrent()1657 inline wxDateTime& wxDateTime::SetToCurrent()
1658 {
1659     *this = Now();
1660     return *this;
1661 }
1662 
wxDateTime(time_t timet)1663 inline wxDateTime::wxDateTime(time_t timet)
1664 {
1665     Set(timet);
1666 }
1667 
wxDateTime(const struct tm & tm)1668 inline wxDateTime::wxDateTime(const struct tm& tm)
1669 {
1670     Set(tm);
1671 }
1672 
wxDateTime(const Tm & tm)1673 inline wxDateTime::wxDateTime(const Tm& tm)
1674 {
1675     Set(tm);
1676 }
1677 
wxDateTime(double jdn)1678 inline wxDateTime::wxDateTime(double jdn)
1679 {
1680     Set(jdn);
1681 }
1682 
Set(const Tm & tm)1683 inline wxDateTime& wxDateTime::Set(const Tm& tm)
1684 {
1685     wxASSERT_MSG( tm.IsValid(), wxT("invalid broken down date/time") );
1686 
1687     return Set(tm.mday, (Month)tm.mon, tm.year,
1688                tm.hour, tm.min, tm.sec, tm.msec);
1689 }
1690 
wxDateTime(wxDateTime_t hour,wxDateTime_t minute,wxDateTime_t second,wxDateTime_t millisec)1691 inline wxDateTime::wxDateTime(wxDateTime_t hour,
1692                               wxDateTime_t minute,
1693                               wxDateTime_t second,
1694                               wxDateTime_t millisec)
1695 {
1696     Set(hour, minute, second, millisec);
1697 }
1698 
wxDateTime(wxDateTime_t day,Month month,int year,wxDateTime_t hour,wxDateTime_t minute,wxDateTime_t second,wxDateTime_t millisec)1699 inline wxDateTime::wxDateTime(wxDateTime_t day,
1700                               Month        month,
1701                               int          year,
1702                               wxDateTime_t hour,
1703                               wxDateTime_t minute,
1704                               wxDateTime_t second,
1705                               wxDateTime_t millisec)
1706 {
1707     Set(day, month, year, hour, minute, second, millisec);
1708 }
1709 
1710 // ----------------------------------------------------------------------------
1711 // wxDateTime accessors
1712 // ----------------------------------------------------------------------------
1713 
GetValue()1714 inline wxLongLong wxDateTime::GetValue() const
1715 {
1716     wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime"));
1717 
1718     return m_time;
1719 }
1720 
GetTicks()1721 inline time_t wxDateTime::GetTicks() const
1722 {
1723     wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime"));
1724     if ( !IsInStdRange() )
1725     {
1726         return (time_t)-1;
1727     }
1728 
1729     return (time_t)((m_time / (long)TIME_T_FACTOR).ToLong()) + WX_TIME_BASE_OFFSET;
1730 }
1731 
SetToLastWeekDay(WeekDay weekday,Month month,int year)1732 inline bool wxDateTime::SetToLastWeekDay(WeekDay weekday,
1733                                          Month month,
1734                                          int year)
1735 {
1736     return SetToWeekDay(weekday, -1, month, year);
1737 }
1738 
1739 inline wxDateTime
GetWeekDayInSameWeek(WeekDay weekday,WeekFlags WXUNUSED (flags))1740 wxDateTime::GetWeekDayInSameWeek(WeekDay weekday,
1741                                  WeekFlags WXUNUSED(flags)) const
1742 {
1743     MODIFY_AND_RETURN( SetToWeekDayInSameWeek(weekday) );
1744 }
1745 
GetNextWeekDay(WeekDay weekday)1746 inline wxDateTime wxDateTime::GetNextWeekDay(WeekDay weekday) const
1747 {
1748     MODIFY_AND_RETURN( SetToNextWeekDay(weekday) );
1749 }
1750 
GetPrevWeekDay(WeekDay weekday)1751 inline wxDateTime wxDateTime::GetPrevWeekDay(WeekDay weekday) const
1752 {
1753     MODIFY_AND_RETURN( SetToPrevWeekDay(weekday) );
1754 }
1755 
GetWeekDay(WeekDay weekday,int n,Month month,int year)1756 inline wxDateTime wxDateTime::GetWeekDay(WeekDay weekday,
1757                                          int n,
1758                                          Month month,
1759                                          int year) const
1760 {
1761     wxDateTime dt(*this);
1762 
1763     return dt.SetToWeekDay(weekday, n, month, year) ? dt : wxInvalidDateTime;
1764 }
1765 
GetLastWeekDay(WeekDay weekday,Month month,int year)1766 inline wxDateTime wxDateTime::GetLastWeekDay(WeekDay weekday,
1767                                              Month month,
1768                                              int year)
1769 {
1770     wxDateTime dt(*this);
1771 
1772     return dt.SetToLastWeekDay(weekday, month, year) ? dt : wxInvalidDateTime;
1773 }
1774 
GetLastMonthDay(Month month,int year)1775 inline wxDateTime wxDateTime::GetLastMonthDay(Month month, int year) const
1776 {
1777     MODIFY_AND_RETURN( SetToLastMonthDay(month, year) );
1778 }
1779 
GetYearDay(wxDateTime_t yday)1780 inline wxDateTime wxDateTime::GetYearDay(wxDateTime_t yday) const
1781 {
1782     MODIFY_AND_RETURN( SetToYearDay(yday) );
1783 }
1784 
1785 // ----------------------------------------------------------------------------
1786 // wxDateTime comparison
1787 // ----------------------------------------------------------------------------
1788 
IsEqualTo(const wxDateTime & datetime)1789 inline bool wxDateTime::IsEqualTo(const wxDateTime& datetime) const
1790 {
1791     return *this == datetime;
1792 }
1793 
IsEarlierThan(const wxDateTime & datetime)1794 inline bool wxDateTime::IsEarlierThan(const wxDateTime& datetime) const
1795 {
1796     return *this < datetime;
1797 }
1798 
IsLaterThan(const wxDateTime & datetime)1799 inline bool wxDateTime::IsLaterThan(const wxDateTime& datetime) const
1800 {
1801     return *this > datetime;
1802 }
1803 
IsStrictlyBetween(const wxDateTime & t1,const wxDateTime & t2)1804 inline bool wxDateTime::IsStrictlyBetween(const wxDateTime& t1,
1805                                           const wxDateTime& t2) const
1806 {
1807     // no need for assert, will be checked by the functions we call
1808     return IsLaterThan(t1) && IsEarlierThan(t2);
1809 }
1810 
IsBetween(const wxDateTime & t1,const wxDateTime & t2)1811 inline bool wxDateTime::IsBetween(const wxDateTime& t1,
1812                                   const wxDateTime& t2) const
1813 {
1814     // no need for assert, will be checked by the functions we call
1815     return IsEqualTo(t1) || IsEqualTo(t2) || IsStrictlyBetween(t1, t2);
1816 }
1817 
IsSameDate(const wxDateTime & dt)1818 inline bool wxDateTime::IsSameDate(const wxDateTime& dt) const
1819 {
1820     Tm tm1 = GetTm(),
1821        tm2 = dt.GetTm();
1822 
1823     return tm1.year == tm2.year &&
1824            tm1.mon == tm2.mon &&
1825            tm1.mday == tm2.mday;
1826 }
1827 
IsSameTime(const wxDateTime & dt)1828 inline bool wxDateTime::IsSameTime(const wxDateTime& dt) const
1829 {
1830     // notice that we can't do something like this:
1831     //
1832     //    m_time % MILLISECONDS_PER_DAY == dt.m_time % MILLISECONDS_PER_DAY
1833     //
1834     // because we have also to deal with (possibly) different DST settings!
1835     Tm tm1 = GetTm(),
1836        tm2 = dt.GetTm();
1837 
1838     return tm1.hour == tm2.hour &&
1839            tm1.min == tm2.min &&
1840            tm1.sec == tm2.sec &&
1841            tm1.msec == tm2.msec;
1842 }
1843 
IsEqualUpTo(const wxDateTime & dt,const wxTimeSpan & ts)1844 inline bool wxDateTime::IsEqualUpTo(const wxDateTime& dt,
1845                                     const wxTimeSpan& ts) const
1846 {
1847     return IsBetween(dt.Subtract(ts), dt.Add(ts));
1848 }
1849 
1850 // ----------------------------------------------------------------------------
1851 // wxDateTime arithmetic
1852 // ----------------------------------------------------------------------------
1853 
Add(const wxTimeSpan & diff)1854 inline wxDateTime wxDateTime::Add(const wxTimeSpan& diff) const
1855 {
1856     wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime"));
1857 
1858     return wxDateTime(m_time + diff.GetValue());
1859 }
1860 
Add(const wxTimeSpan & diff)1861 inline wxDateTime& wxDateTime::Add(const wxTimeSpan& diff)
1862 {
1863     wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime"));
1864 
1865     m_time += diff.GetValue();
1866 
1867     return *this;
1868 }
1869 
1870 inline wxDateTime& wxDateTime::operator+=(const wxTimeSpan& diff)
1871 {
1872     return Add(diff);
1873 }
1874 
Subtract(const wxTimeSpan & diff)1875 inline wxDateTime wxDateTime::Subtract(const wxTimeSpan& diff) const
1876 {
1877     wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime"));
1878 
1879     return wxDateTime(m_time - diff.GetValue());
1880 }
1881 
Subtract(const wxTimeSpan & diff)1882 inline wxDateTime& wxDateTime::Subtract(const wxTimeSpan& diff)
1883 {
1884     wxASSERT_MSG( IsValid(), wxT("invalid wxDateTime"));
1885 
1886     m_time -= diff.GetValue();
1887 
1888     return *this;
1889 }
1890 
1891 inline wxDateTime& wxDateTime::operator-=(const wxTimeSpan& diff)
1892 {
1893     return Subtract(diff);
1894 }
1895 
Subtract(const wxDateTime & datetime)1896 inline wxTimeSpan wxDateTime::Subtract(const wxDateTime& datetime) const
1897 {
1898     wxASSERT_MSG( IsValid() && datetime.IsValid(), wxT("invalid wxDateTime"));
1899 
1900     return wxTimeSpan(GetValue() - datetime.GetValue());
1901 }
1902 
1903 inline wxTimeSpan wxDateTime::operator-(const wxDateTime& dt2) const
1904 {
1905     return this->Subtract(dt2);
1906 }
1907 
Add(const wxDateSpan & diff)1908 inline wxDateTime wxDateTime::Add(const wxDateSpan& diff) const
1909 {
1910     return wxDateTime(*this).Add(diff);
1911 }
1912 
Subtract(const wxDateSpan & diff)1913 inline wxDateTime& wxDateTime::Subtract(const wxDateSpan& diff)
1914 {
1915     return Add(diff.Negate());
1916 }
1917 
Subtract(const wxDateSpan & diff)1918 inline wxDateTime wxDateTime::Subtract(const wxDateSpan& diff) const
1919 {
1920     return wxDateTime(*this).Subtract(diff);
1921 }
1922 
1923 inline wxDateTime& wxDateTime::operator-=(const wxDateSpan& diff)
1924 {
1925     return Subtract(diff);
1926 }
1927 
1928 inline wxDateTime& wxDateTime::operator+=(const wxDateSpan& diff)
1929 {
1930     return Add(diff);
1931 }
1932 
1933 // ----------------------------------------------------------------------------
1934 // wxDateTime and timezones
1935 // ----------------------------------------------------------------------------
1936 
1937 inline wxDateTime
ToTimezone(const wxDateTime::TimeZone & tz,bool noDST)1938 wxDateTime::ToTimezone(const wxDateTime::TimeZone& tz, bool noDST) const
1939 {
1940     MODIFY_AND_RETURN( MakeTimezone(tz, noDST) );
1941 }
1942 
1943 inline wxDateTime
FromTimezone(const wxDateTime::TimeZone & tz,bool noDST)1944 wxDateTime::FromTimezone(const wxDateTime::TimeZone& tz, bool noDST) const
1945 {
1946     MODIFY_AND_RETURN( MakeFromTimezone(tz, noDST) );
1947 }
1948 
1949 // ----------------------------------------------------------------------------
1950 // wxTimeSpan construction
1951 // ----------------------------------------------------------------------------
1952 
wxTimeSpan(long hours,long minutes,wxLongLong seconds,wxLongLong milliseconds)1953 inline wxTimeSpan::wxTimeSpan(long hours,
1954                               long minutes,
1955                               wxLongLong seconds,
1956                               wxLongLong milliseconds)
1957 {
1958     // assign first to avoid precision loss
1959     m_diff = hours;
1960     m_diff *= 60l;
1961     m_diff += minutes;
1962     m_diff *= 60l;
1963     m_diff += seconds;
1964     m_diff *= 1000l;
1965     m_diff += milliseconds;
1966 }
1967 
1968 // ----------------------------------------------------------------------------
1969 // wxTimeSpan accessors
1970 // ----------------------------------------------------------------------------
1971 
GetSeconds()1972 inline wxLongLong wxTimeSpan::GetSeconds() const
1973 {
1974     return m_diff / 1000l;
1975 }
1976 
GetMinutes()1977 inline int wxTimeSpan::GetMinutes() const
1978 {
1979     // For compatibility, this method (and the other accessors) return int,
1980     // even though GetLo() actually returns unsigned long with greater range.
1981     return static_cast<int>((GetSeconds() / 60l).GetLo());
1982 }
1983 
GetHours()1984 inline int wxTimeSpan::GetHours() const
1985 {
1986     return GetMinutes() / 60;
1987 }
1988 
GetDays()1989 inline int wxTimeSpan::GetDays() const
1990 {
1991     return GetHours() / 24;
1992 }
1993 
GetWeeks()1994 inline int wxTimeSpan::GetWeeks() const
1995 {
1996     return GetDays() / 7;
1997 }
1998 
1999 // ----------------------------------------------------------------------------
2000 // wxTimeSpan arithmetic
2001 // ----------------------------------------------------------------------------
2002 
Add(const wxTimeSpan & diff)2003 inline wxTimeSpan wxTimeSpan::Add(const wxTimeSpan& diff) const
2004 {
2005     return wxTimeSpan(m_diff + diff.GetValue());
2006 }
2007 
Add(const wxTimeSpan & diff)2008 inline wxTimeSpan& wxTimeSpan::Add(const wxTimeSpan& diff)
2009 {
2010     m_diff += diff.GetValue();
2011 
2012     return *this;
2013 }
2014 
Subtract(const wxTimeSpan & diff)2015 inline wxTimeSpan wxTimeSpan::Subtract(const wxTimeSpan& diff) const
2016 {
2017     return wxTimeSpan(m_diff - diff.GetValue());
2018 }
2019 
Subtract(const wxTimeSpan & diff)2020 inline wxTimeSpan& wxTimeSpan::Subtract(const wxTimeSpan& diff)
2021 {
2022     m_diff -= diff.GetValue();
2023 
2024     return *this;
2025 }
2026 
Multiply(int n)2027 inline wxTimeSpan& wxTimeSpan::Multiply(int n)
2028 {
2029     m_diff *= (long)n;
2030 
2031     return *this;
2032 }
2033 
Multiply(int n)2034 inline wxTimeSpan wxTimeSpan::Multiply(int n) const
2035 {
2036     return wxTimeSpan(m_diff * (long)n);
2037 }
2038 
Abs()2039 inline wxTimeSpan wxTimeSpan::Abs() const
2040 {
2041     return wxTimeSpan(GetValue().Abs());
2042 }
2043 
IsEqualTo(const wxTimeSpan & ts)2044 inline bool wxTimeSpan::IsEqualTo(const wxTimeSpan& ts) const
2045 {
2046     return GetValue() == ts.GetValue();
2047 }
2048 
IsLongerThan(const wxTimeSpan & ts)2049 inline bool wxTimeSpan::IsLongerThan(const wxTimeSpan& ts) const
2050 {
2051     return GetValue().Abs() > ts.GetValue().Abs();
2052 }
2053 
IsShorterThan(const wxTimeSpan & ts)2054 inline bool wxTimeSpan::IsShorterThan(const wxTimeSpan& ts) const
2055 {
2056     return GetValue().Abs() < ts.GetValue().Abs();
2057 }
2058 
2059 // ----------------------------------------------------------------------------
2060 // wxDateSpan
2061 // ----------------------------------------------------------------------------
2062 
2063 inline wxDateSpan& wxDateSpan::operator+=(const wxDateSpan& other)
2064 {
2065     m_years += other.m_years;
2066     m_months += other.m_months;
2067     m_weeks += other.m_weeks;
2068     m_days += other.m_days;
2069 
2070     return *this;
2071 }
2072 
Add(const wxDateSpan & other)2073 inline wxDateSpan& wxDateSpan::Add(const wxDateSpan& other)
2074 {
2075     return *this += other;
2076 }
2077 
Add(const wxDateSpan & other)2078 inline wxDateSpan wxDateSpan::Add(const wxDateSpan& other) const
2079 {
2080     wxDateSpan ds(*this);
2081     ds.Add(other);
2082     return ds;
2083 }
2084 
Multiply(int factor)2085 inline wxDateSpan& wxDateSpan::Multiply(int factor)
2086 {
2087     m_years *= factor;
2088     m_months *= factor;
2089     m_weeks *= factor;
2090     m_days *= factor;
2091 
2092     return *this;
2093 }
2094 
Multiply(int factor)2095 inline wxDateSpan wxDateSpan::Multiply(int factor) const
2096 {
2097     wxDateSpan ds(*this);
2098     ds.Multiply(factor);
2099     return ds;
2100 }
2101 
Negate()2102 inline wxDateSpan wxDateSpan::Negate() const
2103 {
2104     return wxDateSpan(-m_years, -m_months, -m_weeks, -m_days);
2105 }
2106 
Neg()2107 inline wxDateSpan& wxDateSpan::Neg()
2108 {
2109     m_years = -m_years;
2110     m_months = -m_months;
2111     m_weeks = -m_weeks;
2112     m_days = -m_days;
2113 
2114     return *this;
2115 }
2116 
2117 inline wxDateSpan& wxDateSpan::operator-=(const wxDateSpan& other)
2118 {
2119     return *this += other.Negate();
2120 }
2121 
Subtract(const wxDateSpan & other)2122 inline wxDateSpan& wxDateSpan::Subtract(const wxDateSpan& other)
2123 {
2124     return *this -= other;
2125 }
2126 
Subtract(const wxDateSpan & other)2127 inline wxDateSpan wxDateSpan::Subtract(const wxDateSpan& other) const
2128 {
2129     wxDateSpan ds(*this);
2130     ds.Subtract(other);
2131     return ds;
2132 }
2133 
2134 #undef MILLISECONDS_PER_DAY
2135 
2136 #undef MODIFY_AND_RETURN
2137 
2138 // ============================================================================
2139 // binary operators
2140 // ============================================================================
2141 
2142 // ----------------------------------------------------------------------------
2143 // wxTimeSpan operators
2144 // ----------------------------------------------------------------------------
2145 
2146 wxTimeSpan WXDLLIMPEXP_BASE operator*(int n, const wxTimeSpan& ts);
2147 
2148 // ----------------------------------------------------------------------------
2149 // wxDateSpan
2150 // ----------------------------------------------------------------------------
2151 
2152 wxDateSpan WXDLLIMPEXP_BASE operator*(int n, const wxDateSpan& ds);
2153 
2154 // ============================================================================
2155 // other helper functions
2156 // ============================================================================
2157 
2158 // ----------------------------------------------------------------------------
2159 // iteration helpers: can be used to write a for loop over enum variable like
2160 // this:
2161 //  for ( m = wxDateTime::Jan; m < wxDateTime::Inv_Month; wxNextMonth(m) )
2162 // ----------------------------------------------------------------------------
2163 
2164 WXDLLIMPEXP_BASE void wxNextMonth(wxDateTime::Month& m);
2165 WXDLLIMPEXP_BASE void wxPrevMonth(wxDateTime::Month& m);
2166 WXDLLIMPEXP_BASE void wxNextWDay(wxDateTime::WeekDay& wd);
2167 WXDLLIMPEXP_BASE void wxPrevWDay(wxDateTime::WeekDay& wd);
2168 
2169 #endif // wxUSE_DATETIME
2170 
2171 #endif // _WX_DATETIME_H
2172