mirror of
https://github.com/PDP-10/its.git
synced 2026-01-11 23:53:12 +00:00
Binary-only compiler and library, plus documentation and include files for compiling new programs.
270 lines
10 KiB
Plaintext
Executable File
270 lines
10 KiB
Plaintext
Executable File
NAME
|
||
time_parse - parse free-format date/time string
|
||
|
||
SYNOPSIS
|
||
#include <timex.h>
|
||
|
||
int time_parse(char *str, struct tmx *tmx, char **endptr);
|
||
|
||
struct tmx {
|
||
struct tm tm; /* See ctime(3) for definition */
|
||
struct tmz tmz; /* See time_lzone(3X) for definition */
|
||
char *tmx_err; /* NULL or pointer to error message */
|
||
int tmx_flags; /* Flags for possible future uses */
|
||
};
|
||
#define TMX_NULL (-1) /* Unspecified items are given this value */
|
||
|
||
|
||
DESCRIPTION
|
||
|
||
time_parse() accepts a null-terminated date/time string,
|
||
"str", and parses it to fill out the specified TMX structure, "tmx".
|
||
If "endptr" is not null, it is always set to point to the remainder
|
||
(if any) of the string not consumed by time_parse(). The "time_make()"
|
||
function can be used to derive a UNIX time word of type "time_t" from the
|
||
resulting TMX structure.
|
||
|
||
The integer return value is used to help indicate overall
|
||
success or failure. A negative value means that the parse stopped due
|
||
to conflicting specifications or ambiguous keywords, which usually
|
||
means an error; otherwise, the value is the number of non-break tokens
|
||
successfully scanned, which may be 0. Whenever the parse did not
|
||
reach the end of the string for whatever reason, the char pointer
|
||
"tmx_err" will be non-NULL and will point to a short constant message
|
||
string describing the reason.
|
||
|
||
INPUT
|
||
|
||
"time_parse()" is intended to parse all reasonable date and/or
|
||
time formats, specifically including everything that the TOPS-20/TENEX
|
||
IDTNC JSYS will accept. The function is actually much more flexible
|
||
than this since it will tolerate most cases of arbitrarily ordered,
|
||
delimited, and duplicated items; it makes use of contextual clues to
|
||
heuristically determine the meaning of numerical tokens.
|
||
|
||
The string is parsed into tokens which are either numbers or
|
||
keywords, separated by punctuation break characters. Keywords may be
|
||
in any case and need only have enough of the word to uniquely identify
|
||
it. Whitespace serves to delimit tokens but is otherwise ignored.
|
||
The parse will stop when it encounters a keyword which cannot be
|
||
identified (unknown or ambiguous), or encounters a character that is
|
||
not one of the valid date/time punctuation chars: "()-,/:." plus space
|
||
and tab. It will also stop if the only plausible interpretation of
|
||
a token leads to a clash with already parsed values.
|
||
For maximum flexibility, the parsing is deliberately as
|
||
forgiving as possible, and will accept ANY construct as long as it can
|
||
make some sense out of it, regardless of how bizarre the string looks
|
||
to a human. It is guaranteed to correctly parse all strings which are
|
||
"well formatted", but it cannot be used to enforce a specific syntax
|
||
and its interpretation of some inherently ambiguous strings may not be
|
||
what the user expects.
|
||
|
||
The following are examples of acceptable formats (most taken
|
||
from the TOPS-20/TENEX documentation). They are shown as dates and
|
||
times; a string may have only one of these, or it may have both in
|
||
either order, and sometimes their tokens can intermingle.
|
||
Dates Times
|
||
6-Feb-76 12:34:56 or 1234:56 or 123456
|
||
Feb-6-76 12:34 or 1234
|
||
Feb 6 76 16:30 or 1630 or 4:30pm
|
||
Feb 6, 1976 1:23 or 123 or 0123
|
||
6 Feb 76 1:56AM
|
||
6.2.1976 1:56-EST or 1:56 EST or 0156AM EST
|
||
2/6/76 NOON
|
||
1976-02-06 12:00AM or 12 AM or 12-am or MIDNIGHT
|
||
Wedn Febru 6 1976 5-STD or 0500-STANDARD
|
||
1976 We Fe 6 12:30-DAYLIGHT
|
||
|
||
Combined:
|
||
Fri Nov 13 13:08:02 PDT 1981 (output of ctime())
|
||
Monday, May 24, 1987 3:22:23am-PST (03:22:23) (output of T20 daytime)
|
||
Wed 2 Dec 87 09:18:44 PST (RFC822 format)
|
||
10-Nov-52 12:34-CDT
|
||
2:25 AM, December 25, 2025
|
||
Tues-PDT,(1988)8PM..AugUS 8 Tu (free-format example)
|
||
|
||
Note that any USA timezone abbreviation is allowed, plus GMT, UT,
|
||
and whatever else has been added to the keyword table.
|
||
|
||
DIAGNOSTICS
|
||
To summarize all possible return situations:
|
||
|
||
Value tmx_err **endptr Meaning
|
||
< 0 set start of bad token Parse stopped due to clashing specs
|
||
or ambiguous keyword.
|
||
>= 0 NULL '\0' String was completely parsed.
|
||
>= 0 set start of invalid token String was not completely parsed.
|
||
(if isalpha(**endptr) is
|
||
true, this is an unknown
|
||
keyword)
|
||
|
||
Return-value:
|
||
The exact quantity expressed by a positive return
|
||
value is not useful for most purposes; it represents the number of
|
||
valid numerical or alpha (keyword) tokens that the scan parsed. This
|
||
often but not always corresponds to the number of entries in "tmx"
|
||
that were set. A zero return value always indicates that the scan
|
||
halted before finding any such valid tokens, and nothing in the "tmx"
|
||
structure was set.
|
||
|
||
tmx_err:
|
||
The "tmx_err" member of "tmx" will be NULL if the parse scanned
|
||
the entire string, otherwise it will be set. Note that the setting of
|
||
this variable, as well as the sign of the return value, does not
|
||
necessarily reflect either success or failure; it is up to the
|
||
application program to interpret the results.
|
||
|
||
endptr:
|
||
The "endptr" return value provides another way to see what
|
||
terminated the scan, since it points to the first character of
|
||
whatever token stopped it. This will be '\0' at the end of the
|
||
string, and if **endptr is an alpha character then the token was an
|
||
unidentified or ambiguous keyword.
|
||
|
||
tmx:
|
||
NOTE!! Although a "tm" structure is included in the "tmx"
|
||
structure, the values it contains are not completely consistent with
|
||
the way "tm" structures are used by the C library functions. There
|
||
are two differences:
|
||
|
||
(1) If a structure member was not specified by the date/time string,
|
||
it is given the value TMX_NULL, defined in <timex.h>, which matches
|
||
no valid value for any member. In particular the "tm.tm_yday"
|
||
member will always be set to TMX_NULL since there is no standard
|
||
convention for specifying it in a text string.
|
||
|
||
(2) The "tm.tm_year" member is set to whatever year value the
|
||
string specifies. This may be 87, or 1987, or any other number.
|
||
This conflicts with the C library interpretation where 0 is the
|
||
year 1900.
|
||
|
||
In fact, time_parse() can be used to merely initialize a
|
||
"tmx" structure, by invoking it like this:
|
||
time_parse((char *)0, &tmx, (char *)0);
|
||
The time_make() function can be used to completely
|
||
canonicalize the structure so that the "tm" substructure is then
|
||
acceptable to the standard C library functions.
|
||
|
||
It is important to remember that time_parse() does not, in
|
||
general, attempt to verify the correctness of the resulting "tmx"
|
||
structure. Cross-checking is limited primarily to ensuring that duplicate
|
||
specifications are identical, e.g. if the weekday is seen twice, it
|
||
must have the same value or the parse fails. time_make() will perform
|
||
the necessary content checking to derive a valid "time_t" time.
|
||
|
||
SEE ALSO
|
||
time_make(3X), time_lzone(3X), ctime(3), time(2)
|
||
|
||
AUTHOR
|
||
Ken Harrenstien, SRI International
|
||
<KLH@SRI-NIC.ARPA> 415/859-6552
|
||
|
||
NAME
|
||
time_make - derive a "time_t" time value from a parsed time
|
||
|
||
SYNOPSIS
|
||
#include <timex.h>
|
||
|
||
time_t time_make(struct tmx *tmx);
|
||
|
||
|
||
DESCRIPTION
|
||
|
||
"time_make" can be considered the inverse of "localtime"; it
|
||
takes a broken-down time description and returns a UNIX-format time
|
||
value of type "time_t". Note that it works only on "tmx" structures,
|
||
not "tm" structures.
|
||
|
||
It is possible to have unspecified (TMX_NULL) values in the
|
||
structure, which time_make() will attempt to default reasonably:
|
||
|
||
Member Default value if unspecified
|
||
tm.tm_year Current year.
|
||
tm.tm_mon 0 (Jan) if year specified, else current month.
|
||
tm.tm_mday 1 if month specified, else current mday.
|
||
tm.tm_hour 0
|
||
tm.tm_min 0
|
||
tm.tm_sec 0
|
||
tmz.tm_secwest tmz.tm_minwest * 60
|
||
tmz.tm_minwest local timezone
|
||
tm.tm_isdst 0 if timezone not local. If local,
|
||
applies local DST algorithm.
|
||
|
||
For example, "July 10" will default the year to its current
|
||
value (e.g. 1987), and the time to 00:00:00. Just giving "1980" will
|
||
produce "Jan 1, 1980 00:00:00".
|
||
The timezone, which is specified by tmz.tm_secwest, defaults
|
||
to tmz.tm_minwest*60 which in turn defaults to the local timezone. A
|
||
value of 1 for either variable is interpreted as an explicit request to
|
||
use the local timezone.
|
||
If tm.tm_isdst is set to 0, daylight savings time (DST) is never
|
||
applied. If set to 1 (to represent USA DST) then DST is always applied
|
||
(by subtracting one hour). If not specified, no DST is applied unless
|
||
the timezone is that of the local timezone, in which case DST is applied
|
||
if appropriate (determined by consulting localtime()).
|
||
|
||
The "tm.tm_yday" (day of year) entry is not used to compute
|
||
the time unless neither the month nor day are specified. The
|
||
"tm.tm_wday" (day of week) entry is never used. However, specifying
|
||
either of these values will cause them to be checked, and time_make()
|
||
will fail if the values conflict with the other date specifications.
|
||
|
||
DIAGNOSTICS
|
||
-1 is returned on failure, which is usually due to a parameter
|
||
being out of range. A failure return will always set "tmx_err" in the
|
||
tmx structure to point to a short constant error message. This variable
|
||
is cleared to NULL for a successful return.
|
||
|
||
SEE ALSO
|
||
time_parse(3X), time_lzone(3X), ctime(3), time(2)
|
||
|
||
AUTHOR
|
||
Ken Harrenstien, SRI International
|
||
<KLH@SRI-NIC.ARPA> 415/859-6552
|
||
|
||
NAME
|
||
time_lzone - get local timezone information
|
||
time_tzset - set local timezone information from system
|
||
|
||
SYNOPSIS
|
||
#include <timex.h>
|
||
|
||
int time_lzone(struct tmz *tmz);
|
||
|
||
int time_tzset(void);
|
||
|
||
struct tmz {
|
||
long tmz_secwest; /* Secs west of GMT (-12/+12 hrs) */
|
||
int tmz_minwest; /* Same, in mins. (tmz_secwest/60) */
|
||
int tmz_dsttype; /* DST type if any (0 = none, 1 = USA) */
|
||
char *tmz_name; /* Standard timezone name */
|
||
char *tmz_dname; /* DST timezone name (if any) */
|
||
};
|
||
|
||
DESCRIPTION
|
||
|
||
"time_lzone()" fills out the structure pointed to. It
|
||
does this by copying the contents of the static area indicated by
|
||
time_tzset(), which it calls if necessary.
|
||
|
||
"time_tzset()" attempts to get the local timezone information
|
||
from the system or environment (this is system dependent) and uses
|
||
this to set (or re-initialize) its static TMZ structure. If
|
||
successful, a pointer to this structure is returned; if it could not
|
||
be initialized, NULL is returned. It is not necessary to invoke this
|
||
function explicitly unless the program has some reason to believe that
|
||
the timezone may have changed during execution.
|
||
|
||
SEE ALSO
|
||
time_make(3X), time_parse(3X), ctime(3), time(2)
|
||
|
||
BUGS
|
||
Time zones are a big mess, especially on Unix where there are
|
||
several incompatible (and unportable) methods of tracking them.
|
||
These functions attempt to standardize the information more sensibly.
|
||
|
||
AUTHOR
|
||
Ken Harrenstien, SRI International
|
||
<KLH@SRI-NIC.ARPA> 415/859-6552
|
||
|