-----------------------------------------------------------------------------
--                                                                         --
--  DateTime.e - Routines for handling Date and Time - (c) 2001 CyrekSoft  --
--                                                                         --
-----------------------------------------------------------------------------

                              A. Introduction

 This document contains information on and how to use the DateTime library.
 The sections below follow the layout of the source code which in turn is
 laid out in a logical way.

 Everything in this library (excepting the machine.e segment) is 100%
 original and not borrowed from any other source. The author spent quite a
 while researching to come up with the julianDay() routine... :)

 This document, however, relies on various sources for the history lesson
 and the Euphoria Library Documentation for the formatting style (and some
 obviously 'borrowed' text).

-----------------------------------------------------------------------------

                            B. Table of Contents


 A. Introduction


 B. Table of Contents


 0. The machine.e Segment


 1. Constants and Type Declarations

        1.1 Constant Declarations
                1.1.1 The XLEAP Constant

                    * History Lesson

                1.1.2 Gregorian Reformation Constants (local)
                1.1.3 The DaysPerMonth Constant Sequence (local)
                1.1.4 AverageDays Constants (local)
                1.1.5 Zero Constants
                1.1.6 Datatype Indexing Constants
                1.1.7 EPOCH_1970 - The 1970 Epoch Constant
                1.1.8 The DayLengthInSeconds Constant

        1.2 Types
                1.2.1 Date Structure Types (local)
                1.2.2 The Date Type
                1.2.3 The JDate Type
                1.2.4 Time Structure Types (local)
                1.2.5 The Time Type
                1.2.6 The DateTime Type


 2. Functions by Application Area

        2.1 Predefined Types

        2.2 Type Conversions

        2.3 Getting the Current Date or Time

        2.4 Functions with Simple Return Values

        2.5 Functions with Not-so-simple Return Values

        2.6 Day Differences

        2.7 Seconds Differences

        2.8 Adding and Subtracting Time

        2.9 Epoch 1970 Functions


 3. Alphabetical Listing of all Routines


-----------------------------------------------------------------------------

                          0. The machine.e Segment


   The crash_message() routine has been borrowed from the standard machine.e
   library to produce decent error messages when certain functions fail.

