Absolute Times |

The notion of date and time can be represented with an oriented axis with values in the past on the left and values in the future on the right. Date and time are absolute values which can be compared using a total order relationship based on this time axis representation. Therefore class `DT_ABSOLUTE_TIME` is a descendant of `COMPARABLE`. It also inherits from `HASHABLE` in order to allow dates and times to be used as keys in hash tables. There are three kinds of absolute times. Times, instances of class `DT_TIME`, are temporal values in a day such as 14:30:21. Dates, instances of class `DT_DATE`, are values in the Gregorian calendar such as 21 April 2000. And date/times, instances of class `DT_DATE_TIME`, are a combination of date and time such as 25 December 2000 at 10:35:10.

## Time

Time objects are made up of `hour`, `minute` and `second`. These features follow the normal conventions: seconds are within the range 0 to 59, minutes are between 0 and 59, and hours are between 0 and 23. Precision up to the millisecond is also available thanks to the feature `millisecond`. These four fields of class `DT_TIME` can be set individually or together with the following routines: `set_hour`, `set_minute`, `set_second`, `set_millisecond`, `set_hour_minute_second` and `set_precise_hour_minute_second`. The `precise` prefix in feature names implies that the `millisecond` field is involved. These setting routines are equipped with preconditions to ensure that the fields of the time objects are still within their corresponding ranges. Two other routines, `second_count` and `millisecond_count`, return the number of seconds and milliseconds elapsed since midnight. Time objects can be set using these values with `set_second_count` and `set_millisecond_count`.

Four creation procedures are provided. `make` requires three arguments to set the hour, minute and second, whereas `make_precise` needs an extra argument to set the millisecond precision. On the other hand `make_from_second_count` and `make_from_millisecond_count` create a new time object based on its number of seconds or milliseconds since midnight.

It is possible to add or subtract hours, minutes, seconds and/or milliseconds to a time using features `add_hours`, `add_minutes`, `add_seconds`, `add_milliseconds`, `add_hours_minutes_seconds` and `add_precise_hours_minutes_seconds` with positive or negative arguments. For example adding 25 minutes to the time 14:44:10 yields 15:09:10. However since the notion of time is relative to a day in a cyclic representation, times are always bounded within 00:00:00 and 23:59:59. Therefore adding 1 second to the time 23:59:59 yields 00:00:00 also known as midnight. Likewise adding -6 hours to 02:35:21 yields 20:35:21. Time durations can also be added to time objects with features `add_duration` and `add_time_duration`, or their equivalent infix operators `infix``` `"+"` and `infix``` `"&t"` which return a new object at each call and do not alter the current time object. In short, a time duration is an object which contains among other things the number of hours, minutes, seconds and milliseconds between two times. For example the duration between the times 10:23:45 and 14:35:50 is 4 hours, 12 minutes and 5 seconds. In order to get the duration between two times, one can call the routines `duration` and `time_duration` or their equivalent infix operator `infix``` `"-"`. This operator subtract the fields of the times field by field. For example the subtraction of the times 20:05:14 and 13:24:00 yields 7 hours, -19 minutes and 14 seconds. However it is common practice to use canonical durations, in other words durations where all fields have the same sign and where the absolute value of the number of minutes is between 0 and 59 and absolute value of the number of seconds is between 0 and 59. In such a case, one should call the routine `canonical_duration` instead of the `duration` routine above. The subtraction of the two times 20:05:14 and 13:24:00 now yields the canonical duration 6 hours, 41 minutes and 14 seconds.

Constants related to time are available in class `DT_GREGORIAN_CALENDAR`. `Seconds_in_minute`, `Seconds_in_hour` and `Seconds_in_day` return the number of seconds in a minute, hour or day. `Milliseconds_in_day` returns the number of milliseconds in a day. `Minutes_in_hour` returns the number of minutes in an hour. `Hours_in_day` returns the number of hours in a day.

## Date

Date objects are made up of `year`, `month` and `day`. Because of the irregularities in the Gregorian calendar, the months in a year don't have the same number of days. For example days in January are in the range 1 to 31 whereas in Februay there are either 28 or 29 days depending on whether the year is a leap year or not. One can query the number of days for a given month with the routine `days_in_month` from class `DT_GREGORIAN_CALENDAR`. Likewise one can check whether a given year is a leap year or not with the routine `leap_year`. Two similar routines, `days_in_current_month` and `is_leap_year`, are also available in class `DT_DATE` in order to inspect the month and year of a given date object. The three fields of class `DT_DATE` can be set individually or together with the following routines: `set_year`, `set_month`, `set_day` and `set_year_month_day`. Of course these routines are equipped with preconditions to ensure that the date stays consistent. For example the month has to be between 1 and 12, and the day has to fit in the resulting month. It is indeed impossible given the date 31 March 2000 to set the month to June since there are only 30 days in June.

Two creation procedures are provided. `make` requires three arguments to set the year, month and day. On the other hand `make_from_day_count` takes only one argument corresponding to the number of days since epoch (1 January 1970). It is indeed common practice for operating systems to provide the current date of the system by returning the number of days or seconds elapsed since January 1rst 1970 at midnight. Two related routines in class `DT_DATE` are `day_count` which returns the number of days since 1 January 1970, and `set_day_count` which has a similar effect as the creation procedure `make_from_day_count`. For example, the `day_count` for 31 January 1970 will be 30 whereas the `day_count` for 31 December 1969 will have the negative value -1. Two other useful features are `week_day` which returns the day in the current week of a date object within the range 1 (i.e. Sunday) to 7 (i.e. Saturday), and `year_day` which returns the day of a date object in its current year. For example for 1 January 2000, `year_day` yields 1 whereas for 31 December 1999 the result is 365.

