home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / include / wx / datetime.h < prev    next >
C/C++ Source or Header  |  2002-08-31  |  66KB  |  1,586 lines

  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,v 1.34 2002/08/31 11:29:09 GD Exp $
  9. // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
  10. // Licence:     wxWindows license
  11. /////////////////////////////////////////////////////////////////////////////
  12.  
  13. #ifndef _WX_DATETIME_H
  14. #define _WX_DATETIME_H
  15.  
  16. #if defined(__GNUG__) && !defined(__APPLE__)
  17.     #pragma interface "datetime.h"
  18. #endif
  19.  
  20. #if wxUSE_DATETIME
  21.  
  22. #include <time.h>
  23. #include <limits.h>             // for INT_MIN
  24.  
  25. #include "wx/longlong.h"
  26.  
  27. class WXDLLEXPORT wxDateTime;
  28. class WXDLLEXPORT wxTimeSpan;
  29. class WXDLLEXPORT wxDateSpan;
  30.  
  31. // a hack: don't use inline functions in debug builds - we don't care about
  32. // performances and this only leads to increased rebuild time (because every
  33. // time an inline method is changed, all files including the header must be
  34. // rebuilt)
  35.  
  36. // For Mingw32, causes a link error. (VZ: why?)
  37. #if defined( __WXDEBUG__) && !defined(__MINGW32__)
  38.     #define wxDATETIME_DONT_INLINE
  39.  
  40.     #undef inline
  41.     #define inline
  42. #else
  43.     // just in case
  44.     #undef wxDATETIME_DONT_INLINE
  45. #endif // Debug
  46.  
  47. // not all c-runtimes are based on 1/1/1970 being (time_t) 0
  48. // set this to the corresponding value in seconds 1/1/1970 has on your
  49. // systems c-runtime
  50.  
  51. #ifdef __WXMAC__
  52. #if __MSL__ < 0x6000
  53.     #define WX_TIME_BASE_OFFSET ( 2082844800L + 126144000L )
  54. #else
  55.     #define WX_TIME_BASE_OFFSET 0
  56. #endif
  57. #else
  58.     #define WX_TIME_BASE_OFFSET 0
  59. #endif
  60. /*
  61.  * TODO
  62.  *
  63.  * + 1. Time zones with minutes (make TimeZone a class)
  64.  * ? 2. getdate() function like under Solaris
  65.  * + 3. text conversion for wxDateSpan
  66.  * + 4. pluggable modules for the workdays calculations
  67.  *   5. wxDateTimeHolidayAuthority for Easter and other christian feasts
  68.  */
  69.  
  70. /*
  71.   The three (main) classes declared in this header represent:
  72.  
  73.   1. An absolute moment in the time (wxDateTime)
  74.   2. A difference between two moments in the time, positive or negative
  75.      (wxTimeSpan)
  76.   3. A logical difference between two dates expressed in
  77.      years/months/weeks/days (wxDateSpan)
  78.  
  79.   The following arithmetic operations are permitted (all others are not):
  80.  
  81.   addition
  82.   --------
  83.  
  84.   wxDateTime + wxTimeSpan = wxDateTime
  85.   wxDateTime + wxDateSpan = wxDateTime
  86.   wxTimeSpan + wxTimeSpan = wxTimeSpan
  87.   wxDateSpan + wxDateSpan = wxDateSpan
  88.  
  89.   subtraction
  90.   ------------
  91.   wxDateTime - wxDateTime = wxTimeSpan
  92.   wxDateTime - wxTimeSpan = wxDateTime
  93.   wxDateTime - wxDateSpan = wxDateTime
  94.   wxTimeSpan - wxTimeSpan = wxTimeSpan
  95.   wxDateSpan - wxDateSpan = wxDateSpan
  96.  
  97.   multiplication
  98.   --------------
  99.   wxTimeSpan * number = wxTimeSpan
  100.   number * wxTimeSpan = wxTimeSpan
  101.   wxDateSpan * number = wxDateSpan
  102.   number * wxDateSpan = wxDateSpan
  103.  
  104.   unitary minus
  105.   -------------
  106.   -wxTimeSpan = wxTimeSpan
  107.   -wxDateSpan = wxDateSpan
  108.  
  109.   For each binary operation OP (+, -, *) we have the following operatorOP=() as
  110.   a method and the method with a symbolic name OPER (Add, Subtract, Multiply)
  111.   as a synonym for it and another const method with the same name which returns
  112.   the changed copy of the object and operatorOP() as a global function which is
  113.   implemented in terms of the const version of OPEN. For the unary - we have
  114.   operator-() as a method, Neg() as synonym for it and Negate() which returns
  115.   the copy of the object with the changed sign.
  116. */
  117.  
  118. // an invalid/default date time object which may be used as the default
  119. // argument for arguments of type wxDateTime; it is also returned by all
  120. // functions returning wxDateTime on failure (this is why it is also called
  121. // wxInvalidDateTime)
  122. class WXDLLEXPORT wxDateTime;
  123.  
  124. WXDLLEXPORT_DATA(extern const wxDateTime) wxDefaultDateTime;
  125. #define wxInvalidDateTime wxDefaultDateTime
  126.  
  127. // ----------------------------------------------------------------------------
  128. // wxDateTime represents an absolute moment in the time
  129. // ----------------------------------------------------------------------------
  130.  
  131. class WXDLLEXPORT wxDateTime
  132. {
  133. public:
  134.     // types
  135.     // ------------------------------------------------------------------------
  136.  
  137.         // a small unsigned integer type for storing things like minutes,
  138.         // seconds &c. It should be at least short (i.e. not char) to contain
  139.         // the number of milliseconds - it may also be 'int' because there is
  140.         // no size penalty associated with it in our code, we don't store any
  141.         // data in this format
  142.     typedef unsigned short wxDateTime_t;
  143.  
  144.     // constants
  145.     // ------------------------------------------------------------------------
  146.  
  147.         // the timezones
  148.     enum TZ
  149.     {
  150.         // the time in the current time zone
  151.         Local,
  152.  
  153.         // zones from GMT (= Greenwhich Mean Time): they're guaranteed to be
  154.         // consequent numbers, so writing something like `GMT0 + offset' is
  155.         // safe if abs(offset) <= 12
  156.  
  157.         // underscore stands for minus
  158.         GMT_12, GMT_11, GMT_10, GMT_9, GMT_8, GMT_7,
  159.         GMT_6, GMT_5, GMT_4, GMT_3, GMT_2, GMT_1,
  160.         GMT0,
  161.         GMT1, GMT2, GMT3, GMT4, GMT5, GMT6,
  162.         GMT7, GMT8, GMT9, GMT10, GMT11, GMT12,
  163.         // Note that GMT12 and GMT_12 are not the same: there is a difference
  164.         // of exactly one day between them
  165.  
  166.         // some symbolic names for TZ
  167.  
  168.         // Europe
  169.         WET = GMT0,                         // Western Europe Time
  170.         WEST = GMT1,                        // Western Europe Summer Time
  171.         CET = GMT1,                         // Central Europe Time
  172.         CEST = GMT2,                        // Central Europe Summer Time
  173.         EET = GMT2,                         // Eastern Europe Time
  174.         EEST = GMT3,                        // Eastern Europe Summer Time
  175.         MSK = GMT3,                         // Moscow Time
  176.         MSD = GMT4,                         // Moscow Summer Time
  177.  
  178.         // US and Canada
  179.         AST = GMT_4,                        // Atlantic Standard Time
  180.         ADT = GMT_3,                        // Atlantic Daylight Time
  181.         EST = GMT_5,                        // Eastern Standard Time
  182.         EDT = GMT_4,                        // Eastern Daylight Saving Time
  183.         CST = GMT_6,                        // Central Standard Time
  184.         CDT = GMT_5,                        // Central Daylight Saving Time
  185.         MST = GMT_7,                        // Mountain Standard Time
  186.         MDT = GMT_6,                        // Mountain Daylight Saving Time
  187.         PST = GMT_8,                        // Pacific Standard Time
  188.         PDT = GMT_7,                        // Pacific Daylight Saving Time
  189.         HST = GMT_10,                       // Hawaiian Standard Time
  190.         AKST = GMT_9,                       // Alaska Standard Time
  191.         AKDT = GMT_8,                       // Alaska Daylight Saving Time
  192.  
  193.         // Australia
  194.  
  195.         A_WST = GMT8,                       // Western Standard Time
  196.         A_CST = GMT12 + 1,                  // Central Standard Time (+9.5)
  197.         A_EST = GMT10,                      // Eastern Standard Time
  198.         A_ESST = GMT11,                     // Eastern Summer 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.         // these values only are used to identify the different dates of
  220.         // adoption of the Gregorian calendar (see IsGregorian())
  221.         //
  222.         // All data and comments taken verbatim from "The Calendar FAQ (v 2.0)"
  223.         // by Claus T°ndering, http://www.pip.dknet.dk/~c-t/calendar.html
  224.         // except for the comments "we take".
  225.         //
  226.         // Symbol "->" should be read as "was followed by" in the comments
  227.         // which follow.
  228.     enum GregorianAdoption
  229.     {
  230.         Gr_Unknown,    // no data for this country or it's too uncertain to use
  231.         Gr_Standard,   // on the day 0 of Gregorian calendar: 15 Oct 1582
  232.  
  233.         Gr_Alaska,             // Oct 1867 when Alaska became part of the USA
  234.         Gr_Albania,            // Dec 1912
  235.  
  236.         Gr_Austria = Gr_Unknown,    // Different regions on different dates
  237.         Gr_Austria_Brixen,          // 5 Oct 1583 -> 16 Oct 1583
  238.         Gr_Austria_Salzburg = Gr_Austria_Brixen,
  239.         Gr_Austria_Tyrol = Gr_Austria_Brixen,
  240.         Gr_Austria_Carinthia,       // 14 Dec 1583 -> 25 Dec 1583
  241.         Gr_Austria_Styria = Gr_Austria_Carinthia,
  242.  
  243.         Gr_Belgium,            // Then part of the Netherlands
  244.  
  245.         Gr_Bulgaria = Gr_Unknown, // Unknown precisely (from 1915 to 1920)
  246.         Gr_Bulgaria_1,         //      18 Mar 1916 -> 1 Apr 1916
  247.         Gr_Bulgaria_2,         //      31 Mar 1916 -> 14 Apr 1916
  248.         Gr_Bulgaria_3,         //      3 Sep 1920 -> 17 Sep 1920
  249.  
  250.         Gr_Canada = Gr_Unknown,   // Different regions followed the changes in
  251.                                // Great Britain or France
  252.  
  253.         Gr_China = Gr_Unknown,    // Different authorities say:
  254.         Gr_China_1,            //      18 Dec 1911 -> 1 Jan 1912
  255.         Gr_China_2,            //      18 Dec 1928 -> 1 Jan 1929
  256.  
  257.         Gr_Czechoslovakia,     // (Bohemia and Moravia) 6 Jan 1584 -> 17 Jan 1584
  258.         Gr_Denmark,            // (including Norway) 18 Feb 1700 -> 1 Mar 1700
  259.         Gr_Egypt,              // 1875
  260.         Gr_Estonia,            // 1918
  261.         Gr_Finland,            // Then part of Sweden
  262.  
  263.         Gr_France,             // 9 Dec 1582 -> 20 Dec 1582
  264.         Gr_France_Alsace,      //      4 Feb 1682 -> 16 Feb 1682
  265.         Gr_France_Lorraine,    //      16 Feb 1760 -> 28 Feb 1760
  266.         Gr_France_Strasbourg,  // February 1682
  267.  
  268.         Gr_Germany = Gr_Unknown,  // Different states on different dates:
  269.         Gr_Germany_Catholic,   //      1583-1585 (we take 1584)
  270.         Gr_Germany_Prussia,    //      22 Aug 1610 -> 2 Sep 1610
  271.         Gr_Germany_Protestant, //      18 Feb 1700 -> 1 Mar 1700
  272.  
  273.         Gr_GreatBritain,       // 2 Sep 1752 -> 14 Sep 1752 (use 'cal(1)')
  274.  
  275.         Gr_Greece,             // 9 Mar 1924 -> 23 Mar 1924
  276.         Gr_Hungary,            // 21 Oct 1587 -> 1 Nov 1587
  277.         Gr_Ireland = Gr_GreatBritain,
  278.         Gr_Italy = Gr_Standard,
  279.  
  280.         Gr_Japan = Gr_Unknown,    // Different authorities say:
  281.         Gr_Japan_1,            //      19 Dec 1872 -> 1 Jan 1873
  282.         Gr_Japan_2,            //      19 Dec 1892 -> 1 Jan 1893
  283.         Gr_Japan_3,            //      18 Dec 1918 -> 1 Jan 1919
  284.  
  285.         Gr_Latvia,             // 1915-1918 (we take 1915)
  286.         Gr_Lithuania,          // 1915
  287.         Gr_Luxemburg,          // 14 Dec 1582 -> 25 Dec 1582
  288.         Gr_Netherlands = Gr_Belgium, // (including Belgium) 1 Jan 1583
  289.  
  290.         // this is too weird to take into account: the Gregorian calendar was
  291.         // introduced twice in Groningen, first time 28 Feb 1583 was followed
  292.         // by 11 Mar 1583, then it has gone back to Julian in the summer of
  293.         // 1584 and then 13 Dec 1700 -> 12 Jan 1701 - which is
  294.         // the date we take here
  295.         Gr_Netherlands_Groningen,  // 13 Dec 1700 -> 12 Jan 1701
  296.         Gr_Netherlands_Gelderland, // 30 Jun 1700 -> 12 Jul 1700
  297.         Gr_Netherlands_Utrecht,    // (and Overijssel) 30 Nov 1700->12 Dec 1700
  298.         Gr_Netherlands_Friesland,  // (and Drenthe) 31 Dec 1700 -> 12 Jan 1701
  299.  
  300.         Gr_Norway = Gr_Denmark,       // Then part of Denmark
  301.         Gr_Poland = Gr_Standard,
  302.         Gr_Portugal = Gr_Standard,
  303.         Gr_Romania,                // 31 Mar 1919 -> 14 Apr 1919
  304.         Gr_Russia,                 // 31 Jan 1918 -> 14 Feb 1918
  305.         Gr_Scotland = Gr_GreatBritain,
  306.         Gr_Spain = Gr_Standard,
  307.  
  308.         // Sweden has a curious history. Sweden decided to make a gradual
  309.         // change from the Julian to the Gregorian calendar. By dropping every
  310.         // leap year from 1700 through 1740 the eleven superfluous days would
  311.         // be omitted and from 1 Mar 1740 they would be in sync with the
  312.         // Gregorian calendar. (But in the meantime they would be in sync with
  313.         // nobody!)
  314.         //
  315.         // So 1700 (which should have been a leap year in the Julian calendar)
  316.         // was not a leap year in Sweden. However, by mistake 1704 and 1708
  317.         // became leap years. This left Sweden out of synchronisation with
  318.         // both the Julian and the Gregorian world, so they decided to go back
  319.         // to the Julian calendar. In order to do this, they inserted an extra
  320.         // day in 1712, making that year a double leap year! So in 1712,
  321.         // February had 30 days in Sweden.
  322.         //
  323.         // Later, in 1753, Sweden changed to the Gregorian calendar by
  324.         // dropping 11 days like everyone else.
  325.         Gr_Sweden = Gr_Finland,       // 17 Feb 1753 -> 1 Mar 1753
  326.  
  327.         Gr_Switzerland = Gr_Unknown,// Different cantons used different dates
  328.         Gr_Switzerland_Catholic,    //      1583, 1584 or 1597 (we take 1584)
  329.         Gr_Switzerland_Protestant,  //      31 Dec 1700 -> 12 Jan 1701
  330.  
  331.         Gr_Turkey,                 // 1 Jan 1927
  332.         Gr_USA = Gr_GreatBritain,
  333.         Gr_Wales = Gr_GreatBritain,
  334.         Gr_Yugoslavia              // 1919
  335.     };
  336.  
  337.         // the country parameter is used so far for calculating the start and
  338.         // the end of DST period and for deciding whether the date is a work
  339.         // day or not
  340.         //
  341.         // TODO move this to intl.h
  342.     enum Country
  343.     {
  344.         Country_Unknown, // no special information for this country
  345.         Country_Default, // set the default country with SetCountry() method
  346.                          // or use the default country with any other
  347.  
  348.         // TODO add more countries (for this we must know about DST and/or
  349.         //      holidays for this country)
  350.  
  351.         // Western European countries: we assume that they all follow the same
  352.         // DST rules (true or false?)
  353.         Country_WesternEurope_Start,
  354.         Country_EEC = Country_WesternEurope_Start,
  355.         France,
  356.         Germany,
  357.         UK,
  358.         Country_WesternEurope_End = UK,
  359.  
  360.         Russia,
  361.  
  362.         USA
  363.     };
  364.  
  365.         // symbolic names for the months
  366.     enum Month
  367.     {
  368.         Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec, Inv_Month
  369.     };
  370.  
  371.         // symbolic names for the weekdays
  372.     enum WeekDay
  373.     {
  374.         Sun, Mon, Tue, Wed, Thu, Fri, Sat, Inv_WeekDay
  375.     };
  376.  
  377.         // invalid value for the year
  378.     enum Year
  379.     {
  380.         Inv_Year = SHRT_MIN    // should hold in wxDateTime_t
  381.     };
  382.  
  383.         // flags for GetWeekDayName and GetMonthName
  384.     enum NameFlags
  385.     {
  386.         Name_Full = 0x01,       // return full name
  387.         Name_Abbr = 0x02        // return abbreviated name
  388.     };
  389.  
  390.         // flags for GetWeekOfYear and GetWeekOfMonth
  391.     enum WeekFlags
  392.     {
  393.         Default_First,   // Sunday_First for US, Monday_First for the rest
  394.         Monday_First,    // week starts with a Monday
  395.         Sunday_First     // week starts with a Sunday
  396.     };
  397.  
  398.     // helper classes
  399.     // ------------------------------------------------------------------------
  400.  
  401.         // a class representing a time zone: basicly, this is just an offset
  402.         // (in seconds) from GMT
  403.     class WXDLLEXPORT TimeZone
  404.     {
  405.     public:
  406.         TimeZone(TZ tz);
  407.         TimeZone(wxDateTime_t offset = 0) { m_offset = offset; }
  408.  
  409.         long GetOffset() const { return m_offset; }
  410.  
  411.     private:
  412.         // offset for this timezone from GMT in seconds
  413.         long m_offset;
  414.     };
  415.  
  416.         // standard struct tm is limited to the years from 1900 (because
  417.         // tm_year field is the offset from 1900), so we use our own struct
  418.         // instead to represent broken down time
  419.         //
  420.         // NB: this struct should always be kept normalized (i.e. mon should
  421.         //     be < 12, 1 <= day <= 31 &c), so use AddMonths(), AddDays()
  422.         //     instead of modifying the member fields directly!
  423.     struct WXDLLEXPORT Tm
  424.     {
  425.         wxDateTime_t msec, sec, min, hour, mday;
  426.         Month mon;
  427.         int year;
  428.  
  429.         // default ctor inits the object to an invalid value
  430.         Tm();
  431.  
  432.         // ctor from struct tm and the timezone
  433.         Tm(const struct tm& tm, const TimeZone& tz);
  434.  
  435.         // check that the given date/time is valid (in Gregorian calendar)
  436.         bool IsValid() const;
  437.  
  438.         // get the week day
  439.         WeekDay GetWeekDay() // not const because wday may be changed
  440.         {
  441.             if ( wday == Inv_WeekDay )
  442.                 ComputeWeekDay();
  443.  
  444.             return (WeekDay)wday;
  445.         }
  446.  
  447.         // add the given number of months to the date keeping it normalized
  448.         void AddMonths(int monDiff);
  449.  
  450.         // add the given number of months to the date keeping it normalized
  451.         void AddDays(int dayDiff);
  452.  
  453.     private:
  454.         // compute the weekday from other fields
  455.         void ComputeWeekDay();
  456.  
  457.         // the timezone we correspond to
  458.         TimeZone m_tz;
  459.  
  460.         // these values can't be accessed directly because they're not always
  461.         // computed and we calculate them on demand
  462.         wxDateTime_t wday, yday;
  463.     };
  464.  
  465.     // static methods
  466.     // ------------------------------------------------------------------------
  467.  
  468.         // set the current country
  469.     static void SetCountry(Country country);
  470.         // get the current country
  471.     static Country GetCountry();
  472.  
  473.         // return TRUE if the country is a West European one (in practice,
  474.         // this means that the same DST rules as for EEC apply)
  475.     static bool IsWestEuropeanCountry(Country country = Country_Default);
  476.  
  477.         // return the current year
  478.     static int GetCurrentYear(Calendar cal = Gregorian);
  479.  
  480.         // convert the year as returned by wxDateTime::GetYear() to a year
  481.         // suitable for BC/AD notation. The difference is that BC year 1
  482.         // corresponds to the year 0 (while BC year 0 didn't exist) and AD
  483.         // year N is just year N.
  484.     static int ConvertYearToBC(int year);
  485.  
  486.         // return the current month
  487.     static Month GetCurrentMonth(Calendar cal = Gregorian);
  488.  
  489.         // returns TRUE if the given year is a leap year in the given calendar
  490.     static bool IsLeapYear(int year = Inv_Year, Calendar cal = Gregorian);
  491.  
  492.         // get the century (19 for 1999, 20 for 2000 and -5 for 492 BC)
  493.     static int GetCentury(int year = Inv_Year);
  494.  
  495.         // returns the number of days in this year (356 or 355 for Gregorian
  496.         // calendar usually :-)
  497.     static wxDateTime_t GetNumberOfDays(int year, Calendar cal = Gregorian);
  498.  
  499.         // get the number of the days in the given month (default value for
  500.         // the year means the current one)
  501.     static wxDateTime_t GetNumberOfDays(Month month,
  502.                                         int year = Inv_Year,
  503.                                         Calendar cal = Gregorian);
  504.  
  505.         // get the full (default) or abbreviated month name in the current
  506.         // locale, returns empty string on error
  507.     static wxString GetMonthName(Month month,
  508.                                  NameFlags flags = Name_Full);
  509.  
  510.         // get the full (default) or abbreviated weekday name in the current
  511.         // locale, returns empty string on error
  512.     static wxString GetWeekDayName(WeekDay weekday,
  513.                                    NameFlags flags = Name_Full);
  514.  
  515.         // get the AM and PM strings in the current locale (may be empty)
  516.     static void GetAmPmStrings(wxString *am, wxString *pm);
  517.  
  518.         // return TRUE if the given country uses DST for this year
  519.     static bool IsDSTApplicable(int year = Inv_Year,
  520.                                 Country country = Country_Default);
  521.  
  522.         // get the beginning of DST for this year, will return invalid object
  523.         // if no DST applicable in this year. The default value of the
  524.         // parameter means to take the current year.
  525.     static wxDateTime GetBeginDST(int year = Inv_Year,
  526.                                   Country country = Country_Default);
  527.         // get the end of DST for this year, will return invalid object
  528.         // if no DST applicable in this year. The default value of the
  529.         // parameter means to take the current year.
  530.     static wxDateTime GetEndDST(int year = Inv_Year,
  531.                                 Country country = Country_Default);
  532.  
  533.         // return the wxDateTime object for the current time
  534.     static inline wxDateTime Now();
  535.  
  536.         // return the wxDateTime object for the current time with millisecond
  537.         // precision (if available on this platform)
  538.     static wxDateTime UNow();
  539.  
  540.         // return the wxDateTime object for today midnight: i.e. as Now() but
  541.         // with time set to 0
  542.     static inline wxDateTime Today();
  543.  
  544.     // constructors: you should test whether the constructor succeeded with
  545.     // IsValid() function. The values Inv_Month and Inv_Year for the
  546.     // parameters mean take current month and/or year values.
  547.     // ------------------------------------------------------------------------
  548.  
  549.         // default ctor does not initialize the object, use Set()!
  550.     wxDateTime() { m_time = wxLongLong((long)ULONG_MAX, ULONG_MAX); }
  551.  
  552.         // from time_t: seconds since the Epoch 00:00:00 UTC, Jan 1, 1970)
  553. #if (!(defined(__VISAGECPP__) && __IBMCPP__ >= 400))
  554. // VA C++ confuses this with wxDateTime(double jdn) thinking it is a duplicate declaration
  555.     inline wxDateTime(time_t timet);
  556. #endif
  557.         // from broken down time/date (only for standard Unix range)
  558.     inline wxDateTime(const struct tm& tm);
  559.         // from broken down time/date (any range)
  560.     inline wxDateTime(const Tm& tm);
  561.  
  562.         // from JDN (beware of rounding errors)
  563.     inline wxDateTime(double jdn);
  564.  
  565.         // from separate values for each component, date set to today
  566.     inline wxDateTime(wxDateTime_t hour,
  567.                       wxDateTime_t minute = 0,
  568.                       wxDateTime_t second = 0,
  569.                       wxDateTime_t millisec = 0);
  570.         // from separate values for each component with explicit date
  571.     inline wxDateTime(wxDateTime_t day,             // day of the month
  572.                       Month        month,
  573.                       int          year = Inv_Year, // 1999, not 99 please!
  574.                       wxDateTime_t hour = 0,
  575.                       wxDateTime_t minute = 0,
  576.                       wxDateTime_t second = 0,
  577.                       wxDateTime_t millisec = 0);
  578.  
  579.         // default copy ctor ok
  580.  
  581.         // no dtor
  582.  
  583.     // assignment operators and Set() functions: all non const methods return
  584.     // the reference to this object. IsValid() should be used to test whether
  585.     // the function succeeded.
  586.     // ------------------------------------------------------------------------
  587.  
  588.         // set to the current time
  589.     inline wxDateTime& SetToCurrent();
  590.  
  591. #if (!(defined(__VISAGECPP__) && __IBMCPP__ >= 400))
  592. // VA C++ confuses this with wxDateTime(double jdn) thinking it is a duplicate declaration
  593.         // set to given time_t value
  594.     inline wxDateTime& Set(time_t timet);
  595. #endif
  596.  
  597.         // set to given broken down time/date
  598.     wxDateTime& Set(const struct tm& tm);
  599.  
  600.         // set to given broken down time/date
  601.     inline wxDateTime& Set(const Tm& tm);
  602.  
  603.         // set to given JDN (beware of rounding errors)
  604.     wxDateTime& Set(double jdn);
  605.  
  606.         // set to given time, date = today
  607.     wxDateTime& Set(wxDateTime_t hour,
  608.                     wxDateTime_t minute = 0,
  609.                     wxDateTime_t second = 0,
  610.                     wxDateTime_t millisec = 0);
  611.  
  612.         // from separate values for each component with explicit date
  613.         // (defaults for month and year are the current values)
  614.     wxDateTime& Set(wxDateTime_t day,
  615.                     Month        month,
  616.                     int          year = Inv_Year, // 1999, not 99 please!
  617.                     wxDateTime_t hour = 0,
  618.                     wxDateTime_t minute = 0,
  619.                     wxDateTime_t second = 0,
  620.                     wxDateTime_t millisec = 0);
  621.  
  622.         // resets time to 00:00:00, doesn't change the date
  623.     wxDateTime& ResetTime();
  624.  
  625.         // the following functions don't change the values of the other
  626.         // fields, i.e. SetMinute() won't change either hour or seconds value
  627.  
  628.         // set the year
  629.     wxDateTime& SetYear(int year);
  630.         // set the month
  631.     wxDateTime& SetMonth(Month month);
  632.         // set the day of the month
  633.     wxDateTime& SetDay(wxDateTime_t day);
  634.         // set hour
  635.     wxDateTime& SetHour(wxDateTime_t hour);
  636.         // set minute
  637.     wxDateTime& SetMinute(wxDateTime_t minute);
  638.         // set second
  639.     wxDateTime& SetSecond(wxDateTime_t second);
  640.         // set millisecond
  641.     wxDateTime& SetMillisecond(wxDateTime_t millisecond);
  642.  
  643.         // assignment operator from time_t
  644.     wxDateTime& operator=(time_t timet) { return Set(timet); }
  645.  
  646.         // assignment operator from broken down time/date
  647.     wxDateTime& operator=(const struct tm& tm) { return Set(tm); }
  648.  
  649.         // assignment operator from broken down time/date
  650.     wxDateTime& operator=(const Tm& tm) { return Set(tm); }
  651.  
  652.         // default assignment operator is ok
  653.  
  654.     // calendar calculations (functions which set the date only leave the time
  655.     // unchanged, e.g. don't explictly zero it): SetXXX() functions modify the
  656.     // object itself, GetXXX() ones return a new object.
  657.     // ------------------------------------------------------------------------
  658.  
  659.         // set to the given week day in the same week as this one
  660.     wxDateTime& SetToWeekDayInSameWeek(WeekDay weekday);
  661.     inline wxDateTime GetWeekDayInSameWeek(WeekDay weekday) const;
  662.  
  663.         // set to the next week day following this one
  664.     wxDateTime& SetToNextWeekDay(WeekDay weekday);
  665.     inline wxDateTime GetNextWeekDay(WeekDay weekday) const;
  666.  
  667.         // set to the previous week day before this one
  668.     wxDateTime& SetToPrevWeekDay(WeekDay weekday);
  669.     inline wxDateTime GetPrevWeekDay(WeekDay weekday) const;
  670.  
  671.         // set to Nth occurence of given weekday in the given month of the
  672.         // given year (time is set to 0), return TRUE on success and FALSE on
  673.         // failure. n may be positive (1..5) or negative to count from the end
  674.         // of the month (see helper function SetToLastWeekDay())
  675.     bool SetToWeekDay(WeekDay weekday,
  676.                       int n = 1,
  677.                       Month month = Inv_Month,
  678.                       int year = Inv_Year);
  679.     inline wxDateTime GetWeekDay(WeekDay weekday,
  680.                                  int n = 1,
  681.                                  Month month = Inv_Month,
  682.                                  int year = Inv_Year) const;
  683.  
  684.         // sets to the last weekday in the given month, year
  685.     inline bool SetToLastWeekDay(WeekDay weekday,
  686.                                  Month month = Inv_Month,
  687.                                  int year = Inv_Year);
  688.     inline wxDateTime GetLastWeekDay(WeekDay weekday,
  689.                                      Month month = Inv_Month,
  690.                                      int year = Inv_Year);
  691.  
  692.         // sets the date to the given day of the given week in the year,
  693.         // returns TRUE on success and FALSE if given date doesn't exist (e.g.
  694.         // numWeek is > 53)
  695.     bool SetToTheWeek(wxDateTime_t numWeek, WeekDay weekday = Mon);
  696.     inline wxDateTime GetWeek(wxDateTime_t numWeek, WeekDay weekday = Mon) const;
  697.  
  698.         // sets the date to the last day of the given (or current) month or the
  699.         // given (or current) year
  700.     wxDateTime& SetToLastMonthDay(Month month = Inv_Month,
  701.                                   int year = Inv_Year);
  702.     inline wxDateTime GetLastMonthDay(Month month = Inv_Month,
  703.                                       int year = Inv_Year) const;
  704.  
  705.         // sets to the given year day (1..365 or 366)
  706.     wxDateTime& SetToYearDay(wxDateTime_t yday);
  707.     inline wxDateTime GetYearDay(wxDateTime_t yday) const;
  708.  
  709.         // The definitions below were taken verbatim from
  710.         //
  711.         //      http://www.capecod.net/~pbaum/date/date0.htm
  712.         //
  713.         // (Peter Baum's home page)
  714.         //
  715.         // definition: The Julian Day Number, Julian Day, or JD of a
  716.         // particular instant of time is the number of days and fractions of a
  717.         // day since 12 hours Universal Time (Greenwich mean noon) on January
  718.         // 1 of the year -4712, where the year is given in the Julian
  719.         // proleptic calendar. The idea of using this reference date was
  720.         // originally proposed by Joseph Scalizer in 1582 to count years but
  721.         // it was modified by 19th century astronomers to count days. One
  722.         // could have equivalently defined the reference time to be noon of
  723.         // November 24, -4713 if were understood that Gregorian calendar rules
  724.         // were applied. Julian days are Julian Day Numbers and are not to be
  725.         // confused with Julian dates.
  726.         //
  727.         // definition: The Rata Die number is a date specified as the number
  728.         // of days relative to a base date of December 31 of the year 0. Thus
  729.         // January 1 of the year 1 is Rata Die day 1.
  730.  
  731.         // get the Julian Day number (the fractional part specifies the time of
  732.         // the day, related to noon - beware of rounding errors!)
  733.     double GetJulianDayNumber() const;
  734.     double GetJDN() const { return GetJulianDayNumber(); }
  735.  
  736.         // get the Modified Julian Day number: it is equal to JDN - 2400000.5
  737.         // and so integral MJDs correspond to the midnights (and not noons).
  738.         // MJD 0 is Nov 17, 1858
  739.     double GetModifiedJulianDayNumber() const { return GetJDN() - 2400000.5; }
  740.     double GetMJD() const { return GetModifiedJulianDayNumber(); }
  741.  
  742.         // get the Rata Die number
  743.     double GetRataDie() const;
  744.  
  745.         // TODO algorithms for calculating some important dates, such as
  746.         //      religious holidays (Easter...) or moon/solar eclipses? Some
  747.         //      algorithms can be found in the calendar FAQ
  748.  
  749.     // timezone stuff: a wxDateTime object constructed using given
  750.     // day/month/year/hour/min/sec values correspond to this moment in local
  751.     // time. Using the functions below, it may be converted to another time
  752.     // zone (for example, the Unix epoch is wxDateTime(1, Jan, 1970).ToGMT())
  753.     //
  754.     // these functions try to handle DST internally, but there is no magical
  755.     // way to know all rules for it in all countries in the world, so if the
  756.     // program can handle it itself (or doesn't want to handle it at all for
  757.     // whatever reason), the DST handling can be disabled with noDST.
  758.     //
  759.     // Converting to the local time zone doesn't do anything.
  760.     // ------------------------------------------------------------------------
  761.  
  762.         // transform to any given timezone
  763.     inline wxDateTime ToTimezone(const TimeZone& tz, bool noDST = FALSE) const;
  764.     wxDateTime& MakeTimezone(const TimeZone& tz, bool noDST = FALSE);
  765.  
  766.         // transform to GMT/UTC
  767.     wxDateTime ToGMT(bool noDST = FALSE) const { return ToTimezone(GMT0, noDST); }
  768.     wxDateTime& MakeGMT(bool noDST = FALSE) { return MakeTimezone(GMT0, noDST); }
  769.  
  770.         // is daylight savings time in effect at this moment according to the
  771.         // rules of the specified country?
  772.         //
  773.         // Return value is > 0 if DST is in effect, 0 if it is not and -1 if
  774.         // the information is not available (this is compatible with ANSI C)
  775.     int IsDST(Country country = Country_Default) const;
  776.  
  777.     // accessors: many of them take the timezone parameter which indicates the
  778.     // timezone for which to make the calculations and the default value means
  779.     // to do it for the current timezone of this machine (even if the function
  780.     // only operates with the date it's necessary because a date may wrap as
  781.     // result of timezone shift)
  782.     // ------------------------------------------------------------------------
  783.  
  784.         // is the date valid?
  785.     inline bool IsValid() const { return m_time != wxInvalidDateTime.m_time; }
  786.  
  787.         // get the broken down date/time representation in the given timezone
  788.         //
  789.         // If you wish to get several time components (day, month and year),
  790.         // consider getting the whole Tm strcuture first and retrieving the
  791.         // value from it - this is much more efficient
  792.     Tm GetTm(const TimeZone& tz = Local) const;
  793.  
  794.         // get the number of seconds since the Unix epoch - returns (time_t)-1
  795.         // if the value is out of range
  796.     inline time_t GetTicks() const;
  797.  
  798.         // get the year (returns Inv_Year if date is invalid)
  799.     int GetYear(const TimeZone& tz = Local) const
  800.             { return GetTm(tz).year; }
  801.         // get the month (Inv_Month if date is invalid)
  802.     Month GetMonth(const TimeZone& tz = Local) const
  803.             { return (Month)GetTm(tz).mon; }
  804.         // get the month day (in 1..31 range, 0 if date is invalid)
  805.     wxDateTime_t GetDay(const TimeZone& tz = Local) const
  806.             { return GetTm(tz).mday; }
  807.         // get the day of the week (Inv_WeekDay if date is invalid)
  808.     WeekDay GetWeekDay(const TimeZone& tz = Local) const
  809.             { return GetTm(tz).GetWeekDay(); }
  810.         // get the hour of the day
  811.     wxDateTime_t GetHour(const TimeZone& tz = Local) const
  812.             { return GetTm(tz).hour; }
  813.         // get the minute
  814.     wxDateTime_t GetMinute(const TimeZone& tz = Local) const
  815.             { return GetTm(tz).min; }
  816.         // get the second
  817.     wxDateTime_t GetSecond(const TimeZone& tz = Local) const
  818.             { return GetTm(tz).sec; }
  819.         // get milliseconds
  820.     wxDateTime_t GetMillisecond(const TimeZone& tz = Local) const
  821.             { return GetTm(tz).msec; }
  822.  
  823.         // get the day since the year start (1..366, 0 if date is invalid)
  824.     wxDateTime_t GetDayOfYear(const TimeZone& tz = Local) const;
  825.         // get the week number since the year start (1..52 or 53, 0 if date is
  826.         // invalid)
  827.     wxDateTime_t GetWeekOfYear(WeekFlags flags = Monday_First,
  828.                                const TimeZone& tz = Local) const;
  829.         // get the week number since the month start (1..5, 0 if date is
  830.         // invalid)
  831.     wxDateTime_t GetWeekOfMonth(WeekFlags flags = Monday_First,
  832.                                 const TimeZone& tz = Local) const;
  833.  
  834.         // is this date a work day? This depends on a country, of course,
  835.         // because the holidays are different in different countries
  836.     bool IsWorkDay(Country country = Country_Default) const;
  837.  
  838.         // is this date later than Gregorian calendar introduction for the
  839.         // given country (see enum GregorianAdoption)?
  840.         //
  841.         // NB: this function shouldn't be considered as absolute authority in
  842.         //     the matter. Besides, for some countries the exact date of
  843.         //     adoption of the Gregorian calendar is simply unknown.
  844.     bool IsGregorianDate(GregorianAdoption country = Gr_Standard) const;
  845.  
  846.     // comparison (see also functions below for operator versions)
  847.     // ------------------------------------------------------------------------
  848.  
  849.         // returns TRUE if the two moments are strictly identical
  850.     inline bool IsEqualTo(const wxDateTime& datetime) const;
  851.  
  852.         // returns TRUE if the date is strictly earlier than the given one
  853.     inline bool IsEarlierThan(const wxDateTime& datetime) const;
  854.  
  855.         // returns TRUE if the date is strictly later than the given one
  856.     inline bool IsLaterThan(const wxDateTime& datetime) const;
  857.  
  858.         // returns TRUE if the date is strictly in the given range
  859.     inline bool IsStrictlyBetween(const wxDateTime& t1,
  860.                                   const wxDateTime& t2) const;
  861.  
  862.         // returns TRUE if the date is in the given range
  863.     inline bool IsBetween(const wxDateTime& t1, const wxDateTime& t2) const;
  864.  
  865.         // do these two objects refer to the same date?
  866.     inline bool IsSameDate(const wxDateTime& dt) const;
  867.  
  868.         // do these two objects have the same time?
  869.     inline bool IsSameTime(const wxDateTime& dt) const;
  870.  
  871.         // are these two objects equal up to given timespan?
  872.     inline bool IsEqualUpTo(const wxDateTime& dt, const wxTimeSpan& ts) const;
  873.  
  874.     // arithmetics with dates (see also below for more operators)
  875.     // ------------------------------------------------------------------------
  876.  
  877.         // return the sum of the date with a time span (positive or negative)
  878.     inline wxDateTime Add(const wxTimeSpan& diff) const;
  879.         // add a time span (positive or negative)
  880.     inline wxDateTime& Add(const wxTimeSpan& diff);
  881.         // add a time span (positive or negative)
  882.     inline wxDateTime& operator+=(const wxTimeSpan& diff);
  883.  
  884.         // return the difference of the date with a time span
  885.     inline wxDateTime Subtract(const wxTimeSpan& diff) const;
  886.         // subtract a time span (positive or negative)
  887.     inline wxDateTime& Subtract(const wxTimeSpan& diff);
  888.         // subtract a time span (positive or negative)
  889.     inline wxDateTime& operator-=(const wxTimeSpan& diff);
  890.  
  891.         // return the sum of the date with a date span
  892.     inline wxDateTime Add(const wxDateSpan& diff) const;
  893.         // add a date span (positive or negative)
  894.     wxDateTime& Add(const wxDateSpan& diff);
  895.         // add a date span (positive or negative)
  896.     inline wxDateTime& operator+=(const wxDateSpan& diff);
  897.  
  898.         // return the difference of the date with a date span
  899.     inline wxDateTime Subtract(const wxDateSpan& diff) const;
  900.         // subtract a date span (positive or negative)
  901.     inline wxDateTime& Subtract(const wxDateSpan& diff);
  902.         // subtract a date span (positive or negative)
  903.     inline wxDateTime& operator-=(const wxDateSpan& diff);
  904.  
  905.         // return the difference between two dates
  906.     inline wxTimeSpan Subtract(const wxDateTime& dt) const;
  907.  
  908.     // conversion to/from text: all conversions from text return the pointer to
  909.     // the next character following the date specification (i.e. the one where
  910.     // the scan had to stop) or NULL on failure.
  911.     // ------------------------------------------------------------------------
  912.  
  913.         // parse a string in RFC 822 format (found e.g. in mail headers and
  914.         // having the form "Wed, 10 Feb 1999 19:07:07 +0100")
  915.     const wxChar *ParseRfc822Date(const wxChar* date);
  916.         // parse a date/time in the given format (see strptime(3)), fill in
  917.         // the missing (in the string) fields with the values of dateDef (by
  918.         // default, they will not change if they had valid values or will
  919.         // default to Today() otherwise)
  920.     const wxChar *ParseFormat(const wxChar *date,
  921.                               const wxChar *format = _T("%c"),
  922.                               const wxDateTime& dateDef = wxDefaultDateTime);
  923.         // parse a string containing the date/time in "free" format, this
  924.         // function will try to make an educated guess at the string contents
  925.     const wxChar *ParseDateTime(const wxChar *datetime);
  926.         // parse a string containing the date only in "free" format (less
  927.         // flexible than ParseDateTime)
  928.     const wxChar *ParseDate(const wxChar *date);
  929.         // parse a string containing the time only in "free" format
  930.     const wxChar *ParseTime(const wxChar *time);
  931.  
  932.         // this function accepts strftime()-like format string (default
  933.         // argument corresponds to the preferred date and time representation
  934.         // for the current locale) and returns the string containing the
  935.         // resulting text representation
  936.     wxString Format(const wxChar *format = _T("%c"),
  937.                     const TimeZone& tz = Local) const;
  938.         // preferred date representation for the current locale
  939.     wxString FormatDate() const { return Format(_T("%x")); }
  940.         // preferred time representation for the current locale
  941.     wxString FormatTime() const { return Format(_T("%X")); }
  942.         // returns the string representing the date in ISO 8601 format
  943.         // (YYYY-MM-DD)
  944.     wxString FormatISODate() const { return Format(_T("%Y-%m-%d")); }
  945.         // returns the string representing the time in ISO 8601 format
  946.         // (HH:MM:SS)
  947.     wxString FormatISOTime() const { return Format(_T("%H:%M:%S")); }
  948.  
  949.     // implementation
  950.     // ------------------------------------------------------------------------
  951.  
  952.         // construct from internal representation
  953.     wxDateTime(const wxLongLong& time) { m_time = time; }
  954.  
  955.         // get the internal representation
  956.     inline wxLongLong GetValue() const;
  957.  
  958.     // a helper function to get the current time_t
  959.     static time_t GetTimeNow() { return time((time_t *)NULL); }
  960.  
  961.     // another one to get the current time broken down
  962.     static struct tm *GetTmNow()
  963.     {
  964.         time_t t = GetTimeNow();
  965.         return localtime(&t);
  966.     }
  967.  
  968. private:
  969.     // the current country - as it's the same for all program objects (unless
  970.     // it runs on a _really_ big cluster system :-), this is a static member:
  971.     // see SetCountry() and GetCountry()
  972.     static Country ms_country;
  973.  
  974.     // this constant is used to transform a time_t value to the internal
  975.     // representation, as time_t is in seconds and we use milliseconds it's
  976.     // fixed to 1000
  977.     static const long TIME_T_FACTOR;
  978.  
  979.     // returns TRUE if we fall in range in which we can use standard ANSI C
  980.     // functions
  981.     inline bool IsInStdRange() const;
  982.  
  983.     // the internal representation of the time is the amount of milliseconds
  984.     // elapsed since the origin which is set by convention to the UNIX/C epoch
  985.     // value: the midnight of January 1, 1970 (UTC)
  986.     wxLongLong m_time;
  987. };
  988.  
  989. // ----------------------------------------------------------------------------
  990. // This class contains a difference between 2 wxDateTime values, so it makes
  991. // sense to add it to wxDateTime and it is the result of subtraction of 2
  992. // objects of that class. See also wxDateSpan.
  993. // ----------------------------------------------------------------------------
  994.  
  995. class WXDLLEXPORT wxTimeSpan
  996. {
  997. public:
  998.     // constructors
  999.     // ------------------------------------------------------------------------
  1000.  
  1001.         // return the timespan for the given number of seconds
  1002.     static wxTimeSpan Seconds(long sec) { return wxTimeSpan(0, 0, sec); }
  1003.     static wxTimeSpan Second() { return Seconds(1); }
  1004.  
  1005.         // return the timespan for the given number of minutes
  1006.     static wxTimeSpan Minutes(long min) { return wxTimeSpan(0, min, 0 ); }
  1007.     static wxTimeSpan Minute() { return Minutes(1); }
  1008.  
  1009.         // return the timespan for the given number of hours
  1010.     static wxTimeSpan Hours(long hours) { return wxTimeSpan(hours, 0, 0); }
  1011.     static wxTimeSpan Hour() { return Hours(1); }
  1012.  
  1013.         // return the timespan for the given number of days
  1014.     static wxTimeSpan Days(long days) { return Hours(24 * days); }
  1015.     static wxTimeSpan Day() { return Days(1); }
  1016.  
  1017.         // return the timespan for the given number of weeks
  1018.     static wxTimeSpan Weeks(long days) { return Days(7 * days); }
  1019.     static wxTimeSpan Week() { return Weeks(1); }
  1020.  
  1021.         // default ctor constructs the 0 time span
  1022.     wxTimeSpan() { }
  1023.  
  1024.         // from separate values for each component, date set to 0 (hours are
  1025.         // not restricted to 0..24 range, neither are minutes, seconds or
  1026.         // milliseconds)
  1027.     inline wxTimeSpan(long hours,
  1028.                       long minutes = 0,
  1029.                       long seconds = 0,
  1030.                       long milliseconds = 0);
  1031.  
  1032.         // default copy ctor is ok
  1033.  
  1034.         // no dtor
  1035.  
  1036.     // arithmetics with time spans (see also below for more operators)
  1037.     // ------------------------------------------------------------------------
  1038.  
  1039.         // return the sum of two timespans
  1040.     inline wxTimeSpan Add(const wxTimeSpan& diff) const;
  1041.         // add two timespans together
  1042.     inline wxTimeSpan& Add(const wxTimeSpan& diff);
  1043.         // add two timespans together
  1044.     wxTimeSpan& operator+=(const wxTimeSpan& diff) { return Add(diff); }
  1045.  
  1046.         // return the difference of two timespans
  1047.     inline wxTimeSpan Subtract(const wxTimeSpan& diff) const;
  1048.         // subtract another timespan
  1049.     inline wxTimeSpan& Subtract(const wxTimeSpan& diff);
  1050.         // subtract another timespan
  1051.     wxTimeSpan& operator-=(const wxTimeSpan& diff) { return Subtract(diff); }
  1052.  
  1053.         // multiply timespan by a scalar
  1054.     inline wxTimeSpan Multiply(int n) const;
  1055.         // multiply timespan by a scalar
  1056.     inline wxTimeSpan& Multiply(int n);
  1057.         // multiply timespan by a scalar
  1058.     wxTimeSpan& operator*=(int n) { return Multiply(n); }
  1059.  
  1060.         // return this timespan with inversed sign
  1061.     wxTimeSpan Negate() const { return wxTimeSpan(-GetValue()); }
  1062.         // negate the value of the timespan
  1063.     wxTimeSpan& Neg() { m_diff = -GetValue(); return *this; }
  1064.         // negate the value of the timespan
  1065.     wxTimeSpan& operator-() { return Neg(); }
  1066.  
  1067.         // return the absolute value of the timespan: does _not_ modify the
  1068.         // object
  1069.     inline wxTimeSpan Abs() const;
  1070.  
  1071.         // there is intentionally no division because we don't want to
  1072.         // introduce rounding errors in time calculations
  1073.  
  1074.     // comparaison (see also operator versions below)
  1075.     // ------------------------------------------------------------------------
  1076.  
  1077.         // is the timespan null?
  1078.     bool IsNull() const { return m_diff == 0l; }
  1079.         // returns true if the timespan is null
  1080.     bool operator!() const { return !IsNull(); }
  1081.  
  1082.         // is the timespan positive?
  1083.     bool IsPositive() const { return m_diff > 0l; }
  1084.  
  1085.         // is the timespan negative?
  1086.     bool IsNegative() const { return m_diff < 0l; }
  1087.  
  1088.         // are two timespans equal?
  1089.     inline bool IsEqualTo(const wxTimeSpan& ts) const;
  1090.         // compare two timestamps: works with the absolute values, i.e. -2
  1091.         // hours is longer than 1 hour. Also, it will return FALSE if the
  1092.         // timespans are equal in absolute value.
  1093.     inline bool IsLongerThan(const wxTimeSpan& ts) const;
  1094.         // compare two timestamps: works with the absolute values, i.e. 1
  1095.         // hour is shorter than -2 hours. Also, it will return FALSE if the
  1096.         // timespans are equal in absolute value.
  1097.     bool IsShorterThan(const wxTimeSpan& t) const { return !IsLongerThan(t); }
  1098.  
  1099.     // breaking into days, hours, minutes and seconds
  1100.     // ------------------------------------------------------------------------
  1101.  
  1102.         // get the max number of weeks in this timespan
  1103.     inline int GetWeeks() const;
  1104.         // get the max number of days in this timespan
  1105.     inline int GetDays() const;
  1106.         // get the max number of hours in this timespan
  1107.     inline int GetHours() const;
  1108.         // get the max number of minutes in this timespan
  1109.     inline int GetMinutes() const;
  1110.         // get the max number of seconds in this timespan
  1111.     inline wxLongLong GetSeconds() const;
  1112.         // get the number of milliseconds in this timespan
  1113.     wxLongLong GetMilliseconds() const { return m_diff; }
  1114.  
  1115.     // conversion to text
  1116.     // ------------------------------------------------------------------------
  1117.  
  1118.         // this function accepts strftime()-like format string (default
  1119.         // argument corresponds to the preferred date and time representation
  1120.         // for the current locale) and returns the string containing the
  1121.         // resulting text representation. Notice that only some of format
  1122.         // specifiers valid for wxDateTime are valid for wxTimeSpan: hours,
  1123.         // minutes and seconds make sense, but not "PM/AM" string for example.
  1124.     wxString Format(const wxChar *format = _T("%H:%M:%S")) const;
  1125.  
  1126.     // implementation
  1127.     // ------------------------------------------------------------------------
  1128.  
  1129.         // construct from internal representation
  1130.     wxTimeSpan(const wxLongLong& diff) { m_diff = diff; }
  1131.  
  1132.         // get the internal representation
  1133.     wxLongLong GetValue() const { return m_diff; }
  1134.  
  1135. private:
  1136.     // the (signed) time span in milliseconds
  1137.     wxLongLong m_diff;
  1138. };
  1139.  
  1140. // ----------------------------------------------------------------------------
  1141. // This class is a "logical time span" and is useful for implementing program
  1142. // logic for such things as "add one month to the date" which, in general,
  1143. // doesn't mean to add 60*60*24*31 seconds to it, but to take the same date
  1144. // the next month (to understand that this is indeed different consider adding
  1145. // one month to Feb, 15 - we want to get Mar, 15, of course).
  1146. //
  1147. // When adding a month to the date, all lesser components (days, hours, ...)
  1148. // won't be changed unless the resulting date would be invalid: for example,
  1149. // Jan 31 + 1 month will be Feb 28, not (non existing) Feb 31.
  1150. //
  1151. // Because of this feature, adding and subtracting back again the same
  1152. // wxDateSpan will *not*, in general give back the original date: Feb 28 - 1
  1153. // month will be Jan 28, not Jan 31!
  1154. //
  1155. // wxDateSpan can be either positive or negative. They may be
  1156. // multiplied by scalars which multiply all deltas by the scalar: i.e. 2*(1
  1157. // month and 1 day) is 2 months and 2 days. They can be added together and
  1158. // with wxDateTime or wxTimeSpan, but the type of result is different for each
  1159. // case.
  1160. //
  1161. // Beware about weeks: if you specify both weeks and days, the total number of
  1162. // days added will be 7*weeks + days! See also GetTotalDays() function.
  1163. //
  1164. // Finally, notice that for adding hours, minutes &c you don't need this
  1165. // class: wxTimeSpan will do the job because there are no subtleties
  1166. // associated with those.
  1167. // ----------------------------------------------------------------------------
  1168.  
  1169. class WXDLLEXPORT wxDateSpan
  1170. {
  1171. public:
  1172.     // constructors
  1173.     // ------------------------------------------------------------------------
  1174.  
  1175.         // this many years/months/weeks/days
  1176.     wxDateSpan(int years = 0, int months = 0, int weeks = 0, int days = 0)
  1177.     {
  1178.         m_years = years;
  1179.         m_months = months;
  1180.         m_weeks = weeks;
  1181.         m_days = days;
  1182.     }
  1183.  
  1184.         // get an object for the given number of days
  1185.     static wxDateSpan Days(int days) { return wxDateSpan(0, 0, 0, days); }
  1186.     static wxDateSpan Day() { return Days(1); }
  1187.  
  1188.         // get an object for the given number of weeks
  1189.     static wxDateSpan Weeks(int weeks) { return wxDateSpan(0, 0, weeks, 0); }
  1190.     static wxDateSpan Week() { return Weeks(1); }
  1191.  
  1192.         // get an object for the given number of months
  1193.     static wxDateSpan Months(int mon) { return wxDateSpan(0, mon, 0, 0); }
  1194.     static wxDateSpan Month() { return Months(1); }
  1195.  
  1196.         // get an object for the given number of years
  1197.     static wxDateSpan Years(int years) { return wxDateSpan(years, 0, 0, 0); }
  1198.     static wxDateSpan Year() { return Years(1); }
  1199.  
  1200.         // default copy ctor is ok
  1201.  
  1202.         // no dtor
  1203.  
  1204.     // accessors (all SetXXX() return the (modified) wxDateSpan object)
  1205.     // ------------------------------------------------------------------------
  1206.  
  1207.         // set number of years
  1208.     wxDateSpan& SetYears(int n) { m_years = n; return *this; }
  1209.         // set number of months
  1210.     wxDateSpan& SetMonths(int n) { m_months = n; return *this; }
  1211.         // set number of weeks
  1212.     wxDateSpan& SetWeeks(int n) { m_weeks = n; return *this; }
  1213.         // set number of days
  1214.     wxDateSpan& SetDays(int n) { m_days = n; return *this; }
  1215.  
  1216.         // get number of years
  1217.     int GetYears() const { return m_years; }
  1218.         // get number of months
  1219.     int GetMonths() const { return m_months; }
  1220.         // get number of weeks
  1221.     int GetWeeks() const { return m_weeks; }
  1222.         // get number of days
  1223.     int GetDays() const { return m_days; }
  1224.         // returns 7*GetWeeks() + GetDays()
  1225.     int GetTotalDays() const { return 7*m_weeks + m_days; }
  1226.  
  1227.     // arithmetics with date spans (see also below for more operators)
  1228.     // ------------------------------------------------------------------------
  1229.  
  1230.         // return sum of two date spans
  1231.     inline wxDateSpan Add(const wxDateSpan& other) const;
  1232.         // add another wxDateSpan to us
  1233.     inline wxDateSpan& Add(const wxDateSpan& other);
  1234.         // add another wxDateSpan to us
  1235.     inline wxDateSpan& operator+=(const wxDateSpan& other);
  1236.  
  1237.         // return difference of two date spans
  1238.     inline wxDateSpan Subtract(const wxDateSpan& other) const;
  1239.         // subtract another wxDateSpan from us
  1240.     inline wxDateSpan& Subtract(const wxDateSpan& other);
  1241.         // subtract another wxDateSpan from us
  1242.     inline wxDateSpan& operator-=(const wxDateSpan& other);
  1243.  
  1244.         // return a copy of this time span with changed sign
  1245.     inline wxDateSpan Negate() const;
  1246.         // inverse the sign of this timespan
  1247.     inline wxDateSpan& Neg();
  1248.         // inverse the sign of this timespan
  1249.     wxDateSpan& operator-() { return Neg(); }
  1250.  
  1251.         // return the date span proportional to this one with given factor
  1252.     inline wxDateSpan Multiply(int factor) const;
  1253.         // multiply all components by a (signed) number
  1254.     inline wxDateSpan& Multiply(int factor);
  1255.         // multiply all components by a (signed) number
  1256.     inline wxDateSpan& operator*=(int factor) { return Multiply(factor); }
  1257.  
  1258. private:
  1259.     int m_years,
  1260.         m_months,
  1261.         m_weeks,
  1262.         m_days;
  1263. };
  1264.  
  1265. // ----------------------------------------------------------------------------
  1266. // wxDateTimeArray: array of dates.
  1267. // ----------------------------------------------------------------------------
  1268.  
  1269. #include "wx/dynarray.h"
  1270.  
  1271. WX_DECLARE_EXPORTED_OBJARRAY(wxDateTime, wxDateTimeArray);
  1272.  
  1273. // ----------------------------------------------------------------------------
  1274. // wxDateTimeHolidayAuthority: an object of this class will decide whether a
  1275. // given date is a holiday and is used by all functions working with "work
  1276. // days".
  1277. //
  1278. // NB: the base class is an ABC, derived classes must implement the pure
  1279. //     virtual methods to work with the holidays they correspond to.
  1280. // ----------------------------------------------------------------------------
  1281.  
  1282. class WXDLLEXPORT wxDateTimeHolidayAuthority;
  1283. WX_DEFINE_EXPORTED_ARRAY(wxDateTimeHolidayAuthority *, wxHolidayAuthoritiesArray);
  1284.  
  1285. class wxDateTimeHolidaysModule;
  1286. class WXDLLEXPORT wxDateTimeHolidayAuthority
  1287. {
  1288. friend class wxDateTimeHolidaysModule;
  1289. public:
  1290.     // returns TRUE if the given date is a holiday
  1291.     static bool IsHoliday(const wxDateTime& dt);
  1292.  
  1293.     // fills the provided array with all holidays in the given range, returns
  1294.     // the number of them
  1295.     static size_t GetHolidaysInRange(const wxDateTime& dtStart,
  1296.                                      const wxDateTime& dtEnd,
  1297.                                      wxDateTimeArray& holidays);
  1298.  
  1299.     // clear the list of holiday authorities
  1300.     static void ClearAllAuthorities();
  1301.  
  1302.     // add a new holiday authority (the pointer will be deleted by
  1303.     // wxDateTimeHolidayAuthority)
  1304.     static void AddAuthority(wxDateTimeHolidayAuthority *auth);
  1305.  
  1306. protected:
  1307.     // this function is called to determine whether a given day is a holiday
  1308.     virtual bool DoIsHoliday(const wxDateTime& dt) const = 0;
  1309.  
  1310.     // this function should fill the array with all holidays between the two
  1311.     // given dates - it is implemented in the base class, but in a very
  1312.     // inefficient way (it just iterates over all days and uses IsHoliday() for
  1313.     // each of them), so it must be overridden in the derived class where the
  1314.     // base class version may be explicitly used if needed
  1315.     //
  1316.     // returns the number of holidays in the given range and fills holidays
  1317.     // array
  1318.     virtual size_t DoGetHolidaysInRange(const wxDateTime& dtStart,
  1319.                                         const wxDateTime& dtEnd,
  1320.                                         wxDateTimeArray& holidays) const = 0;
  1321.  
  1322. private:
  1323.     // all holiday authorities
  1324.     static wxHolidayAuthoritiesArray ms_authorities;
  1325. };
  1326.  
  1327. // the holidays for this class are all Saturdays and Sundays
  1328. class WXDLLEXPORT wxDateTimeWorkDays : public wxDateTimeHolidayAuthority
  1329. {
  1330. protected:
  1331.     virtual bool DoIsHoliday(const wxDateTime& dt) const;
  1332.     virtual size_t DoGetHolidaysInRange(const wxDateTime& dtStart,
  1333.                                         const wxDateTime& dtEnd,
  1334.                                         wxDateTimeArray& holidays) const;
  1335. };
  1336.  
  1337. // ============================================================================
  1338. // inline functions implementation
  1339. // ============================================================================
  1340.  
  1341. // don't include inline functions definitions when we're included from anything
  1342. // else than datetime.cpp in debug builds: this minimizes rebuilds if we change
  1343. // some inline function and the performance doesn't matter in the debug builds.
  1344.  
  1345. #if !defined(wxDATETIME_DONT_INLINE) || defined(wxDEFINE_TIME_CONSTANTS)
  1346.     #define INCLUDED_FROM_WX_DATETIME_H
  1347.         #include "wx/datetime.inl"
  1348.     #undef INCLUDED_FROM_WX_DATETIME_H
  1349. #endif
  1350.  
  1351. // if we defined it to be empty above, restore it now
  1352. #ifdef wxDATETIME_DONT_INLINE
  1353.     #undef inline
  1354. #endif
  1355.  
  1356. // ============================================================================
  1357. // binary operators
  1358. // ============================================================================
  1359.  
  1360. // ----------------------------------------------------------------------------
  1361. // wxDateTime operators
  1362. // ----------------------------------------------------------------------------
  1363.  
  1364. // arithmetics
  1365. // -----------
  1366.  
  1367. // no need to check for validity - the member functions we call will do it
  1368.  
  1369. inline wxDateTime WXDLLEXPORT operator+(const wxDateTime& dt,
  1370.                                         const wxTimeSpan& ts)
  1371. {
  1372.     return dt.Add(ts);
  1373. }
  1374.  
  1375. inline wxDateTime WXDLLEXPORT operator-(const wxDateTime& dt,
  1376.                                         const wxTimeSpan& ts)
  1377. {
  1378.     return dt.Subtract(ts);
  1379. }
  1380.  
  1381. inline wxDateTime WXDLLEXPORT operator+(const wxDateTime& dt,
  1382.                                         const wxDateSpan& ds)
  1383. {
  1384.     return dt.Add(ds);
  1385. }
  1386.  
  1387. inline wxDateTime WXDLLEXPORT operator-(const wxDateTime& dt,
  1388.                                         const wxDateSpan& ds)
  1389. {
  1390.     return dt.Subtract(ds);
  1391. }
  1392.  
  1393. inline wxTimeSpan WXDLLEXPORT operator-(const wxDateTime& dt1,
  1394.                                         const wxDateTime& dt2)
  1395. {
  1396.     return dt1.Subtract(dt2);
  1397. }
  1398.  
  1399. // comparison
  1400. // ----------
  1401.  
  1402. inline bool WXDLLEXPORT operator<(const wxDateTime& t1, const wxDateTime& t2)
  1403. {
  1404.     wxASSERT_MSG( t1.IsValid() && t2.IsValid(), _T("invalid wxDateTime") );
  1405.  
  1406.     return t1.GetValue() < t2.GetValue();
  1407. }
  1408.  
  1409. inline bool WXDLLEXPORT operator<=(const wxDateTime& t1, const wxDateTime& t2)
  1410. {
  1411.     wxASSERT_MSG( t1.IsValid() && t2.IsValid(), _T("invalid wxDateTime") );
  1412.  
  1413.     return t1.GetValue() <= t2.GetValue();
  1414. }
  1415.  
  1416. inline bool WXDLLEXPORT operator>(const wxDateTime& t1, const wxDateTime& t2)
  1417. {
  1418.     wxASSERT_MSG( t1.IsValid() && t2.IsValid(), _T("invalid wxDateTime") );
  1419.  
  1420.     return t1.GetValue() > t2.GetValue();
  1421. }
  1422.  
  1423. inline bool WXDLLEXPORT operator>=(const wxDateTime& t1, const wxDateTime& t2)
  1424. {
  1425.     wxASSERT_MSG( t1.IsValid() && t2.IsValid(), _T("invalid wxDateTime") );
  1426.  
  1427.     return t1.GetValue() >= t2.GetValue();
  1428. }
  1429.  
  1430. inline bool WXDLLEXPORT operator==(const wxDateTime& t1, const wxDateTime& t2)
  1431. {
  1432.     wxASSERT_MSG( t1.IsValid() && t2.IsValid(), _T("invalid wxDateTime") );
  1433.  
  1434.     return t1.GetValue() == t2.GetValue();
  1435. }
  1436.  
  1437. inline bool WXDLLEXPORT operator!=(const wxDateTime& t1, const wxDateTime& t2)
  1438. {
  1439.     wxASSERT_MSG( t1.IsValid() && t2.IsValid(), _T("invalid wxDateTime") );
  1440.  
  1441.     return t1.GetValue() != t2.GetValue();
  1442. }
  1443.  
  1444. // ----------------------------------------------------------------------------
  1445. // wxTimeSpan operators
  1446. // ----------------------------------------------------------------------------
  1447.  
  1448. // arithmetics
  1449. // -----------
  1450.  
  1451. inline wxTimeSpan WXDLLEXPORT operator+(const wxTimeSpan& ts1,
  1452.                                         const wxTimeSpan& ts2)
  1453. {
  1454.     return wxTimeSpan(ts1.GetValue() + ts2.GetValue());
  1455. }
  1456.  
  1457. inline wxTimeSpan WXDLLEXPORT operator-(const wxTimeSpan& ts1,
  1458.                                         const wxTimeSpan& ts2)
  1459. {
  1460.     return wxTimeSpan(ts1.GetValue() - ts2.GetValue());
  1461. }
  1462.  
  1463. inline wxTimeSpan WXDLLEXPORT operator*(const wxTimeSpan& ts, int n)
  1464. {
  1465.     return wxTimeSpan(ts).Multiply(n);
  1466. }
  1467.  
  1468. inline wxTimeSpan WXDLLEXPORT operator*(int n, const wxTimeSpan& ts)
  1469. {
  1470.     return wxTimeSpan(ts).Multiply(n);
  1471. }
  1472.  
  1473. // comparison
  1474. // ----------
  1475.  
  1476. inline bool WXDLLEXPORT operator<(const wxTimeSpan &t1, const wxTimeSpan &t2)
  1477. {
  1478.     return t1.GetValue() < t2.GetValue();
  1479. }
  1480.  
  1481. inline bool WXDLLEXPORT operator<=(const wxTimeSpan &t1, const wxTimeSpan &t2)
  1482. {
  1483.     return t1.GetValue() <= t2.GetValue();
  1484. }
  1485.  
  1486. inline bool WXDLLEXPORT operator>(const wxTimeSpan &t1, const wxTimeSpan &t2)
  1487. {
  1488.     return t1.GetValue() > t2.GetValue();
  1489. }
  1490.  
  1491. inline bool WXDLLEXPORT operator>=(const wxTimeSpan &t1, const wxTimeSpan &t2)
  1492. {
  1493.     return t1.GetValue() >= t2.GetValue();
  1494. }
  1495.  
  1496. inline bool WXDLLEXPORT operator==(const wxTimeSpan &t1, const wxTimeSpan &t2)
  1497. {
  1498.     return t1.GetValue() == t2.GetValue();
  1499. }
  1500.  
  1501. inline bool WXDLLEXPORT operator!=(const wxTimeSpan &t1, const wxTimeSpan &t2)
  1502. {
  1503.     return t1.GetValue() != t2.GetValue();
  1504. }
  1505.  
  1506. // ----------------------------------------------------------------------------
  1507. // wxDateSpan
  1508. // ----------------------------------------------------------------------------
  1509.  
  1510. // arithmetics
  1511. // -----------
  1512.  
  1513. inline WXDLLEXPORT wxDateSpan operator+(const wxDateSpan& ds1,
  1514.                                         const wxDateSpan& ds2)
  1515. {
  1516.     return wxDateSpan(ds1.GetYears() + ds2.GetYears(),
  1517.                       ds1.GetMonths() + ds2.GetMonths(),
  1518.                       ds1.GetWeeks() + ds2.GetWeeks(),
  1519.                       ds1.GetDays() + ds2.GetDays());
  1520. }
  1521.  
  1522. inline WXDLLEXPORT wxDateSpan operator-(const wxDateSpan& ds1,
  1523.                                         const wxDateSpan& ds2)
  1524. {
  1525.     return wxDateSpan(ds1.GetYears() - ds2.GetYears(),
  1526.                       ds1.GetMonths() - ds2.GetMonths(),
  1527.                       ds1.GetWeeks() - ds2.GetWeeks(),
  1528.                       ds1.GetDays() - ds2.GetDays());
  1529. }
  1530.  
  1531. inline WXDLLEXPORT wxDateSpan operator*(const wxDateSpan& ds, int n)
  1532. {
  1533.     return wxDateSpan(ds).Multiply(n);
  1534. }
  1535.  
  1536. inline WXDLLEXPORT wxDateSpan operator*(int n, const wxDateSpan& ds)
  1537. {
  1538.     return wxDateSpan(ds).Multiply(n);
  1539. }
  1540.  
  1541. // ============================================================================
  1542. // other helper functions
  1543. // ============================================================================
  1544.  
  1545. // ----------------------------------------------------------------------------
  1546. // iteration helpers: can be used to write a for loop over enum variable like
  1547. // this:
  1548. //  for ( m = wxDateTime::Jan; m < wxDateTime::Inv_Month; wxNextMonth(m) )
  1549. // ----------------------------------------------------------------------------
  1550.  
  1551. inline WXDLLEXPORT void wxNextMonth(wxDateTime::Month& m)
  1552. {
  1553.     wxASSERT_MSG( m < wxDateTime::Inv_Month, _T("invalid month") );
  1554.  
  1555.     // no wrapping or the for loop above would never end!
  1556.     m = (wxDateTime::Month)(m + 1);
  1557. }
  1558.  
  1559. inline WXDLLEXPORT void wxPrevMonth(wxDateTime::Month& m)
  1560. {
  1561.     wxASSERT_MSG( m < wxDateTime::Inv_Month, _T("invalid month") );
  1562.  
  1563.     m = m == wxDateTime::Jan ? wxDateTime::Inv_Month
  1564.                              : (wxDateTime::Month)(m - 1);
  1565. }
  1566.  
  1567. inline WXDLLEXPORT void wxNextWDay(wxDateTime::WeekDay& wd)
  1568. {
  1569.     wxASSERT_MSG( wd < wxDateTime::Inv_WeekDay, _T("invalid week day") );
  1570.  
  1571.     // no wrapping or the for loop above would never end!
  1572.     wd = (wxDateTime::WeekDay)(wd + 1);
  1573. }
  1574.  
  1575. inline WXDLLEXPORT void wxPrevWDay(wxDateTime::WeekDay& wd)
  1576. {
  1577.     wxASSERT_MSG( wd < wxDateTime::Inv_WeekDay, _T("invalid week day") );
  1578.  
  1579.     wd = wd == wxDateTime::Sun ? wxDateTime::Inv_WeekDay
  1580.                                : (wxDateTime::WeekDay)(wd - 1);
  1581. }
  1582.  
  1583. #endif // wxUSE_DATETIME
  1584.  
  1585. #endif // _WX_DATETIME_H
  1586.