-----------------------------------------------------------------------------

                     1. Constants and Type Declarations


 1.1 Constants
 =============


 1.1.1 The XLEAP Constant
 ------------------------

 The XLEAP constant makes DateTime.e ridiculously future-proof (excepting a
 change of calendar system...). Here's a little (badly written) history:


   During Roman times (around 46BC), the calendar had 12 lunar months of 29
   or 30 days. The length of the month depending on when the full moon for
   that particular month occured. Unfortunately, that left the calendar
   10_1/4 days short. To remedy the problem every other year had a short 20
   day month added to the end. This pattern of 355, 375, 355, etc. meant
   that an average year was still 1/4 day short, and so the calendar
   eventually moved out of step with the seasons.

   Julius Caesar, the Emperor at the time, commisioned a Greek astronomer,
   Sosigenes, to redesign the ailing calendar and solve the problem once
   and for all. Sosigenes recommended a year of 365 days with an extra
   day added every four years - a leap year. While this was a good idea
   the new calendar couldn't be used until the old year was back in step
   with the seasons. So the year went on. For 445 days. The Roman populace
   was thrown into utter confusion, but at the end of it there was a much
   improved, Julian, calendar.

   Two other important things happened at that time: The long year caused
   the March new year to fall in January (as it still does today) and
   a month in the new calendar was renamed 'Julius' (July) in honour of the
   Emperor. Two years later (so legend has it) Julius Caesar was killed by
   his 'friend' Brutus.

   In 27BC, Julius Caesar's adopted son Octavian took the name Augustus and
   made himself dictator of Rome, founding the Roman Empire in the process.
   To make his mark he renamed the month of Sextilis, which was now
   (paradoxically) the eighth month, 'Augustus' and gave it 31 days, where
   previously it had had 30. He borrowed the day from February, reducing its
   number to 28. Note that in a leap year the month lengths would have
   alternated 31, 30, 31, 30... etc. all the way through the year had he not
   made the change.

   A quarter of a century later the founder of the religion that shaped the
   western world was born. Since then the year has been numbered according
   to the number of years since (or before) the birth of Jesus Christ.

   Slowly, the discrepancies between the calendar and the seasons crept back
   into play. A 365_1/4 day year is slightly too long, but close enough for
   it to be 1600 years later, and 10 days out of step, before someone decided
   to make a further change.

   In 1582, to bring the calendar back into step, Pope Gregory XIII deemed
   that October 4th 1582 should be followed by October 15th thus removing the
   10 day error. To prevent the same thing from happening another 1600 years
   hence, it was put forth that all further end-of-century years, excluding
   those divisible by 400, should be non-leap years.

   The Gregorian Calendar, as it became known, was not adopted by the mainly
   Protestant British and their colonies until 1752. At that time America
   was still over 20 years away from gaining independence and so adopted
   the new calendar at the same time as the British.

   In 1752, the Julian calendar was 11 days out of step. Correcting for this
   the British Government deemed that September 2nd 1752 should be followed
   by September 14th. Riots occured among the people who demanded back their
   eleven days!

 The Gregorian calendar is still (theoretically) imperfect since the average
 Gregorian year length is 365.2425 days long, contrasting with the true
 average year length of 365.2422 days.

 The XLEAP constant extends the leap year rules to accommodate this. i.e.
 a year is an extended-leap year if it divides by 4, 400 or 80000 but not if
 it divides by 100 or 3200. e.g. the year 6400 would not be a leap year using
 the XLEAP rules, whereas it would be a leap year without XLEAP.


 1.1.2 Gregorian Reformation Constants (local)
 ---------------------------------------------

 DateTime.e uses the 1752 version of the Julian-Gragorian change-over.
 There is also rounded down version of the constant to help with julianDay()
 calculations.


 1.1.3 The DaysPerMonth Constant Sequence (local)
 ------------------------------------------------

 The lengths of the 12 months in non-leap years. Use the daysInMonth()
 function to get at these values external to the library.


 1.1.4 AverageDays Constants (local)
 -----------------------------------

 These values are averages over the period 1AD - 80000AD. They are used
 by a guesstimate in the julianDate() function


 1.1.5 Zero Constants
 --------------------

 Date_0, Time_0 and DateTime_0 represent the smallest magnitude constant for
 their respectively named data types.

 DateTime.e projects the 1752 Gregorian calendar back to 1AD (and beyond) so
 date zero is the 31st of December 1BC.

 Notes:

 * The 445 day long 46BC and oddly lengthed previous years are not emulated.

 * 1BC is represented internally as year 0, 2BC as year -1, etc. Be aware of
   this if you play with dates pre 1AD


 1.1.6 Datatype Indexing Constants
 ---------------------------------

 Used for accessing parts of the Date, Time and DateTime data types.
 e.g.

   atom j
   DateTime dt
   dt = DateTime_0

   dt[DT_TIME][HOURS]   = 14
   dt[DT_TIME][MINUTES] = 25
   dt[DT_TIME][SECONDS] = 00     -- set dt to 2:25pm on June 24th 2001
   dt[DT_DATE][MONTH]   = 6
   dt[DT_DATE][DAY]     = 24
   dt[DT_DATE][YEAR]    = 2001

   dt = { {2001, 6, 24}, {14, 25, 00} } -- same as above

   j = julianDayOfYear(dt[DT_DATE])     -- j = 175 (175th day of year)

   if integer(dt[DT_TIME][SECONDS]) then
       puts(1, "No fraction on seconds\n")
   end if


 1.1.7 EPOCH_1970 - The 1970 Epoch Constant
 ------------------------------------------

 Many computer systems store time internally as the number of seconds since
 midnight on the January 1st 1970. Conversely, DateTime.e when asked to
 represent a DateTime datatype as a number of seconds, will return the
 number of seconds since Date_0. (1BC-12-31)

 This constant, a global variable and two functions enable conversions to and
 from the 1970 epoch format. See section 2.9.


 1.1.8 The DayLengthInSeconds Constant
 -------------------------------------

 A constant for a number that may well be used often with a library that uses
 days and seconds as its base data types.


 1.2 Types
 =========

 Further information on the global data types - Date, JDate, Time and
 DateTime  - may be found in section 3. Expansions on the Date and DateTime
 types - ValidDate and ValidDateTime - are covered only in that section.


 1.2.1 Date Structure Types (local)
 ----------------------------------

 These bound the values for years, months, days and number of days in a year
 to -2500000..2500000, 1..12, 1..31 and 1..366 respectively.


 1.2.2 The Date Type
 -------------------

 The Date type is essentially a three-integer sequence containing a year,
 a month, and a day number in that order. e.g.

   Date d
   d = {2001, 12, 25} -- Xmas 2001


 1.2.3 The JDate Type
 --------------------

 A two-integer sequence containing a year and a number of days representing
 the position in the year. e.g.

   JDate jd
   jd = {2001, 359} -- Also Xmas 2001

 JDates are only simply supported within the library. Conversion functions
 are provided to and from Dates so that JDates may be worked with.

 There is a JDAY indexing constant to access the days part. e.g.

   integer j
   j = jdt[JDAY] -- j = 359


 1.2.4 Time Structure Types (local)
 ----------------------------------

 These bound the values for hours, minutes and seconds to 0..23, 0..59 and
 0..59.99.. respectively. Note that seconds is allowed to be non-integral,
 i.e. an atom.


 1.2.5 The Time Type
 -------------------

 A two-integer, one-atom sequence containing a time of day as hours, minutes,
 and seconds in that order. e.g.

   Time t
   t = {15, 8, 45} -- t = 3:08pm and 45 seconds


 1.2.6 The DateTime Type
 -----------------------

 A two element sequence, the first being a Date the second being a Time.
 See the example in section 1.1.6

