class ref name: time_o
category-group: time
layer: 2
header file: z_time.h
libraries: libz00.lib libz01.lib libz02.lib

synopsis.
basic time and date operations. Dates used by this object are based on the currently Earth-based calendar - the Gregorian calendar, started on February 24, 1582. What most humans call a "date" is referred to as "time". Thus a "time object" includes year, day, month, hour, minute, second, and microsecond.

Many operations can be done with this class, including:

name description
is_leapyear() tells if the time object is in a leap year
numdays_inmonth() the # of days in the current month
<=, >=, ==, <, > compare the object's time to another time_o; return one of -1, 0, 1
now() set the object to the current date + time
incr_month(), decr_month() set the month to the next[/previous] month. The year will be adjusted if a boundary is crossed. Also, the day might be adjusted.
[support routines] A large set of time-related subroutines:
  • is_z_now_leap_year(I) - is the current year a leap year?
  • z_day_of_week() - DOW for inputted month/day/year
  • z_firstday_ofyear() DOW of Jan 1 for a given year
  • z_NumSeconds_InDay() - a collection of "# [units] in [units]" type subroutines

description.
Time is stored in an internal data structure called "datestuff", which maintains the earthly units century, year, month, day, hour, minute, second, millisecond, and microsecond. The latter two are mutually exclusive: setting microseconds will wipe out (set to 0) the milliseconds, and vice-versa.

Setting a time object's time to the current time (including date) is done by calling now():

time_o t;
t.now();

All time comparisons using operators are precise (down to the microsecond). In the example below, 't1' is "before" 't2':

time_o t1, t2;
t1.set_date (6, 30, 2011);
t2 = t1;
t1.set_time (12, 30, 05, 0);    // Jun 6, 2012 12:30:05pm
t2.set_time (16, 45, 59, 0);    // Jun 6, 2012  4:45:59pm
You can use the 'cmp()' member function to compare just the date part (or to whatever resolution is desired):
time_o t1, t2, t3;
t1.set_date("12/31/2007 08:15");        // t1: 12/31/2007 8:15am
t2.set_date (1, 4, 2008);               // t2: 01/04/2008
t2.set_time (9, 14);                    // t2: 01/04/2008 09:14am
t3.set_date (12, 31, 2007);             // t3: same "date" as t1
t3.set_time ("08:52");                  // t3: 12/31/2007 8:52am
int x = t1.cmp(t2, zTU_Days);           // x = -1
int y = t1.cmp(t3, zTU_Days);           // x = 0 (although "t3 > t1")
int z = t1.cmp(t3, zTU_Hours);          // x = 0 (again-up to the hour)

most "mode" flags are inherited from a singleton, "master" time object. You can set some of these modes: z_Default_to_Now, z_Auto_Set, and z_Allow_Throw.

  • z_Default_to_Now: when the time object is reset, it sets the time to the current time. If this flag is not set, the time value will be "not set".
  • z_Auto_Set: the idea of this flag is to set the time to the current time, if it is not set and a function is called where it is hard to determine if it is unset due to the return code (such as is_leapyear()).
  • z_Allow_Throw: if this is set, in functions that cannot simply return an error code, such as constructors and comparing 2 time objects, if this flag is set, a "throw" will be done (with an int value of -1).

member functions (primary)

time_o()
SIGNATURE: time_o ()
SYNOPSIS:
Creates an empty instance of the time class. The object's time is not set to anything, so it cannot be used for comparisons or getting a time/date.
 

destructor
SIGNATURE: ~time_o ()
SYNOPSIS: virtual destructor. The instance, including its settings, is reset.
 

operator = (time_o)
SIGNATURE: time_o &operator = (const time_o &rhs)
SYNOPSIS: copies exactly the [Right-Hand-Side] object "rhs". the object's time is set to that of "rhs".
RETURNS: a reference to the current object.
 

