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