-----------------------------------------------------------------------------

                        2. Functions by Application Area

 2.1 Predefined Types
 ====================

 As well as declaring variables with these types, you can also call them just
 like ordinary functions, in order to test if a value is a certain type.

 Date            - See section 1.2.2 - test if an object is a date

 JDate           - See section 1.2.3 - test if an object is a julian date

 Time            - See section 1.2.5 - test if an object is a time

 DateTime        - See section 1.2.6 - test if an object is a date and time

 ValidDate       - test if an object is a valid date

 ValidDateTime   - test if an object is a DateTime with a valid date


 2.2 Type Conversions
 ====================

 Each of these converts one data type into another.

 JDateToDate     - convert a JDate into a Date - See 1.2.3 and 1.2.2

 DateToJDate     - convert a Date into a JDate - See 1.2.2 and 1.2.3

 hmsToSeconds    - convert a Time into a number of seconds since midnight

 secondsToHms    - convert a number of seconds since midnight into a Time

 DateTimeToSeconds - convert a DateTime into a number of sec.s since Date_0

 secondsToDateTime - convert a number of seconds since Date_0 to a DateTime

 DateToDateTime  - convert a Date into a DateTime

 DateTimeToDate  - convert a DateTime into a Date (Warning - Time is lost!)


 2.3 Getting the Current Date or Time
 ====================================

 nowDate         - returns today's Date

 nowTime         - returns the Time

 nowDateTime     - returns today's Date and the current Time


 2.4 Functions with Simple Return Values
 =======================================

 isLeap          - returns whether a given year is a leap year

 daysInYear      - returns the number of days in a given year

 daysInMonth     - returns the nr. of days in a given month of a given year

 dayOfWeek       - returns the day of week for a given Date (Sun=1..Sat=7)


 2.5 Functions with Not-so-simple Return Values
 ==============================================

 julianDay       - returns the number of days since Date_0

 julianDayOfYear - returns the number of days since Dec 31st (Jan 1st = 1)

 julianDate      - returns the date associated with the given number of days
                   since Date_0 (i.e. the opposite of julianDay)

 julianDateInYear - same as JDateToDate


 2.6 Day Differences
 ===================

 daysSince       - returns number of days since a given Date in the past

 daysUntil       - returns number of days until a given Date in the future

 daysDifference  - returns the number of days between two Dates (may be -ve)


 2.7 Seconds Differences
 =======================

 secondsDifference - returns nr. of sec.s between two Times or two DateTimes


 2.8 Adding and Subtracting Time
 ===============================

 addToDate       - add number of days to a Date

 subFromDate     - as above, subtracting rather than adding

 addToTime       - add a Time to another Time (as a delta) or a nr. of sec.s

 subFromTime     - as above, subtracting rather than adding

 addToDateTime   - add a DateTime to a Time (as a delta) or number of sec.s

 subFromDateTime - as above, subtracting rather than adding


 2.9 Epoch 1970 Functions
 ========================

 Epoch  - a global variable for setting an Epoch. 1970-1-1 is the default

 secondsSinceEpoch  - convert number of seconds since Date_0 (DateTime.e
                      native format) into the number of seconds since the
                      Epoch (using the default = Linux/Unix format)

 EpochTimeTo1ADTime - convert number of seconds since Epoch into the number
                      of seconds since Date_0. i.e. Convert Linux/Unix to
                      DateTime.e native when Epoch is set to default.