time_o(time_o)
SIGNATURE: time_o (const time_o &rhs)
SYNOPSIS: creates a a new time object; the time object's data is an exact image of the copied object, "rhs".
 

time_o(<args>)
SIGNATURE: time_o (int month, int day, int year)
SYNOPSIS:
constructor: the object's date is set to the month, day, and year as given by the input arguments with the same name. If any of the input parameters are invalid (eg, negative, out of range, or resulting in a bad time or date), the time-date will not be set. In the latter case (a combination of invalid parameters, eg., February 31), the object state is set to "time_o::z_Error".
PARAMETERS

  • month: the month part of the date to set the time to. must be in the range [1..12]. Use 1 for the first month (January).
  • day: the day to set the time-date object to. Use 1 for the first day, eg "time_o s(6, 1, 2010);" will create an time object set to June 1st of 2010.
  • year: The year to set the object to. The value is the same as the value based on the Gregorian calendar. Use the full number, eg, "2012" not "12" for the year 2012.
 

is_ok()
SIGNATURE: boolean is_ok () const
SYNOPSIS: returns TRUE if the object's date is set to a valid date.
RETURNS:
TRUE: object time-date is set to a valid time;
FALSE: otherwise.
 

is_date_set()
SIGNATURE: boolean is_date_set () const
SYNOPSIS: same as "is_ok()" (see which for more details)
 

is_date_valid()
SIGNATURE: boolean is_date_valid () const
SYNOPSIS:
tells if the object is set to a valid date. if the time has not been set, this returns FALSE. This member function checks only the date (month, day, year) part of the time.
RETURNS:
TRUE: object time-date has a valid date;
FALSE: otherwise.
 

is_time_valid()
SIGNATURE: boolean is_time_valid () const
SYNOPSIS:
tells if the object is set to a valid date. if the time has not been set, this returns FALSE. This member function checks only the time (hour, minute, second) part of the time.
RETURNS:
TRUE: object time-date has a valid time;
FALSE: otherwise.
 

is_leapyear()
SIGNATURE: boolean is_leapyear () const
SYNOPSIS:
Tells (returns TRUE) if the time object's year is a leap year. If the object's time-date is not set, and the object is in "automatic" mode (time_o::z_Auto_Set is set ON). Modes can be set or unset with member function set_mode().
RETURNS:
TRUE: object's time-date is in a leap year;
FALSE: otherwise.
 

