----------------------------------------------------------------------------- -- -- -- DateTime.e - Routines for handling Date and Time - (c) 2003 CyrekSoft -- -- -- ----------------------------------------------------------------------------- A. Introduction This document contains information about, 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.2.1 Internal 2.2.2 Internal / Related External 2.2.3 Related External 2.2.4 Unrelated External 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 Boolean Comparison 2.9 Adding and Subtracting Time 2.10 Epoch 1970 Functions 2.11 Output 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-Gregorian 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, "There is 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.10. 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 = jd[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. 2.2.1 Internal -------------- 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 DateToDateTime - convert a Date into a DateTime DateTimeToDate - convert a DateTime into a Date (Warning - Time is lost!) 2.2.2 Internal / Related External ---------------------------------- 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 dayFractionToHms - convert a fraction of a day into the equivalent Time hmsToDayFraction - convert a Time into an equivalent fraction of a day 2.2.3 Related External ---------------------- dayFractionToSeconds - convert a fraction of a day into seconds secondsToDayFraction - convert a number of seconds into a fraction of a day 2.2.4 Unrelated External ------------------------ ToSeconds - convert any Euphoria data type to a number of seconds ToDateTime - convert any Euphoria data type into a DateTime 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) validDayOfWeek - as above but returns -1 for an invalid Date 2.5 Functions with Not-so-simple Return Values ============================================== julianDay - returns the number of days since Date_0 julianDayDT - returns the number (& fraction) of days since DateTime_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) julianDateTime - returns the DateTime associated with the given number of days (& fraction) since DateTime_0 (inverse julianDayDT) julianDateInYear - same as JDateToDate 2.6 Day Differences =================== daysSince - returns number of days since a given Date in the past daysSinceDT - as above but returns days (& fraction) given a DateTime daysUntil - returns number of days until a given Date in the future daysUntilDT - as above but returns days (& fraction) given a DateTime daysDifference - returns the number of days between two Dates (may be -ve) daysDifferenceDT - as above but returns days (& fraction) given 2 DateTimes 2.7 Seconds Differences ======================= secondsDifference - returns nr. of sec.s between two Times or two DateTimes 2.8 Boolean Comparison ====================== isEquivalent - returns whether two DateTime.e objects are equivalent isBefore - returns whether the first object is before the second isAfter - returns whether the first object is after the second 2.9 Adding and Subtracting Time =============================== addToDate - add number of days to a Date subFromDate - as above, subtracting rather than adding addToTime - add a Time (as a delta) or seconds to a Time subFromTime - as above, subtracting rather than adding addSecondsToDateTime - add seconds or a Time (as a delta) to a DateTime subSecondsFromDateTime - as above, subtracting rather than adding addDaysToDateTime - add days (& fraction) to a DateTime subDaysFromDateTime - as above, subtracting rather than adding 2.10 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. 2.11 Output =========== sDumpDT - returns a formatted string sequence suitable for output ----------------------------------------------------------------------------- 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 (any of the following) a - an atom i - an integer s - a sequence d - a Date jd - a JDate t - a Time dt - a DateTime ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: dt1 = addDaysToDateTime(dt2, a) Description: Increases a DateTime object by a number of days and returns the result. Comments: Wraps correctly at the ends of years, months, hours, etc. Warning: May suffer from atom rounding errors Example: DateTime dt dt = nowDateTime() -- get current time and date dt = addDaysToDateTime(dt, 3+1/4) -- 3 and 1/4 days from now See Also: subDaysFromDateTime, other add and sub functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: dt1 = addSecondsToDateTime(dt2, a) dt1 = addSecondsToDateTime(dt2, t) Description: Increases a DateTime object by a number of seconds or a Time (used as a delta) and returns the result. Comments: Wraps correctly at the ends of years, months, hours, etc. Example 1: DateTime dt dt = nowDateTime() -- get current time and date dt = addSecondsToDateTime(dt, {5, 0, 0}) -- 5 hours from now Example 2: dt = addToDateTime(dt, 27.3) -- add 27.3 seconds to dt See Also: subSecondsFromDateTime, other add and sub functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: t = addToTime(x1, x2) Description: Adds any pairing of seconds (atoms) and/or Times and returns the result as a Time object Comments: If either x1 or x2 is not an atom or a Time, an error occurs. Warning: Wraps around zero at midnight! Example: ? addToTime({18, 02, 34}, 21386) -- prints {23, 59, 0} See Also: subFromTime, other add and sub functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: t = dayFractionToHms(a) Description: Converts a fraction of a day into a Time object. Warnings: Does not use integer part of parameter. Some rounding errors may occur. Example 1: ? dayFractionToHms(0.5) -- prints {12,0,0} -- Half a day is twelve hours Example 2: ? dayFractionToHms(1.5) -- also prints {12,0,0} -- the integer part cannot be represented in a Time object. See Also: hmsToDayFraction, other conversion functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: a1 = dayFractionToSeconds(a2) Description: Converts a fraction of a day into a number of seconds. Warning: Does not use integer part of a2. Some rounding errors may occur. Example: ? dayFractionToSeconds(0.915) -- prints 79056 See Also: secondsToDayFraction, other conversion functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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) See Also: validDayOfWeek ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: a = daysDifferenceDT(dt1, dt2) Description: Return the exact number of days between dt1 and dt2. Comments: Similar to daysDifference but can return a fractional number of days since Times are present. The return value is equivalent to dt2 minus dt1. Warning: May suffer from atom rounding errors Example: DateTime dt atom a integer year dt = nowDateTime() year = dt[DT_DATE][YEAR] + 1 a = daysDifferenceDT(dt, {{year,1,1},Time_0}) printf(1, "There are %.8g days until %d!\n", {a,year}) See Also: secondsDifference, functions beginning add and sub ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 range set by the library. i.e. -2500000..2500000 Example: ? daysInYear(2000) -- prints 366 See Also: daysInMonth ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: a = daysSinceDT(dt) Description: Returns the exact number of days since a specified DateTime. Comments: Similar to daysSince but can return a fractional number of days since Times are present. Will return a negative number if 'dt' is in the future. Warning: May suffer from atom rounding errors Example: ? daysSinceDT({{1918,11,11},{11,00,00}}) -- Exact number of days since the end of the Great War. -- = more than 30000 See Also: daysUntilDT, daysDifferenceDT ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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: daysSince, daysDifference ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: a = daysUntilDT(dt) Description: Return the exact number of days until a specified DateTime. Comments: Similar to daysUntil but can return a fractional number of days since Times are present. Will return a negative number if 'dt' is in the past. Warning: May suffer from atom rounding errors Example: ? daysUntilDT({{3456,7,8},{9,10,11.12}}) -- Exact number of days to the obscure date: -- July 8th 3456AD at 10 past 9(am) and 11.12 seconds. -- = well above half a million days... See Also: daysSinceDT, daysDifferenceDT ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: a = hmsToDayFraction(t) Description: Converts a Time object into a fraction of a day Comments: 'a' will always be in the range 0 <= a < 1 Warning: May suffer from atom rounding errors Example: ? hmsToDayFraction({22, 48, 0}) -- prints 0.95 (95%) See Also: dayFractionToHms, other conversion functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: i = isAfter(x1, x2) Description: Return 1 if x1 represents a period in time after x2 else return 0. Comments: Similar to the greater-than '>' operator, but works with Dates, Times, and DateTimes. Note that the real greater-than operator can not work as required with DateTime.e objects. Warnings: The facts that Dates can be invalid, Times wrap at midnight, and that some Dates and Times are ambiguous, can cause unexpected results from this function. Example: ? isAfter(nowDateTime(), {2004, 1, 1}) -- returns whether the current date and time is after the -- first day of 2004. Note that this line would not print 1 -- until the _2nd_ of January, 2004. See Also: isBefore, isEquivalent ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: i = isBefore(x1, x2) Description: Return 1 if x1 represents a period in time before x2 else return 0. Comments: Similar to the less-than '<' operator, but works with Dates, Times, and DateTimes. Note that the real less-than operator can not work as required with DateTime.e objects. Warnings: The facts that Dates can be invalid, Times wrap at midnight, and that some Dates and Times are ambiguous, can cause unexpected results from this function. Example: Date d d = nowDate() puts(1, "We are in the ") if isBefore(d,{d[YEAR], 7, 1}) then puts(1, "first ") else puts(1, "second ") end if printf(1, "half of %d\n", d[YEAR]) See Also: isAfter, isEquivalent ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: i = isEquivalent(x1, x2) Description: Return 1 if x1 and x2 represent the same number of seconds since Date_0 else return 0. Comments: Works much like Euphoria's equal() function but works solely with Dates, Times, Datetimes and atoms (as number of seconds) Warnings: The facts that Dates can be invalid, Times wrap at midnight, and that some Dates and Times are ambiguous, can cause unexpected results from this function. Example 1: if isEquivalent({22, 0, 0}, nowTime()) then puts(1, "Time for the News at Ten!\n") end if Example 2: ? isEquivalent({2003,2,29} , {2003,3,1}) -- prints 1 -- Since there is no February 29th in 2003, the date is -- equivalent to March 1st See Also: isAfter, isBefore, Euphoria's equal() function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: dt = julianDateTime(a) Description: Converts the exact number of days since (or until) December 31st 1BC into a valid DateTime object. Comments: Functions identically to julianDate, but uses the parameter's fractional part to generate an additional Time. This function is the opposite to julianDayDT. Warning: May suffer from atom rounding errors Example: ? julianDateTime(856288.75) -- prints {{2345,6,7},{18,0,0}} -- June 7th 2345AD at 6pm See Also: julianDayDT, julianDate, other julian functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: a = julianDayDT(dt) Description: Returns the exact number of days since December 31st 1BC Comments: This function reduces any DateTime to an exact number of days allowing calculations to be unhampered by irregular year and month boundaries. This function is the inverse of julianDateTime. Warning: May suffer from atom rounding errors Example: ? julianDayDT({ {2161, 3, 27}, {8, 9, 36} }) -- prints 789012.34 - March 27th 2161AD at just before 8:10am See Also: julianDateTime, julianDay, other julian functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: d = nowTime() Description: Returns the Time object representing the current time. 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: s = sDumpDT(x) Description: Returns a formatted string sequence suitable for output. Comments: Intended mainly for debugging purposes to return a string for the user to eventually display the value of x. Uses the ToDateTime (q.v.) function to interpret x. Warning: Any Date that is indistinguishable from a Time will be interpreted as a Time. See the examples for a workaround. Example 1: puts(1, sDumpDT({2003, 1, 9}) & "\n") -- prints 2003-1-9 Example 2: DateTime dt dt = nowDateTime() puts(2, "Now: " & sDumpDT(dt) & "\n") -- outputs the current date and time to STDERR -- using the format: -- yyyy-M-d @ hh:mm:ss.ff Example 3: Date d sequence s d = {0, 12, 25} -- First ever Xmas? s = sDumpDT(d) -- s = "00:12:25.00" because it is impossible to tell 'd' apart from a Time object. Example 4: -- A workaround for the above problem Date d sequence s d = {0, 12, 25} -- First ever Xmas? s = sDumpDT( DateToDateTime(d) ) s = s[1..find(' ',s)-1] -- s = "0-1-25" See Also: ToDateTime, Euphoria functions: sprintf, puts ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 find the number of seconds between two Date objects, first convert 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()) ) -- Times could not be used here since they wrap at midnight. See Also: daysDifference, functions beginning add and sub ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 1970-1-1 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: a1 = secondsToDayFraction(a2) Description: Convert a number of seconds to an equivalent fraction of a day Comments: a1 will always be in the range 0 <= a1 < 1. Example: ? secondsToDayFraction(85885) -- prints 0.9940393519 -- approaching midnight (~0.6% of the day to go) See Also: dayFractionToSeconds, secondsToHms, other conversions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: t = secondsToHms(a) Description: Convert a number of seconds to a Time of day Comments: If 'a' is less than 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: dt1 = subDaysFromDateTime(dt2, a) Description: Decreases a DateTime object by a number of days and returns the result. Comments: Wraps correctly at the ends of years, months, hours, etc. Warning: May suffer from atom rounding errors. Example: DateTime dt dt = nowDateTime() -- get current time and date dt = subDaysFromDateTime(dt, 7) -- last week at this time... See Also: addDaysToDateTime, other add and sub functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: t = subFromTime(x1, x2) Description: Subtracts the rightmost (x2) of any pairing of seconds (atoms) and/or Times from the leftmost (x1), and returns the result as a Time object. Comments: If either x1 or x2 is not an atom or a Time, an error occurs. Warning: Wraps around zero at midnight! Example: ? subFromTime(Time_0, 60) -- prints {23, 59, 0} See Also: addToTime, other add and sub functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: dt1 = subSecondsFromDateTime(dt2, t) dt1 = subSecondsFromDateTime(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 = subSecondsFromDateTime(dt, {5, 0, 0}) -- 5 hrs before now Example 2: dt = subFromDateTime(dt, (3+3/4) * 60) -- subtract three and three-quarter minutes from dt See Also: addSecondsToDateTime, other add and sub functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