.tl.date-long
- long date
.tl.date-long-format
- long date format
.tl.date-short
- short date
.tl.date-short-format
- short date format
.tl.dst?
- daylight savings status
.tl.leapyear?
- is given year a leap year?
.tl.local-to-ut
- convert local time to UTC
.tl.locale-ampm
- get player's locale string for am/pm
.tl.locale-month-long
- get player's full-length
locale string for month
.tl.locale-month-short
- get player's abbreviated
locale string for month
.tl.locale-weekday-long
- get player's full-length
locale string for weekday
.tl.locale-weekday-short
- get player's abbreviated
locale string for weekday
.tl.mktime
- build a systime from parts
.tl.muck-to-ut
- convert Muck local time to UTC
.tl.my-date-long
- my long date
.tl.my-date-short
- my short date
.tl.my-local-to-ut
- Convert my local time to UTC
.tl.my-strftime
- strftime
aware of my locale
.tl.my-time-long
- my long time
.tl.my-time-short
- my long short
.tl.strftime
- locale-aware strftime
.tl.systime-local
- time local to a player
.tl.systime-muck
- time local to the Muck
.tl.systime-my-local
- time local to me
.tl.systime-ut
- time in UTC
.tl.time-long
- long time
.tl.time-long-format
- long time format
.tl.time-short
- short time
.tl.time-short-format
- short time format
.tl.timezonename
- player's time zone
.tl.ut-to-local
- convert UTC to local time
.tl.ut-to-muck
- convert UTC to Muck time
.tl.ut-to-my-local
- convert UTC to my local time
_time/ampm/am
(string)
%p
" in calls to .tl.strftime
(default
"AM
").
_time/ampm/pm
(string)
%p
" in calls to .tl.strftime
(default
"PM
").
_time/DST-cache/systime
(integer)
_time/DST-cache/value
(integer)
_time/DST-rule
(string)
_time/format/date-long
(string)
%A %e %B
%Y
").
_time/format/date-short
(string)
%d-%b-%Y
").
_time/format/time-long
(string)
%I:%M:%S
%p
").
_time/format/time-short
(string)
%H:%M
").
_time/month-long/
n (string)
%B
" in calls to .tl.strftime
(January is 1,
December is 12) (default is in English).
_time/month-short/
n (string)
%b
" in calls to .tl.strftime
(Jan is 1, Dec is 12)
(default is first three letters of each English month).
_time/Offset-DST
(string)
_time/Offset-STD
(string)
_time/weekday-long/
n (string)
%A
" in calls to .tl.strftime
(Sunday is 0,
Saturday is 6) (default is in English).
_time/weekday-short/
n (string)
%a
" in calls to .tl.strftime
(Sun is 0, Sat is 6)
(default is first three letters of each English weekday).
_time/Zone-DST
(string)
_time/Zone-STD
(string)
#0
, whereas
the default locale (UTC) is stored on the da.timelib.muf
object.
timelib's functions fall into two categories: those which use a locale, and those which don't. Most functions fall into the former category.
Locale functions come in several flavours: Those which convert from one locale to another, those which produce a string for the current locale, and those which perform other locale-based tasks.
.tl.local-to-ut
,
.tl.ut-to-local
,
.tl.my-local-to-ut
,
.tl.ut-to-my-local
and
.tl.muck-to-ut
,
.tl.ut-to-muck
.
These macros convert from UTC to a given locale. (In fact, the last four
macros are expressed in terms of the first two, and are there for
convenience only.) For each of these, you need to give a systime, and in the case of
.tl.local-to-ut
and
.tl.ut-to-local
, the dbref of an object to use the locale
of. If you attempt to use an object for which no locale information has
been set, UTC will be used.
.tl.date-long
,
.tl.date-long-format
,
.tl.date-short
,
.tl.date-short-format
,
.tl.time-long
,
.tl.time-long-format
,
.tl.time-short
,
.tl.time-short-format
,
.tl.locale-weekday-long
,
.tl.locale-weekday-short
,
.tl.locale-month-long
,
.tl.locale-month-short
,
.tl.strftime
,
.tl.my-strftime
and
.tl.timezonename
.
Some of these, such as
.tl.locale-
[weekday
|month
]-
[long
|short
],
and
.tl.
[date
|time
]-
[long
|short
]-format
,
simply return the string associated with a certain part of an object's
locale. Some, such as
.tl.
[date
|time
]-
[long
|short
],
Interpolate a given local systime into these locale strings to produce a
date or time in the object's preferred format. These four functions use
.tl.strftime
.
strftime
is a standard C library function which takes a
systime and produces a string in a specified format. It works by
replacing certain string sequences in the format string with substrings
specifying the given date and time. For instance, all occurrences of
"%A" will be replaced by the string
"Sunday"
if the systime you gave strftime
was for a Sunday, and
likewise for any other day of the week. "%A" thus
means that the long weekday name is inserted into the text at that
point.
On the Muck, there is a primitive strftime
which simply
calls the C library function. The primitive has a number of
shortcomings, however. The main one is that the MUF
strftime
is not locale-aware. It is fixed in the Muck's
locale, which often isn't the locale that players want to use. Another
point of confusion with MUF's strftime
is that it accepts a
systime local to UTC, yet it implicitly converts this time to the Muck's
time zone before displaying it.
The timelib version, .tl.strftime
, addresses
both of thes problems. It cancels the implicit converting of systimes
into the Muck-local time zone, so you can call it with a local systime
and be sure that it will continue to display it in that time zone.
.tl.strftime
is also aware of time zone and language
locale. Thus "%A" will substitute
"Sonntag" if you have set your locale up to use
German weekday names, and "%Z" will substitute
the name of your time zone at the time you ask to be formatted (which
could be your standard or summer time).
This is the full listing of substitutions made by
.tl.strftime
:
%m
%h, %b
%B
%d
%e
%j
%w
%a
%A
%y
%Y
%H
%I
%k
%l
%M
%S
%s
%p
%z, %Z
%%
%U
%W
%U
except weeks start on Monday
Note that the MUF-primitive strftime
allows space-padding
of fields and the abbreviations
%C
,
%c
,
%x
,
%d
,
%D
,
%T
,
%X
,
%R
and
%r
. .tl.strftime
does not support these,
however it is easy to expand the latter into their definitions. Type
man strftime
at the command line to see the definitions of
these substitutions.
.tl.my-strftime
uses the locale of the player running
the program. This is usually what you want.
.tl.timezonename
prints a player's time zone name assuming
their current local time. This is probably not very useful and can be
expressed in terms of .tl.strftime
.
.tl.dst?
,
.tl.systime-ut
,
.tl.systime-local
,
.tl.systime-muck
and
.tl.systime-my-local
.
.tl.systime-
* simply returns the current systime converted
to a local time zone. .tl.systime-ut
is identical to the
MUF primitive systime
. The other three are expressed in
terms of .tl.systime-ut
and the locale conversion functions
above.
.tl.dst?
returns 0 or 1, saying whether a locale is
experiencing daylight savings time at the given local systime. This
uses an object's locale setting for the DST rule. A DST rule looks
like this:
010100:040102-0:110102-0
Each of the parts of the string between colons specifies a time that DST
swaps from being off to on. (Before the start of the string is parsed,
DST is off.) Each transition is in the format
MMDDHH[[+
|-
]W]. The
first six digits indicate the month, date and hour (in 24-hour format
using the standard time zone)
that the transition occurs at. If included, the seventh and eighth
characters indicate that from the given date, you should go back
(-
) or forwards (+
) to the next day of the
week given (0 is Sunday, 6 is Saturday), not including today. Thus the above DST rule says:
On at 00:00:00 local time January 1.This is the rule for Victoria. Note that in the southern hemisphere, the year starts in DST. The "010100:" prefix fixes that by instantly turning DST on at the first rule segment.
Off at 02:00:00 local standard time (i.e., probably 3 am summer time) first Sunday preceding April 1.
On at 02:00:00 local standard time first Sunday preceding November 1.
Note that the DST rule always works in standard time. This is why the last part of the rule above had "02" in it, not "03" (assuming that the locale's DST is one hour advanced from standard time, which in Victoria it is, but the DST rule doesn't know or care about that).
Because DST rules are a pain to set up, you can use a small number of rules which don't follow the above format, because there are global mappings from the names to the relevant rules. For instance, you can use the DST rule "USA" and you are implicitly using the global rule "040102+0:110102-0".
Parsing DST rules is expensive in terms of processor time and
instruction count. As a result, any time you do a daylight savings
test, the time of the test and its result are stored on the object in
case you need to make a test for the same time the next time you need to
check this object's DST status (it turns out that this is much more
common than you might think). This DST cache is considered valid for
times one minute either side of the time for which it was calculated.
Note that any timelib function which uses local time,
including the .tl.systime-
* macros, do DST checks.
.tl.leapyear?
returns 0 or 1 depending on whether the year
given to it is a leap year. .tl.mktime
builds a systime
from a series of integers indicating a time.
Say a program has the following code:
... systime "format-string" strftime ...
This string will print the time in the Muck's local time zone (even
though it looks as though it should print it in UTC). If you want it to
continue to print in the Muck's time zone, you would use:
... #0 .tl.systime-muck "format-string" .tl.strftime ...
This uses the Muck's locale, so that little has been gained from this.
However, we can equally use a player's locale for this, probably the
player running the program:
... .tl.systime-my-local "format-string" .tl.my-strftime ...
With this code, every player running the program will see the time in
its own time zone using its own locale information.
If possible, try and use a player's short and long date and time
formats, with the
.tl.
[date
|time
]-
[long
|short
][-format
]
macros.
For places with two-tiered daylight savings time it is not
possible to represent the DST rule. A fix is being considered. This
will alter the return value of .tl.dst?
. Programs should
rely on .tl.dst?
returning 0 for standard time, 1 for
daylight savings time and 2 or more for extra tiers of DST.
When converting from local time to UT
(.tl.
*-to-ut
), there is an ambiguity
around the time when DST ends and the clock is wound back. For
instance, if the clock is wound back at 3 am summer time to 2 am
standard time, then there exists a period of one hour from 2 to 3 am
which exists twice that day (once with DST on and once with it off).
timelib always assumes in this case that DST is off. Likewise, when the
clock is wound forward at the start of DST there is a time from 2 to 3
am which doesn't exist at all. If a time inside that period is given
(it shouldn't occur naturally), then timelib assumes that DST
is on. These are merely arbitrary decisions which make the function
local-to-ut easier to write.
Converting local time to UTC is a somewhat expensive operation in terms of processor time and instruction count. This is why the DST cache was introduced. However, the cache could theoretically be out of date by up to a minute, so be prepared for unexpected results near to a DST transition.
.tl.mktime
doesn't do any bounds checking.