-----------------------------------------------------------------------------

                   3. Alphabetical Listing of all Routines


 To indicate what kind of object may be passed in and returned, the following
 prefixes are used:

 x     - a general object (atom or sequence)

 a     - an atom

 i     - an integer

 d     - a Date

 jd    - a JDate

 t     - a Time

 dt    - a DateTime

 <addToDate>

 Syntax:      d1 = addToDate(d2, i)

 Description: Adds a number of days onto a Date and returns a new Date.

 Comments:    Wraps around correctly at the ends of months and years.

 Example:     ? addToDate({2001, 6, 24}, 7) -- prints {2001, 7, 1}

 See Also:    subFromDate, other add and sub functions


 <addToDateTime>

 Syntax:      dt1 = addToDateTime(dt2, t)
              dt1 = addToDateTime(dt2, a)

 Description: Adds a number of seconds or a Time (used as a delta) onto a
              DateTime object and returns a new DateTime.

 Comments:    Wraps correctly at the ends of years, months, hours, etc.

 Example 1:   DateTime dt
              dt = nowDateTime() -- get current time and date

              dt = addToDateTime(dt, {5, 0, 0}) -- dt = 5 hours from now

 Example 2:   dt = addToDateTime(dt, 27.3) -- add 27.3 seconds to dt

 See Also:    subFromDateTime, other add and sub functions


 <addToTime>

 Syntax:      d1 = addToTime(d2, t)
              d1 = addToTime(d2, a)

 Description: Adds a number of seconds or a Time (used as a delta) onto a
              Time object and returns a new Time.

 Comments:    Wraps around correctly at the ends of hours and minutes.

 Warning:     Wraps around zero at midnight!

 Example:     ? addToTime({18, 02, 34}, 21386) -- prints {23, 59, 0}

 See Also:    subFromTime, other add and sub functions


 <Date>

 Syntax:      i = Date(x)

 Description: Return 1 if x is a Date else return 0.

 Comments:    This serves to define the Date type. You can also call it
              like an ordinary function to determine if an object is a
              Date.

 Structure:   A Date is a three-integer sequence of the format:

                {year, month, day}

              where  -2500000 <=  year  <= 2500000
                            1 <=  month <= 12
                            1 <=   day  <= 31

              The parts of a Date may be accessed using the DAY, MONTH and
              YEAR indexing constants.

 Warnings:    Some Dates and Times are indistinguishable - {1, 1, 1} is both
              a valid Date and Time.

              Date() only checks that its values are correctly bounded - it
              does not check that the actual date is valid. For that, use the
              ValidDate() routine. e.g. Date({2001, 2, 31}) will return 1
              even though there is no such thing as February 31st.

 Example 1:   Date d
              d = {2001, 12, 25}      -- Xmas
              ? d[MONTH]              -- prints 12

 Example 2:   if Date(x) then
                  puts(1, "It looks like a Date...\n")
              end if

 See Also:    ValidDate, JDate, Time, DateTime, ValidDateTime


 <DateTime>

 Syntax:      i = DateTime(x)

 Description: Return 1 if x is a DateTime object else return 0.

 Comments:    This serves to define the DateTime type. You can also call it
              like an ordinary function to determine if an object is a
              DateTime.

 Structure:   A DateTime wraps a Date structure and a Time structure in a
              a two element sequence. The format is:

                {date, time}

              where 'date' and 'time' are valid by the Date and Time types
              respectively.

              The two parts of a DateTime object may be accessed using the
              DT_DATE and DT_TIME indexing constants. They, in turn may be
              accessed like Dates and Times.

 Warnings:    DateTime() calls Date() internally and therefore only checks
              that its DT_DATE values are correctly bounded - it does not
              check that the actual date is valid. For that, use the
              ValidDateTime() routine.

 Example 1:   DateTime dt
              dt = nowDateTime()    -- set dt to current date and time
              dt[DT_TIME] = Time_0  -- set the time to midnight

 Example 2:   if DateTime(x) then
                  ? x[DT_DATE][YEAR] -- print the year part of x
              end if

 See Also:    Date, Time, ValidDateTime, JDate, ValidDate


 <DateTimeToDate>

 Syntax:      d = DateTimeToDate(dt)

 Description: Converts a DateTime object to a Date object.

 Comments:    Returns the Date part of a DateTime object. This means that
              any information from the DT_TIME part is lost.

 Example:     ? DateTimeToDate(DateTime_0) = Date_0 -- prints 1

 See Also:    DateToDateTime, DateTimeToSeconds, other conversion functions


 <DateTimeToSeconds>

 Syntax:      a = DateTimeToSeconds(dt)

 Description: Returns the number of seconds since (or until) Date_0

 Comments:    'a' will be in the range -7889403153600 to 78892380259199

 Example:     ? DateTimeToSeconds(nowDateTime()) -- prints a large number!

 See Also:    secondsToDateTime, DateTimeToDate, other conversion functions


 <DateToDateTime>

 Syntax:      dt = DateToDateTime(d)

 Description: Converts a Date object to a DateTime object.

 Comments:    Returns a DateTime object with the DT_DATE part set to the
              given date and the DT_TIME part set to Time_0.

 Example:     dt = DateToDateTime( DateTimeToDate(dt) )

              -- This is equivalent to:

              dt[DT_TIME] = Time_0

 See Also:    DateTimeToDate, DateToJDate, other conversion functions


 <DateToJDate>

 Syntax:      jd = DateToJDate(d)

 Description: Converts a Date object to a JDate object.

 Example:     ? DateToJDate({ 2001, 6, 24 }) -- prints {2001, 175}

 See Also:    JDateToDate, DateToDateTime, other conversion functions


 <dayOfWeek>

 Syntax:      i = dayOfWeek(d)

 Description: Return the day of week for the given date 'd'.

 Comments:    The return values are in the range 1..7, 1 being Sunday and
              7 being Saturday.

 Example:     ? dayOfWeek({ 2001, 12, 25 }) -- prints 3 (Tuesday)


 <daysDifference>

 Syntax:      a = daysDifference(d1, d2)

 Description: Return the number of days from d1 to d2.

 Comments:    In most circumstances an integer can be used to store the
              returned value from this function. An atom is only required
              if the dates are over 29.4 million years apart.

              The return value is equivalent to d2 minus d1.

 Example:     Date d
              integer i

              d = nowDate()
              i = daysDifference(d, {d[YEAR],12,25}) - 1

              if i = 0 then
                  puts(1, "Merry Christmas!\n")

              elsif i < 0
                  puts(1, "Uh-oh. Xmas/New Year Lull week.\n"

              else
                  printf(1, "Only %d shopping days left 'til Xmas!\n", i)

              end if

 See Also:    secondsDifference, functions beginning add and sub


 <daysInMonth>

 Syntax:      i1 = daysInMonth(i2, i3)

 Description: Return the number of days in the month (i3) specified by the
              given year (i2)

 Comments:    An error will result if the year or the month are outside the
              ranges set by the library. i.e. -2500000..2500000 and 1..12
              respectively.

 Example:     ? daysInMonth(1752, 9) -- prints 19 (See the history lesson!)

 See Also:    daysInYear


 <daysInYear>

 Syntax:      i1 = daysInYear(i2)

 Description: Return the number of days in the year specified by 'i2'

 Comments:    An error will result if the year is outside the ranges set by
              the library. i.e. -2500000..2500000

 Example:     ? daysInYear(2000) -- prints 366

 See Also:    daysInMonth


 <daysSince>

 Syntax:      a = daysSince(d)

 Description: Return the number of days since a specified date.

 Comments:    In most circumstances an integer can be used to store the
              returned value from this function. An atom is only required
              if the date is over 29.4 million years ago.

              Will return a negative number if 'd' is in the future.

 Example:     ? daysSince(EPOCH_1970) -- prints nr. of days since 1970-1-1

 See Also:    daysUntil, daysDifference


 <daysUntil>

 Syntax:      a = daysUntil(d)

 Description: Return the number of days until a specified date.

 Comments:    In most circumstances an integer can be used to store the
              returned value from this function. An atom is only required
              if the date will be over 29.4 million years hence.

              Will return a negative number if 'd' is in the past.

 Example:     ? daysUntil({3000,1,1}) -- prints nr. of days until 3000AD

 See Also:    daysUntil, daysDifference


 <EpochTimeTo1ADTime>

 Syntax:      a1 = EpochTimeTo1ADTime(a2)

 Description: Convert the number of seconds since the date and time
              specified by the 'Epoch' global variable into the number of
              seconds since the internal epoch of 1-Jan-1AD.

 Comments:    Will return a negative value if 'a2' is before the date and
              time specified by the 'Epoch' global variable.

              Use this for converting Linux dates and times stored in
              number-of-seconds-since-1/1/1970 format.

 Example:     ? secondsToDateTime(
                  EpochTimeTo1ADTime(10 * DayLengthInSeconds)
                )
              -- prints date and time of 10 days after the 'Epoch' variable.

 See Also:    secondsSinceEpoch


 <hmsToSeconds>

 Syntax:      a = hmsToSeconds(t)

 Description: Returns the number of seconds since Time_0

 Comments:    'a' will be in the range 0 <= a < 86400 (DayLengthInSeconds)

 Example:     ? hmsToSeconds({22, 8, 0}) -- prints 79680

 See Also:    secondsToHms, other conversion functions


 <isLeap>

 Syntax:      i1 = isLeap(i2)

 Description: Return 1 if i2 is a leap year else return 0.

 Comments:    The XLEAP constant affects the return values of this function,
              and therefore any functions that rely on it, for years
              including and after 3200AD

 Example:     ? isLeap(2000) -- prints 1 (2000 was a leap year)

 See Also:    Section 1.1.1 - The XLEAP Constant


 <JDate>

 Syntax:      i = JDate(x)

 Description: Return 1 if x is a JDate else return 0.

 Comments:    This serves to define the JDate type. You can also call it
              like an ordinary function to determine if an object is a
              JDate.

              JDates are not widely supported by the library, but they can
              serve a useful purpose. One use is to avoid the ambiguity
              between Dates and Times, since JDates have only 2 elements.

              Functions are provided to convert JDates to and from Dates

 Structure:   A JDate is a two-integer sequence of the format:

                {year, jday}

              where  -2500000 <=  year  <= 2500000
                            1 <=  jday  <= 366

              The parts of a JDate may be accessed using the JDAY and YEAR
              indexing constants.

 Warnings:    JDate() only checks that its values are correctly bounded - it
              does not check whether the JDAY value is valid for the YEAR
              specified. e.g. JDate({1999, 366}) will return 1 even though
              there was only 365 days in 1999.

 Example:     -- This code emulates a nowJDate() function
              JDate today
              sequence date_info

              date_info = date()
              today = date[1] & date[8] -- today's JDate

 See Also:    Date, JDateToDate, Time, DateTime


 <JDateToDate>

 Syntax:      d = JDateToDate(jd)

 Description: Converts a JDate object to a Date object.

 Example:     ? DateToJDate({ 2001, 176 }) -- prints {2001, 6, 25}

 See Also:    DateToJDate, other conversion functions


 <julianDate>

 Syntax:      d = julianDate(i)

 Description: Converts the number of days since (or until) December 31st 1BC
              into a valid date.

 Comments:    Calculating a date is not an exact science, so julianDate
              guesstimates a year and the number of days passed in that year.
              If the days value falls outside the guessed year a correction
              is quickly made. In tests this function only had to make a
              maximum of _one_ adjustment - even for the most extreme Dates.

              This function is the opposite to julianDay.

 Example:     ? julianDay(856288) -- prints {2345, 6, 7} - June 7th 2345AD

 See Also:    julianDay, julianDateInYear, julianDayOfYear


 <julianDateInYear>

 Syntax:      d = julianDateInYear(jd)

 Description: Converts the number of days since the end of the previous year
              and the year into a Date.

 Comments:    This function is identical to the JDateToDate function.

 See Also:    JDateToDate, julianDayOfYear, julianDate, julianDay


 <julianDay>

 Syntax:      i = julianDay(d)

 Description: Returns the number of days since (or until) December 31st 1BC

 Comments:    This function reduces any Date to an integral number of days
              allowing calculations to be unhampered by irregular year and
              month boundaries. It is also the most mathematically complex
              function in the library.

              This function is also the inverse of julianDate.

 Example:     ? julianDay({2054, 6, 4}) -- prints 750000 - June 4th 2054AD

 See Also:    julianDate, julianDayOfYear, julianDateInYear


 <julianDayOfYear>

 Syntax:      i = julianDayOfYear(d)

 Description: Returns the number of days since the end of the previous year

 Comments:    Use to avoid irregular month boundaries within a year.

 Example:     ? julianDayOfYear({2001, 6, 25}) -- prints 176

 See Also:    julianDateInYear, julianDay, julianDate


 <nowDate>

 Syntax:      d = nowDate()

 Description: Returns the Date object representing the current date.

 Comments:    Calls Euphoria's date() function internally.

              The YEAR part is always 4 (or I suppose more) digits.

 Example:     ? nowDate() -- prints today's date as a sequence

 See Also:    nowTime, nowDateTime


 <nowDateTime>

 Syntax:      d = nowDateTime()

 Description: Returns the DateTime object representing the current date and
              time.

 Comments:    Calls Euphoria's date() function internally.

              The YEAR subpart of the DT_TIME part is always 4 (or I suppose
              more) digits.

 Example:     ? nowDateTime() -- printed {{2001, 6, 25}, {22, 09, 23}}
                              -- June 25th 2001AD, 10:09pm and 23 seconds.

 See Also:    nowDate, nowTime


 <nowTime>

 Syntax:      d = nowTime()

 Description: Returns the Date object representing the current date.

 Comments:    Calls Euphoria's date() function internally.

 Example:     printf(1, "%02d:%02d:%02d", nowTime())
                    -- prints the current time e.g. 23:12:56

 See Also:    nowDateTime, nowDate


 <secondsDifference>

 Syntax:      a = secondsDifference(x1, x2)

 Description: Return the number of seconds from x1 to x2.

 Comments:    x1 and x2 must be both Time objects or both DateTime objects
              otherwise an error will result. They cannot be Date objects
              due to Date / Time ambiguities. To get th number of seconds
              between two Date objects, conver them to DateTimes with the
              DateToDateTime function.

              The return value is equivalent to x2 minus x1.

 Example:     DateTime dt
              dt = nowDateTime()

              -- Do something for a very long time

              printf(1, "Took %d seconds to run!\n",
                  secondsDifference(dt, nowDateTime())
              )

              -- We couldn't use Times here because they wrap at midnight.

 See Also:    daysDifference, functions beginning add and sub


 <secondsSinceEpoch>

 Syntax:      a1 = secondsSinceEpoch(a2)

 Description: Convert the number of seconds since the internal epoch of
              January 1st 1AD into the number of seconds since the date and
              time specified by the 'Epoch' global variable.

 Comments:    Use this for converting *to* Linux dates and times in the
              number-of-seconds-since-1/1/1970 format.

 Example:     integer linux_midnight

              linux_midnight =
                  secondsSinceEpoch(
                      DateTimeToSeconds(
                          DateToDateTime(
                              nowDate()
                          )
                      )
                  )

              -- Translates today at midnight to a linux-format time
              -- Date -> DateTime -> internal seconds format -> linux

 See Also:    EpochTimeTo1ADTime


 <secondsToDateTime>

 Syntax:      dt = secondsToDateTime(a)

 Description: Convert the number of seconds since Date_0 into a valid Date
              and Time

 Comments:    If 'a' is outside the range -7889403153600 to 78892380259199
              an internal error will result. This is unlikely if the
              function is used only with values generated by the library.

 Example:     ? secondsToDateTime(DateTimeToSeconds(nowDateTime()))
              -- A very roundabout way of printing the current date + time!

 See Also:    DateTimeToSeconds, secondsToHms, other conversion functions


 <secondsToHms>

 Syntax:      t = secondsToHms(a)

 Description: Convert a number of seconds to a Time of day

 Comments:    If 'a' is less then 0 or greater than 86400, the Time returned
              will be modulo one day.

 Example:     Time t

              t = secondsToHms(DateTimeToSeconds(nowDateTime()))

              -- A very roundabout way of setting t to nowTime()

 See Also:    hmsToSeconds, secondsToDateTime, other conversion functions


 <subFromDate>

 Syntax:      d1 = subFromDate(d2, i)

 Description: Subtracts a number of days from a Date and returns a new Date.

 Comments:    Wraps around correctly at the ends of months and years.

 Example:     ? subFromDate({2002, 1, 3}, 14) -- prints {2001, 12, 20}

 See Also:    addToDate, other add and sub functions


 <subFromDateTime>

 Syntax:      dt1 = subFromDateTime(dt2, t)
              dt1 = subFromDateTime(dt2, a)

 Description: Subtracts a number of seconds or a Time (used as a delta) from
              a DateTime object and returns a new DateTime.

 Comments:    Wraps correctly at the ends of years, months, hours, etc.

 Example 1:   DateTime dt
              dt = nowDateTime() -- get current time and date

              dt = subFromDateTime(dt, {5, 0, 0}) -- dt = 5 hours from now

 Example 2:   dt = subFromDateTime(dt, (3+3/4) * 60)
                    -- subtract three and three-quarter minutes from dt

 See Also:    addToDateTime, other add and sub functions


 <subFromTime>

 Syntax:      d1 = subFromTime(d2, t)
              d1 = subFromTime(d2, a)

 Description: Subtracts a number of seconds or a Time (used as a delta) from
              a Time object and returns a new Time.

 Comments:    Wraps around correctly at the ends of hours and minutes.

 Warning:     Wraps around zero at midnight!

 Example:     ? subFromTime(Time_0, 60) -- prints {23, 59, 0}

 See Also:    addToTime, other add and sub functions


 <Time>

 Syntax:      i = Time(x)

 Description: Return 1 if x is a Date else return 0.

 Comments:    This serves to define the Time type. You can also call it
              like an ordinary function to determine if an object is a
              Time.

 Structure:   A Time is a two-integer-followed-by-one-atom sequence of the
              format:

                {hours, minutes, seconds}

              where:  0 <=   hours  <= 59
                      0 <=  minutes <= 59
                      0 <=  seconds <  60

              The parts of a Time may be accessed using the HOURS, MINUTES
              and SECONDS indexing constants.

 Warnings:    Some Dates and Times are indistinguishable - {1, 1, 1} is both
              a valid Date and Time.

 Example 1:   Time t
              t = {23, 45, 56}  -- nearly 11:46pm
              t[SECONDS] += 4   -- causes an error - use addToTime() instead

 Example 2:   integer twelve_hour

              if Time(x) then
                  twelve_hour = remainder(x[HOURS], 12)
                  if twelve_hour = 1 then
                      puts(1, "Hickory Dickory Dock!\n")
                  end if

                  for i = 1 to twelve_hour do
                      puts(1, "Bong!\n")
                  end for

                  if twelve_hour = 1 then
                      puts(1, "Bye-bye Mouse.\n")
                  end if
              else
                  puts(1, "How can we scare mice if there's no clock?\n")
              end if

 See Also:    Date, DateTime, ValidDateTime

 <ValidDate>

 Syntax:      i = ValidDate(x)

 Description: Return 1 if x is a ValidDate else return 0.

 Comments:    This serves to define a strict ValidDate type. Its main use is
              as an ordinary function to determine if an object is a truly
              valid Date object.

              If a date is invalid within a current year, this function will
              catch it. Date() will not.

 Structure:   Identical to the Date object.

 Warnings:    Some Dates and Times are indistinguishable - {1, 1, 1} is both
              a valid Date and Time.

 Example:     ? ValidDate({1752, 9, 6}) -- returns 0

              -- there was no such day as the 6th of September 1752
              -- see the history lesson

 See Also:    Date, ValidDateTime


 <ValidDateTime>

 Syntax:      i = ValidDateTime(x)

 Description: Return 1 if x is a ValidDateTime else return 0.

 Comments:    This serves to define a strict valid-date-and-time
              (ValidDateTime) type. Its main use is as an ordinary function
              to determine if a DateTime object contains a truly valid Date
              object.

              Calls ValidDate() internally.

 Structure:   Identical to the DateTime object.

 Warnings:    Some Dates and Times are indistinguishable - {1, 1, 1} is both
              a valid Date and Time.

 Example:     DateTime dt

              -- get a value for dt from somewhere

              if Date(dt) and not ValidDate(dt) then
                  puts(1, "You nearly got me there - It looked like\n")
                  puts(1, "a proper date until I checked properly!\n)
              else
                  puts(1, "Bad Data - Go sit in the corner.\n")
              end if

              -- there was no such day as the 6th of September 1752
              -- see the history lesson

 See Also:    DateTime, ValidDate, Date, Time