is_samedate()
SIGNATURE: boolean is_samedate (const time_o &rhs) const
SYNOPSIS:
tells if the object has the same date (only; not time) as the time object "rhs". If the object's time is not set, object goes into "error mode" (time_o::z_Error flag is set).
PARAMETERS

  • rhs: time object to compare to
  • RETURNS:
    TRUE: object's date is same as that of "rhs"
    FALSE: otherwise.
     

    numdays_inmonth()
    SIGNATURE: count_t numdays_inmonth (int *pi = NULL) const
    SYNOPSIS:
    This member function exists for the timespan object. If the time is set, this returns the number of days for the object's month.
    PARAMETERS

  • pi: [output] error indicator variable. If set to zErr_NotInitialized, this indicates that the object's time is not set, or it is in an error state.
  • RETURNS:
    [n >= 0]: number of days in month for this object's time-date.
    -1: error
     

    months_diff()
    SIGNATURE: count_t months_diff (const time_o &rhs) const
    SYNOPSIS:
    returns the number of months between the object and object "rhs". If this object is set to Feb 2, 2012 and "rhs" is set to July 9, 2011, this function returns 7. The answer is always a positive number (unless there is an error, in which case -1 is returned).
    PARAMETERS

  • rhs: the time object to compare to.
  • RETURNS:
    [n >= 0]: # of months difference betweeen objecs
    -1: this object or rhs object is not set to a valid time-date.
     

    dow()
    SIGNATURE: int time_o::dow (int meth = 0, int *pi = NULL) const
    SYNOPSIS:
    returns the number representing the day of the week for the time object, if the date has been set. If not, -1 is returned. The value for Sunday is 0, Monday is 1, and so on:

      0 = Sunday
      1 = Monday
      2 = Tuesday
      3 = Wednesday
      4 = Thursday
      5 = Friday
      6 = Saturday
    

    PARAMETERS
    • meth: various techniques can be used to calculate the value. This parameter is not meant to deviate from the default value (0). It can be set to either 0, 1, or 2. The results are [should be] the same for all cases.
    • pi: error indicator variable. values:
      0: success
      zErr_NotInitialized: object not initialized
      zErr_OutofBounds: century not in 18..21
      zErr_Index_OutofBounds: illegal value of 'meth'
    DESCRIPTION:
    The methods for calculating the day of the week are in the public domain. All are based on the Gregorian calendar. The algorithm for meth = 0 is described as "Schwerdtfeger's variation of Kraitchik's algorithm". For method = 1, this is a version of Tondering's algorithm, created by Tomohiko Sakamoto". For method = 2, it is Zeller's algorithm (which is very similar to the Gaussian algorithm).
    RETURNS:
    [n >= 0]: the day of the week for the date of the object
    -1: error, object's date has not been initialized
     

    operator <=()
    SIGNATURE: int operator <= (const time_o &rhs) const
    SYNOPSIS:
    compares object to "rhs". Both objects must be set to a valid time-date. If not, both are set to error states, and if "throw" mode is permitted, the function throws a -1.
    RETURNS:
    1: object is on or before the time set in "rhs".
    FALSE: otherwise.
     

    operator >=()
    SIGNATURE: int operator >= (const time_o &rhs) const
    SYNOPSIS:
    compares object to "rhs". Both objects must be set to a valid time-date. If not, both are set to error states, and if "throw" mode is permitted, the function throws a -1.
    RETURNS:
    1: object is on or after the time set in "rhs".
    FALSE: otherwise.
     

    operator ==()
    SIGNATURE: int operator == (const time_o &that) const
    SYNOPSIS:
    compares object to "that" and tests for equality. Both objectS must be set to a valid time-date. If not, both are set to error states, and if "throw" mode is permitted, the function throws a -1. Note that all time comparisons are precise (down to the second).
    RETURNS:
    1: object's time is the same as the time set in "that".
    FALSE: otherwise.
     

    operator <()
    SIGNATURE: int operator < (const time_o &that) const
    SYNOPSIS: compares object to "that" and tests if this object is "before" 'that' object.
    RETURNS:
    1: object's time is before the time as set in "that".
    FALSE: otherwise.
     

    operator >()
    SIGNATURE: int operator > (const time_o &that) const
    SYNOPSIS: compares object to "rhs" and tests if this object is "after" 'that' object.
    RETURNS:
    1: object's time is after the time set in "that".
    FALSE: otherwise.
     

    century()
    SIGNATURE: int century () const
    SYNOPSIS:
    returns the century for the object (if the time-date is set). If the object's year is 1950, '19' is returned. Note that this does not mean the 19th century, as the verbal convention is different from the century number.
    RETURNS:
    [n >= 0]: the object's century
    -1: time not set
     

    year()
    SIGNATURE: int year () const
    SYNOPSIS: returns the year for the object's time value (if set).
    RETURNS:
    [n >= 0]: the object's year
    -1: time not set
     

    month()
    SIGNATURE: int month () const
    SYNOPSIS: returns the month for the object's time value (if set).
    RETURNS:
    [n >= 0]: the object's year
    -1: time not set
     

    day()
    SIGNATURE: int day () const
    SYNOPSIS: returns the day for the object's time value (if set).
    RETURNS:
    [n >= 0]: the object's day
    -1: time not set
     

    hour()
    SIGNATURE: int hour () const
    SYNOPSIS: returns the hour for the object's time value (if set).
    RETURNS:
    [n >= 0]: the object's hours
    -1: time not set
     

    minute()
    SIGNATURE: int minute () const
    SYNOPSIS: returns the minute for the object's time value (if set).
    RETURNS:
    [n >= 0]: the object's minutes
    -1: time not set
     

    second()
    SIGNATURE: int second () const
    SYNOPSIS: returns the seconds for the object's time value (if set).
    RETURNS:
    [n >= 0]: the object's seconds
    -1: time not set
     

    microsecond()
    SIGNATURE: u_long microsecond () const
    SYNOPSIS:
    returns the microseconds for the object's time value (if set). Note that whether this value can be set is highly dependent on the underlying operating system. If the OS cannot (or will not) supply this information, this value is always 0.
    RETURNS:
    [n >= 0]: the object's microseconds
    -1: time not set
     

    set_mode()
    SIGNATURE: int set_mode (time_mode x, boolean is_on = TRUE)
    SYNOPSIS:
    sets a mode (internal flag) for the object. Current valid modes are: z_Default_to_Now, z_Auto_Set, z_Manual_Set, and z_Allow_Throw. "z_Allow_Throw" is being phased out; "z_Manual_Set" is the inverse of "z_Auto_Set", so really only "z_Default_to_Now" and "z_Auto_Set" are valid mode-flags.
    PARAMETERS

    • x: mode to set/unset
    • is_on: if TRUE, the mode is set ON; if FALSE, it is set OFF.
    RETURNS:
    0: success
    -1: illegal mode given (or possibly, but unlikely, that an error ocurred).
     

    reset()
    SIGNATURE: int reset ()
    SYNOPSIS:
    resets the object to at-construction state. if the object is in 'z_Default_to_Now' mode, the object will be set to the current time. otherwise, the time will be unset ('z_Is_Set' will be unset).
    RETURNS: 0
     

    now()
    SIGNATURE: int now ()
    SYNOPSIS: sets the object's time to the current time. Both date part and time part is set.
    RETURNS: 0
     

    set_date()
    SIGNATURE: int set_date (int month, int day, int year)
    SYNOPSIS:
    sets the object's date-part [only]. The month, day, and year is set to the values corresponding to the input parameters with the same names. The resultant date must be a valid date. If any of the input parameters are invalid (eg, negative or out of range), the date will not be set in the object.
    PARAMETERS

    • month: the month part of the date to set the time to. must be in the range [1..12]. Use 1 for the first month (January).
    • day: the day to set the time-date object to. Use 1 for the first day, eg "stime_o s(6, 1, 2010);" will create an stime object set to June 1st of 2010.
    • year: The year to set the object to. The value is the same as the value based on the Gregorian calendar. Use the full number, eg, "2012" not "12" for the year 2012.
    RETURNS:
    0: the object's date was successfully set
    -1: error (most likely the date was invalid)
     

    set_time()
    SIGNATURE: int set_time (int hour, int minute, int second, u_long msec = 0)
    SYNOPSIS:
    sets the time-part of the time-date [only], to the values of the input parameters. All values must be valid, and the aggregate constitute a valid time. Hours are based on a 24-hour clock.
    PARAMETERS

    • hour: the hour component. Midnight = 0; 11pm = 23.
    • minute: the minutes component of the [day's] time. values are in [0..59].
    • second: the seconds component of the [day's] time. values are in [0..59].
    • msec: the microseconds to set to. The value range is [0 .. 1,000,000]
    RETURNS:
    0: the object's time was successfully set
    -1: error (most likely the time was invalid)
     

    set_year()
    SIGNATURE: int set_year (int year)
    SYNOPSIS:
    sets the year for the current time object. This also sets the 'century' variable internally. Member functions in the group "set_[xxx]()" where [xxx] is a single unit of time measure are intended to be used mainly internally. None of the other time units are affected. Thus, if the time-date is currently February 9, 1971, and this function is called with year value 1999, the new time is set to February 9, 1999.
    RETURNS:
    0: the object's year was successfully set
    -1: error (most likely the year was invalid)
     

    set_month()
    SIGNATURE: int set_month (int mo)
    SYNOPSIS: sets the month for the current time object. This function is analogous to "set_year()" (which see for more details).
    PARAMETERS

  • mo: the month to set the date to. Valid values are from 1 (January) to 12.
  • RETURNS:
    0: the object's month was successfully set
    -1: error (most likely the month value was invalid)
     

    set_day()
    SIGNATURE: int set_day (int day)
    SYNOPSIS:
    sets the month for the current time object. This function is analogous to "set_year()" (see it for more details). Note that this function in particular of the "set_[xxx]()" group can make the date invalid. For example, if the object's date is Feb. 2, 2012, and set_day(31) is called, the resultant date ("Feb. 31, 2012") would not be valid. In such cases, the object's date is unaffected and -1 is returned.
    RETURNS:
    0: the object's day was successfully set
    -1: error (most likely the day value was invalid)
     

    set_hour()
    SIGNATURE: int set_hour (int hour)
    SYNOPSIS: sets the hour compoent of the time-date. All other time-date units are unaffected.
    PARAMETERS

  • hour: the new hour to set to. Must be in 0..23
  • RETURNS:
    0: the object's day was successfully set
    -1: error (most likely the day value was invalid)
     

    set_minute()
    SIGNATURE: int set_minute (int new_min)
    SYNOPSIS: sets the minutes compoent of the time-date. All other time-date units are unaffected.
    PARAMETERS

  • new_min: the new minutes to set to. Must be in 0..59
  • RETURNS:
    0: the object's minutes were successfully set
    -1: error (most likely the minute value was invalid)
     

    set_second()
    SIGNATURE: int set_second (int sec)
    SYNOPSIS: sets the seconds compoent of the time-date. All other time-date units are unaffected.
    PARAMETERS

  • sec: the new seconds to set to. Must be in 0..59
  • RETURNS:
    0: the object's seconds were successfully set
    -1: error (most likely the seconds value was invalid)
     

    set_microsecond()
    SIGNATURE: int set_microsecond (u_long msec)
    SYNOPSIS:
    sets the microseconds component of the time-date. All other time-date units are unaffected.
    example:

    time_o t;
    t.set_date (3, 5, 2000);
    t.set_hour (1);
    t.set_second (55);
    t.set_microsecond (120000);
    
    Here, the time-date is March 5, 2000, at 1:00am, plus 55.12 seconds.
    PARAMETERS
  • msec: value of microseconds; valid range is 0 .. 1 million
  • RETURNS:
    0: the object's microseconds were successfully set
    -1: error (most likely the microseconds value was invalid)
     

    incr_month()
    SIGNATURE: int incr_month ()
    SYNOPSIS:
    "increments" the object's month value by 1, that is, moves the month forward to the next month. The time-date must be set in order for this function to succeed. The year value is automatically rolled over for December.
    RETURNS: 0
     

    decr_month()
    SIGNATURE: int decr_month ()
    SYNOPSIS:
    decrements the object's month value by 1. The year value is automatically adjusted for January:

    time_o t;
    t.set_date(1, 6, 2000);
    t.decr_month();         // the new date is Dec 6, 1999
    
    Note that the time-date must be set in order for this function to affect the object.
    RETURNS: 0
     

    operator ++()
    SIGNATURE: int operator ++ (int)
    SYNOPSIS:
    [postfix] date increment. One day is added to the object's current date. All higher time units (month, year) are adjusted if necessary, such as setting the date to the first of the next month, if the current date is at the last day of the month.
    This function will fail if the object date is not set and valid.
    RETURNS:
    0: the object's day was successfully incremented
    -1: error (most likely the object's time-date has not been set)
     

    operator --()
    SIGNATURE: int operator -- (int)
    SYNOPSIS:
    [postfix] date decrement. One day is subtracted from the object's current date. All higher time units (month, year) are adjusted as necessary.
    This function will fail if the object date is not set and valid.
    RETURNS:
    0: the object's day was successfully decremented
    -1: error (most likely the object's time-date has not been set)
     

    operator ++()
    SIGNATURE: int operator ++ ()
    SYNOPSIS:
    date increment. 1 is added to the object's current date. All higher time units (month, year) are adjusted if necessary.
    RETURNS:
    0: the object's day was successfully incremented
    -1: error (most likely the object's time-date has not been set)
     

    operator --()
    SIGNATURE: int operator -- ()
    SYNOPSIS:
    date decrement. 1 is subtracted from the object's current date. All higher time units (month, year) are adjusted if necessary.
    RETURNS:
    0: the object's day was successfully decremented
    -1: error (most likely the object's time-date has not been set)
     

    check_ifvalid()
    SIGNATURE: void check_ifvalid (int *pie)
    SYNOPSIS:
    This function checks the time and date stored internally and updates the internal state. Sets / unsets the "z_Is_Set" flag. This is used by subclasses, to update the state. It can be called at any time to do a self-check.
    PARAMETERS

  • pie: error indicator variable. This output parameter can be used to determine the current 'is-set' state. values:
    0: object time and date is set;
    1: 'date' part is not set;
    2: 'time of day' part not set
    3: both 'date' and 'time of day' parts not set.
  •  

    examples.
    Here is a motley assortment of time_o function calls and usage of support routines:

    #include "z_time.h"
    
    int main (int argc, char *argv[])
    {
        time_o t;
        t.set ("Jan 17, 1981 14:01");               // 01/17/1981 02:01pm
        t++;                                        // 01/18/1981 02:01pm
        t.incr_month();                             // 02/18/1981 02:01pm
        t.set_day(1);                               // 02/01/1981 02:01pm
        t.set_time(8, 15);                          // 02/01/1981 08:15am
        t--;                                        // 01/31/1981 02:01pm
        t-= 2;                                      // 01/29/1981 02:01pm
        t += 4;                                     // 02/02/1981 02:01pm
    
        if (is_leapyear (t.year()) == TRUE)
            printf ("current lear is a leap year.\n");
    
        int x = z_day_of_week (t.month(), t.day(), t.year());
        printf ("current day: %s\n", z_DOW_to_str(x));
    
        x = z_firstday_ofyear (t.year());
        printf ("current: 1st day of the year is: %s\n", z_DOW_to_str(x));
        return 0;
    }
    

    history.

    ??? 05/16/2002: added function copy needed for timespan
    ??? 04/07/1987: time class started
    ??? 04/21/1987: 6PM - finished
    ??? 07/04/1988: third_friday(), iday_of_week(), etc can be cleaned up
    ??? 07/05/1988: gdate_t changed from u_long to float. no time limit
    ??? 11/11/1988: bit operators added for "is_holiday()"
    ??? 01/04/1989: checked for incongruencies in gdate_t (which is DOUBLE!)
    ??? 12/08/1990: c++ syntax conversion: gdate_t -> DATE_o classes
    ??? 08/09/1991: reworked .h file: function names and order
    ??? 08/11/1991: major cleanup; consistency and standardization
    ??? 08/18/1991: broke up formatting -> separate object in another file
    ??? 07/01/1995: phased out date-fmt object; canonical format
    ??? 12/04/1995: added microsecond resolution (for rng class)
    ??? 07/05/1996: took out the check "if (tp.tv_sec != d.second)"
    ??? 07/11/1997: created rep. for the end of time (as per nostradamus)
    ??? 06/17/1999: "time_o::now()" working on MS visual c++, using MFC
    ??? 05/16/2002: minor changes to fix timespan {--AG}
    Thu 05/30/2002: new #define naming conventions ("zos_", "zcc_")