scsh-0.5/doc/newtime-spec.txt

162 lines
6.5 KiB
Plaintext

Scsh time interface
Olin Shivers
November, 1994
* Discussion
Jargon:
"UTC" and "UCT" stand for "universal coordinated time," which is the
official name for what is colloquially referred to as "Greenwich Mean
Time."
Posix allows a single time zone to specify *two* different offsets from
UTC: one standard one, and one for "summer time." Summer time is frequently
some sort of daylight savings time.
The scsh time package consistently uses this jargon: we never say
"gmt" or "dst;" we always say "utc" and "summer time."
We have two types: time and date.
A TIME specifies an instant in the history of the universe.
It is location and time-zone independent. A time is specified
by giving the number of elapsed seconds since the Unix "epoch"
(Midnight, January 1, 1970 UTC).
A DATE is a name for an instant in time that is specified
relative to some location/time-zone in the world, for example
Friday October 31, 1994 3:47:21 pm
What instant this date specifies depends on where you are. If I phone a Hong
Kong friend from Cambridge, Massachusetts, then the current TIME is the same
for both of us, but it has different DATES -- Hong Kong is 12 hours ahead
of Cambridge.
(define-record date ; A Posix tm struct
seconds ; Seconds after the minute (0-59)
minute ; Minutes after the hour (0-59)
hour ; Hours since midnight (0-23)
month-day ; Day of the month (1-31)
month ; Months since January (0-11)
year ; Years since 1900
summer? ; Summer (e.g., Daylight Savings) time in effect?
week-day ; Days since Sunday (0-6) These two fields
year-day) ; Days since Jan. 1 (0-365) are redundant.
(make-date seconds minute hour month-day month year
[summer? week-day year-day])
When making a DATE, the last three elements of the record are optional,
and default to #f, 0, and 0 respectively. This is useful when creating
a DATE record to pass to TIME->DATE.
Notice that the value of SUMMER? resolves amiguous boundary cases. For
example, on the morning of the Fall daylight savings change-over, 1:00am -
2:00am happens twice. Hence the date 1:30:00 on this morning can specify two
different seconds; the SUMMER? flag says which one.
Specifying time zones:
Several time procedures time time zones as arguments. When optional,
the time zone defaults to local time zone. Otherwise the time zone
can be one of:
#f Local time
Integer Seconds of offset from UTC. For example,
New York City is -18000 (-5 hours), San Francisco
is -28800 (-8 hours).
String A Posix time zone string understood by the OS
(i.e., the sort of time zone assigned to the $TZ
environment variable).
An integer time zone gives the number of seconds you must add to UTC
to get time in that zone. It is *not* "seconds west" of UTC -- that flips
the sign.
To get UTC time, use a time zone of either 0 or "UCT0".
* Procedures
(utime) -> [secs usecs]
The current time. UTIME provies micro-second resolution.
Sub-second resolution is not provided by Posix, but is in BSD.
If the OS does not support sub-second resolution, the USECS value
is always 0.
(date) -> date
The current date, in the local time zone.
(date [time tz]) -> date
Converts the time to the date as specified by the time zone TZ.
TIME defaults to the current time; TZ defaults to local time,
and is as described above.
(time) -> int
The current time.
(time [date tz]) -> int
Converts a date to a time as specified by the time zone TZ.
DATE defaults to the current date; TZ defaults to local time,
and is as described above.
A DATE record is overconstrained; TIME ignores the DATE's
WEEK-DAY and YEAR-DAY fields.
When passed to TIME, the SUMMER? field has the following meaning:
#f Resolve an ambiguous time in favor of non-summer time.
#t Resolve an ambiguous time in favor of summer time.
This is useful in boundary cases during the change-over. For example,
in the Fall, when US daylight savings time changes over at 2:00 am,
1:30 am happens twice -- it names two instants in time, an hour apart.
Outside of these boundary cases, the SUMMER? flag is *ignored*. For
example, if the standard/summer change-overs happen in the Fall and the
Spring, then the value of SUMMER? is ignored for a January or July date.
A January date would be resolved with standard time, and a July date with
summer time, regardless of the SUMMER? value.
The SUMMER? flag is also ignored if the time zone doesn't have a summer
time -- for example, an integer time zone, or simple UTC.
(date->string date) -> string
(time->string time [tz]) -> string
(format-date fmt date [tz]) -> string
These have Posix analogs. FORMAT-DATE's time zone argument is only
used when one requests the time zone in the formatted string.
(utc-offset [time tz])
Returns the offset from UTC of time zone TZ at instant TIME.
TIME defaults to the current time; TZ defaults to local time,
and is as specified above.
The offset is the number of seconds you add to UTC time to get
local time.
Note: Be aware that other time interfaces (e.g., the BSD C interface)
give offsets as seconds *west* of UTC, which flips the sign. The scsh
definition is chosen for arithmetic simplicity. It's easy to remember
the definition of the offset: what you add to UTC to get local.
(time-zone [summer? tz])
Returns the name of the time zone as a string. SUMMER? is
used to choose between the summer name and the standard name (e.g.,
"EST" and "EDT"). SUMMER? is interpreted as follows:
Integer A TIME value. The variant in use at that time
is returned.
#f The standard time name is returned.
Otherwise The summer time name is returned.
SUMMER? defaults to the case that pertains at the time of the call.
It is ignored if the time zone doesn't have a summer variant.
We need a general date/time parser.
DATE has two more fields: tz-secs and tz-name.
TIME->DATE: These are set.
tz-secs is the offset from UTC for the instant this date specifies.
It includes summer time adjustments.
TZ=#f: tz-name is constructed from tzname[] and tz-secs.
TZ string: tz-name is constructed from tzname[] and tz-secs.
TZ int: tz-name is of form UTChh:mm:ss ?? or #f ??
DATE->TIME:
tz-secs integer: It is used for conversion.
summer? is ignored.
otw: time zone taken from tz-name, with #f meaning "local time."
summer? is used, if the time zone is a dual one.