It is possible to add or subtract years, months and/or days to a date using features `add_years`, `add_months`, `add_days` and `add_years_months_days` with positive or negative arguments. For example adding 8 months to the date 3 August 1996 yields 3 April 1997. Note that because of the irregularities in the Gregorian calendar, it has been decided to truncate the day when the resulting date is invalid. For instance adding one year to 29 February 2000 yields 28 February 2001, and adding one month to 31 March 2000 yields 30 April 2000. Similarly, adding 5 days and 1 month is not always the same as adding 1 month and 5 days. For example starting with 28 March 2000, the first operation yields 2 May 2000 whereas the second yields 3 May 2000. Therefore the convention chosen for `add_years_months_days` is to add the years first, then the months, truncate the day if necessary and finally add the days. Date durations can also be added to date objects with the features `add_duration` and `add_date_duration`, or their equivalent infix operators `infix``` `"+"` and `infix``` `"&d"` which return a new object at each call and do not alter the current date object. In short, a date duration is an object which contains among other things the number of years, months and days between two dates. For example the duration between the dates 5 April 2000 and 15 July 2002 is 2 years, 3 months and 10 days. In order to get the duration between two dates, one can call the routines `duration` and `date_duration` or their equivalent infix operator `infix``` `"-"`. As we will see later, a date duration is generally not deterministic. For example adding one month to 15 April 2000 is equivalent to adding 30 days, whereas adding 1 month to 15 May 2000 is equivalent to adding 31 days. Therefore a date duration is said to be definite when it is expressed only in terms of days, leaving the year and month parts empty. The result of the three duration routines above is definite. For example the `duration` between 2 May 2000 and 3 July 2000 yields 62 days. However it is common practice to use canonical durations, in other words durations where all fields have the same sign and where the absolute value of the number of days is the smallest possible one and the absolute value of the number of months is between 0 and 11. In such a case, one should call the routine `canonical_duration` instead of the `duration` routine above. The subtraction of the two dates 3 July 2000 and 2 May 2000 now yields the canonical duration 2 months and 1 day. But again, because of irregularities in the Gregorian calendar, this might become tricky. For example the canonical duration between 31 May 2000 and 30 June 2000 is 1 month and not 30 days! Indeed, if we follow the definition of canonical duration, 0 day is smaller than 30 days and adding 1 month to 31 May 2000 yields the expected date thanks to the truncation of the day which occurs in the addition routines.

Constants related to date are available in class `DT_GREGORIAN_CALENDAR`. `Months_in_year` returns the number of months in a year. `Days_in_year` returns the number of days in a non-leap year whereas `Days_in_leap_year` returns the number of days in a leap year. The months of the year are also given symbolic names: `January`, `February`, `March`, `April`, `May`, `June`, `July`, `August`, `September`, `October`, `November`, `December`. `Days_in_week` returns the number of days in a week and days of the week are given symbolic names: `Sunday`, `Monday`, `Tuesday`, `Wednesday`, `Thursday`, `Friday`, `Saturday`. The next and previous day of a given day in the week can also be found by calling features `next_day` and `previous_day`.

## Date Time

Date/time objects are a combination of a date and a time relative to that date. They are made up of `year`, `month`, `day`, `hour`, `minute`, `second` and `millisecond`. Class `DT_DATE_TIME` is equipped with the same setting routines as `DT_DATE` and `DT_TIME`. In addition to the features inherited from these two classes, one can also get or set the date and the time parts of a date/time object with routines `date`, `time`, `set_date` and `set_time`.

Five creation procedures are provided. `make` requires six arguments to set the year, month, day, hour, minute and second, whereas `make_precise` needs an extra argument to set the millisecond precision. On the other hand `make_from_date_time` and `make_from_date` create a new date/time object based on its date and time parts. `make_from_epoch` creates a new date time from the number of seconds since epoch (1 Jan 1970 at 00:00:00). This routine is useful to convert the time stamp of a file (see feature `time_stamp` from class `KI_FILE`) into a human readable format.

Contrary to time, date time objects do not have a cyclic representation. When the time part reaches 23:59:59, the date part swiches to the next day. For example adding 2 hours to 30 April 2000 23:30:00 yields 1 May 2000 01:30:00. Otherwise it is possible to add and subtract years, months, days, hours, minutes, seconds and/or milliseconds to a date/time using the same features as in `DT_DATE` and `DT_TIME`. One can also add date durations, time durations and date/time durations with the features `add_date_duration`, `add_time_duration` and `add_duration` or their infix operator counterparts `infix``` `"&d"`, `infix``` `"&t"``` and `infix``` `"+"`. In order to get the duration between two date/times, one can call the routines `duration` or its equivalent infix operator `infix``` `"-"`. As for date objects, these routines return a definite duration. In orther words the year and month parts are null and the hour, minute and second parts may have arbitrary values. One should call `canonical_duration` instead of the `duration` routine above in order to get a duration where the date and time parts are canonical. One last difference with `DT_DATE` and `DT_TIME` is that `date_duration` only returns the date part of `duration` whereas `time_duration` only returns its time part.