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