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