seconds: use new libc date api
This commit is contained in:
parent
6d3a2e6531
commit
c834f535b7
1 changed files with 87 additions and 439 deletions
|
@ -1,466 +1,114 @@
|
||||||
/*
|
|
||||||
* seconds absolute_date ... - convert absolute_date to seconds since epoch
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
typedef ulong Time;
|
char *knownfmt[] = {
|
||||||
|
/* asctime */
|
||||||
enum {
|
"WW MMM DD hh:mm:ss ?Z YYYY",
|
||||||
AM, PM, HR24,
|
/* RFC3339 */
|
||||||
|
"YYYY-MM-DD[T]hh:mm:ss[Z]?Z",
|
||||||
/* token types */
|
"YYYY-MM-DD[T]hh:mm:ss[Z]?Z",
|
||||||
Month = 1,
|
"YYYY-MM-DD[T]hh:mm:ss ?Z",
|
||||||
Year,
|
"YYYY-MM-DD[T]hh:mm:ss?Z",
|
||||||
Day,
|
nil,
|
||||||
Timetok,
|
|
||||||
Tz,
|
|
||||||
Dtz,
|
|
||||||
Ignore,
|
|
||||||
Ampm,
|
|
||||||
|
|
||||||
Maxtok = 6, /* only this many chars are stored in datetktbl */
|
|
||||||
Maxdateflds = 25,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
char *datefmt[] = {
|
||||||
* macros for squeezing values into low 7 bits of "value".
|
/* RFC5322 */
|
||||||
* all timezones we care about are divisible by 10, and the largest value
|
"?W ?DD ?MMM ?YYYY",
|
||||||
* (780) when divided is 78.
|
"?W, DD-?MM-YY",
|
||||||
*/
|
/* RFC822/RFC2822 */
|
||||||
#define TOVAL(tp, v) ((tp)->value = (v) / 10)
|
"DD MMM YYYY",
|
||||||
#define FROMVAL(tp) ((tp)->value * 10) /* uncompress */
|
"DD MMM YY",
|
||||||
|
/* RFC850 */
|
||||||
|
"WW, DD-MMM-YY",
|
||||||
|
/* RFC1123 */
|
||||||
|
"WWW, DD MMM YYYY",
|
||||||
|
/* RFC 3339 and human-readable variants */
|
||||||
|
"YYYY-MM-DD",
|
||||||
|
"YYYY-MM-DD [@] ",
|
||||||
|
/* random formats */
|
||||||
|
"?W ?MMM ?DD ?YYYY",
|
||||||
|
"?MMM ?DD ?YYYY",
|
||||||
|
"?DD ?MM ?YYYY",
|
||||||
|
"MMM ?DD ?YYYY",
|
||||||
|
"YYYY ?MM ?DD",
|
||||||
|
"YYYY ?DD ?MM",
|
||||||
|
"YYYY/MM?/DD?",
|
||||||
|
"MMM YYYY ?DD",
|
||||||
|
"?DD YYYY MMM",
|
||||||
|
"MM/DD/YYYY",
|
||||||
|
nil
|
||||||
|
};
|
||||||
|
|
||||||
/* keep this struct small since we have an array of them */
|
char *timefmt[] = {
|
||||||
typedef struct {
|
" hh:mm:ss",
|
||||||
char token[Maxtok];
|
" hh:mm",
|
||||||
char type;
|
" hh",
|
||||||
schar value;
|
" hh:mm:ss ?A",
|
||||||
} Datetok;
|
" hh:mm ?A",
|
||||||
|
" hh ?A",
|
||||||
|
"",
|
||||||
|
nil,
|
||||||
|
};
|
||||||
|
|
||||||
int dtok_numparsed;
|
char *zonefmt[] = {
|
||||||
|
" ?Z",
|
||||||
|
"",
|
||||||
|
nil,
|
||||||
|
};
|
||||||
|
|
||||||
/* forwards */
|
|
||||||
Datetok *datetoktype(char *s, int *bigvalp);
|
|
||||||
|
|
||||||
static Datetok datetktbl[];
|
|
||||||
static unsigned szdatetktbl;
|
|
||||||
|
|
||||||
/* parse 1- or 2-digit number, advance *cpp past it */
|
|
||||||
static int
|
|
||||||
eatnum(char **cpp)
|
|
||||||
{
|
|
||||||
int c, x;
|
|
||||||
char *cp;
|
|
||||||
|
|
||||||
cp = *cpp;
|
|
||||||
c = *cp;
|
|
||||||
if (!isascii(c) || !isdigit(c))
|
|
||||||
return -1;
|
|
||||||
x = c - '0';
|
|
||||||
|
|
||||||
c = *++cp;
|
|
||||||
if (isascii(c) && isdigit(c)) {
|
|
||||||
x = 10*x + c - '0';
|
|
||||||
cp++;
|
|
||||||
}
|
|
||||||
*cpp = cp;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return -1 on failure */
|
|
||||||
int
|
|
||||||
parsetime(char *time, Tm *tm)
|
|
||||||
{
|
|
||||||
tm->hour = eatnum(&time);
|
|
||||||
if (tm->hour == -1 || *time++ != ':')
|
|
||||||
return -1; /* only hour; too short */
|
|
||||||
|
|
||||||
tm->min = eatnum(&time);
|
|
||||||
if (tm->min == -1)
|
|
||||||
return -1;
|
|
||||||
if (*time++ != ':') {
|
|
||||||
tm->sec = 0;
|
|
||||||
return 0; /* no seconds; okay */
|
|
||||||
}
|
|
||||||
|
|
||||||
tm->sec = eatnum(&time);
|
|
||||||
if (tm->sec == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* this may be considered too strict. garbage at end of time? */
|
|
||||||
return *time == '\0' || isascii(*time) && isspace(*time)? 0: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* try to parse pre-split timestr in fields as an absolute date
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tryabsdate(char **fields, int nf, Tm *now, Tm *tm)
|
|
||||||
{
|
|
||||||
int i, mer = HR24, bigval = -1;
|
|
||||||
long flg = 0, ty;
|
|
||||||
Datetok *tp;
|
|
||||||
|
|
||||||
now = localtime(time(0)); /* default to local time (zone) */
|
|
||||||
tm->tzoff = now->tzoff;
|
|
||||||
strncpy(tm->zone, now->zone, sizeof tm->zone);
|
|
||||||
|
|
||||||
tm->mday = tm->mon = tm->year = -1; /* mandatory */
|
|
||||||
tm->hour = tm->min = tm->sec = 0;
|
|
||||||
dtok_numparsed = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < nf; i++) {
|
|
||||||
if (fields[i][0] == '\0')
|
|
||||||
continue;
|
|
||||||
tp = datetoktype(fields[i], &bigval);
|
|
||||||
ty = (1L << tp->type) & ~(1L << Ignore);
|
|
||||||
if (flg & ty)
|
|
||||||
return -1; /* repeated type */
|
|
||||||
flg |= ty;
|
|
||||||
switch (tp->type) {
|
|
||||||
case Year:
|
|
||||||
tm->year = bigval;
|
|
||||||
if (tm->year < 1970 || tm->year > 2106)
|
|
||||||
return -1; /* can't represent in ulong */
|
|
||||||
/* convert 4-digit year to 1900 origin */
|
|
||||||
if (tm->year >= 1900)
|
|
||||||
tm->year -= 1900;
|
|
||||||
break;
|
|
||||||
case Day:
|
|
||||||
tm->mday = bigval;
|
|
||||||
break;
|
|
||||||
case Month:
|
|
||||||
tm->mon = tp->value - 1; /* convert to zero-origin */
|
|
||||||
break;
|
|
||||||
case Timetok:
|
|
||||||
if (parsetime(fields[i], tm) < 0)
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case Dtz:
|
|
||||||
case Tz:
|
|
||||||
/* tm2sec mangles timezones, so we do our own handling */
|
|
||||||
tm->tzoff = FROMVAL(tp);
|
|
||||||
snprint(tm->zone, sizeof(tm->zone), "GMT");
|
|
||||||
break;
|
|
||||||
case Ignore:
|
|
||||||
break;
|
|
||||||
case Ampm:
|
|
||||||
mer = tp->value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1; /* bad token type: CANTHAPPEN */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tm->year == -1 || tm->mon == -1 || tm->mday == -1)
|
|
||||||
return -1; /* missing component */
|
|
||||||
if (mer == PM)
|
|
||||||
tm->hour += 12;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
prsabsdate(char *timestr, Tm *now, Tm *tm)
|
|
||||||
{
|
|
||||||
int nf;
|
|
||||||
char *fields[Maxdateflds];
|
|
||||||
static char delims[] = "- \t\n/,";
|
|
||||||
|
|
||||||
nf = gettokens(timestr, fields, nelem(fields), delims+1);
|
|
||||||
if (nf > nelem(fields))
|
|
||||||
return -1;
|
|
||||||
if (tryabsdate(fields, nf, now, tm) < 0) {
|
|
||||||
char *p = timestr;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* could be a DEC-date; glue it all back together, split it
|
|
||||||
* with dash as a delimiter and try again. Yes, this is a
|
|
||||||
* hack, but so are DEC-dates.
|
|
||||||
*/
|
|
||||||
while (--nf > 0) {
|
|
||||||
while (*p++ != '\0')
|
|
||||||
;
|
|
||||||
p[-1] = ' ';
|
|
||||||
}
|
|
||||||
nf = gettokens(timestr, fields, nelem(fields), delims);
|
|
||||||
if (nf > nelem(fields) || tryabsdate(fields, nf, now, tm) < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
validtm(Tm *tm)
|
|
||||||
{
|
|
||||||
if (tm->year < 0 || tm->mon < 0 || tm->mon > 11 ||
|
|
||||||
tm->mday < 1 || tm->hour < 0 || tm->hour >= 24 ||
|
|
||||||
tm->min < 0 || tm->min > 59 ||
|
|
||||||
tm->sec < 0 || tm->sec > 61) /* allow 2 leap seconds */
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Time
|
|
||||||
seconds(char *timestr)
|
|
||||||
{
|
|
||||||
Tm date;
|
|
||||||
|
|
||||||
memset(&date, 0, sizeof date);
|
|
||||||
if (prsabsdate(timestr, localtime(time(0)), &date) < 0)
|
|
||||||
return -1;
|
|
||||||
return validtm(&date)? tm2sec(&date) - 60*date.tzoff: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
convert(char *timestr)
|
|
||||||
{
|
|
||||||
char *copy;
|
|
||||||
Time tstime;
|
|
||||||
|
|
||||||
copy = strdup(timestr);
|
|
||||||
if (copy == nil)
|
|
||||||
sysfatal("out of memory");
|
|
||||||
tstime = seconds(copy);
|
|
||||||
free(copy);
|
|
||||||
if (tstime == -1) {
|
|
||||||
fprint(2, "%s: `%s' not a valid date\n", argv0, timestr);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
print("%lud\n", tstime);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
fprint(2, "usage: %s date-time ...\n", argv0);
|
fprint(2, "usage: %s [-f fmt] date-time/win m...\n", argv0);
|
||||||
exits("usage");
|
exits("usage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* seconds absolute_date ... - convert absolute_date to seconds since epoch
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i, sts;
|
char **f, **df, **tf, **zf, *fmt, *ep, buf[256];
|
||||||
|
Tzone *tz;
|
||||||
|
Tm tm;
|
||||||
|
int i;
|
||||||
|
|
||||||
sts = 0;
|
fmt = nil;
|
||||||
ARGBEGIN{
|
ARGBEGIN{
|
||||||
|
case 'f':
|
||||||
|
fmt = EARGF(usage());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
}ARGEND
|
}ARGEND;
|
||||||
if (argc == 0)
|
|
||||||
usage();
|
|
||||||
for (i = 0; i < argc; i++)
|
|
||||||
sts |= convert(argv[i]);
|
|
||||||
exits(sts != 0? "bad": 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
if((tz = tzload("local")) == nil)
|
||||||
* Binary search -- from Knuth (6.2.1) Algorithm B. Special case like this
|
sysfatal("bad local time: %r");
|
||||||
* is WAY faster than the generic bsearch().
|
for(i = 0; i < argc; i++){
|
||||||
*/
|
if(fmt != nil){
|
||||||
Datetok *
|
if(tmparse(&tm, fmt, argv[i], tz, &ep) != nil && *ep == 0)
|
||||||
datebsearch(char *key, Datetok *base, unsigned nel)
|
goto Found;
|
||||||
{
|
}else{
|
||||||
int cmp;
|
for(f = knownfmt; *f != nil; f++)
|
||||||
Datetok *last = base + nel - 1, *pos;
|
if(tmparse(&tm, *f, argv[i], tz, &ep) != nil && *ep == 0)
|
||||||
|
goto Found;
|
||||||
while (last >= base) {
|
for(df = datefmt; *df; df++)
|
||||||
pos = base + ((last - base) >> 1);
|
for(tf = timefmt; *tf; tf++)
|
||||||
cmp = key[0] - pos->token[0];
|
for(zf = zonefmt; *zf; zf++){
|
||||||
if (cmp == 0) {
|
snprint(buf, sizeof(buf), "%s%s%s", *df, *tf, *zf);
|
||||||
cmp = strncmp(key, pos->token, Maxtok);
|
if(tmparse(&tm, buf, argv[i], tz, &ep) != nil && *ep == 0)
|
||||||
if (cmp == 0)
|
goto Found;
|
||||||
return pos;
|
}
|
||||||
}
|
}
|
||||||
if (cmp < 0)
|
if(*ep == 0)
|
||||||
last = pos - 1;
|
sysfatal("tmparse: %r");
|
||||||
else
|
else
|
||||||
base = pos + 1;
|
sysfatal("tmparse: trailing junk");
|
||||||
|
Found:
|
||||||
|
print("%lld\n", tmnorm(&tm));
|
||||||
}
|
}
|
||||||
return 0;
|
exits(nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datetok *
|
|
||||||
datetoktype(char *s, int *bigvalp)
|
|
||||||
{
|
|
||||||
char *cp = s;
|
|
||||||
char c = *cp;
|
|
||||||
static Datetok t;
|
|
||||||
Datetok *tp = &t;
|
|
||||||
|
|
||||||
if (isascii(c) && isdigit(c)) {
|
|
||||||
int len = strlen(cp);
|
|
||||||
|
|
||||||
if (len > 3 && (cp[1] == ':' || cp[2] == ':'))
|
|
||||||
tp->type = Timetok;
|
|
||||||
else {
|
|
||||||
if (bigvalp != nil)
|
|
||||||
*bigvalp = atoi(cp); /* won't fit in tp->value */
|
|
||||||
if (len == 4)
|
|
||||||
tp->type = Year;
|
|
||||||
else if (++dtok_numparsed == 1)
|
|
||||||
tp->type = Day;
|
|
||||||
else
|
|
||||||
tp->type = Year;
|
|
||||||
}
|
|
||||||
} else if (c == '-' || c == '+') {
|
|
||||||
int val = atoi(cp + 1);
|
|
||||||
int hr = val / 100;
|
|
||||||
int min = val % 100;
|
|
||||||
|
|
||||||
val = hr*60 + min;
|
|
||||||
TOVAL(tp, c == '-'? -val: val);
|
|
||||||
tp->type = Tz;
|
|
||||||
} else {
|
|
||||||
char lowtoken[Maxtok+1];
|
|
||||||
char *ltp = lowtoken, *endltp = lowtoken+Maxtok;
|
|
||||||
|
|
||||||
/* copy to lowtoken to avoid modifying s */
|
|
||||||
while ((c = *cp++) != '\0' && ltp < endltp)
|
|
||||||
*ltp++ = (isascii(c) && isupper(c)? tolower(c): c);
|
|
||||||
*ltp = '\0';
|
|
||||||
tp = datebsearch(lowtoken, datetktbl, szdatetktbl);
|
|
||||||
if (tp == nil) {
|
|
||||||
tp = &t;
|
|
||||||
tp->type = Ignore;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* to keep this table reasonably small, we divide the lexval for Tz and Dtz
|
|
||||||
* entries by 10 and truncate the text field at MAXTOKLEN characters.
|
|
||||||
* the text field is not guaranteed to be NUL-terminated.
|
|
||||||
*/
|
|
||||||
static Datetok datetktbl[] = {
|
|
||||||
/* text token lexval */
|
|
||||||
"acsst", Dtz, 63, /* Cent. Australia */
|
|
||||||
"acst", Tz, 57, /* Cent. Australia */
|
|
||||||
"adt", Dtz, -18, /* Atlantic Daylight Time */
|
|
||||||
"aesst", Dtz, 66, /* E. Australia */
|
|
||||||
"aest", Tz, 60, /* Australia Eastern Std Time */
|
|
||||||
"ahst", Tz, 60, /* Alaska-Hawaii Std Time */
|
|
||||||
"am", Ampm, AM,
|
|
||||||
"apr", Month, 4,
|
|
||||||
"april", Month, 4,
|
|
||||||
"ast", Tz, -24, /* Atlantic Std Time (Canada) */
|
|
||||||
"at", Ignore, 0, /* "at" (throwaway) */
|
|
||||||
"aug", Month, 8,
|
|
||||||
"august", Month, 8,
|
|
||||||
"awsst", Dtz, 54, /* W. Australia */
|
|
||||||
"awst", Tz, 48, /* W. Australia */
|
|
||||||
"bst", Tz, 6, /* British Summer Time */
|
|
||||||
"bt", Tz, 18, /* Baghdad Time */
|
|
||||||
"cadt", Dtz, 63, /* Central Australian DST */
|
|
||||||
"cast", Tz, 57, /* Central Australian ST */
|
|
||||||
"cat", Tz, -60, /* Central Alaska Time */
|
|
||||||
"cct", Tz, 48, /* China Coast */
|
|
||||||
"cdt", Dtz, -30, /* Central Daylight Time */
|
|
||||||
"cet", Tz, 6, /* Central European Time */
|
|
||||||
"cetdst", Dtz, 12, /* Central European Dayl.Time */
|
|
||||||
"cst", Tz, -36, /* Central Standard Time */
|
|
||||||
"dec", Month, 12,
|
|
||||||
"decemb", Month, 12,
|
|
||||||
"dnt", Tz, 6, /* Dansk Normal Tid */
|
|
||||||
"dst", Ignore, 0,
|
|
||||||
"east", Tz, -60, /* East Australian Std Time */
|
|
||||||
"edt", Dtz, -24, /* Eastern Daylight Time */
|
|
||||||
"eet", Tz, 12, /* East. Europe, USSR Zone 1 */
|
|
||||||
"eetdst", Dtz, 18, /* Eastern Europe */
|
|
||||||
"est", Tz, -30, /* Eastern Standard Time */
|
|
||||||
"feb", Month, 2,
|
|
||||||
"februa", Month, 2,
|
|
||||||
"fri", Ignore, 5,
|
|
||||||
"friday", Ignore, 5,
|
|
||||||
"fst", Tz, 6, /* French Summer Time */
|
|
||||||
"fwt", Dtz, 12, /* French Winter Time */
|
|
||||||
"gmt", Tz, 0, /* Greenwish Mean Time */
|
|
||||||
"gst", Tz, 60, /* Guam Std Time, USSR Zone 9 */
|
|
||||||
"hdt", Dtz, -54, /* Hawaii/Alaska */
|
|
||||||
"hmt", Dtz, 18, /* Hellas ? ? */
|
|
||||||
"hst", Tz, -60, /* Hawaii Std Time */
|
|
||||||
"idle", Tz, 72, /* Intl. Date Line, East */
|
|
||||||
"idlw", Tz, -72, /* Intl. Date Line, West */
|
|
||||||
"ist", Tz, 12, /* Israel */
|
|
||||||
"it", Tz, 22, /* Iran Time */
|
|
||||||
"jan", Month, 1,
|
|
||||||
"januar", Month, 1,
|
|
||||||
"jst", Tz, 54, /* Japan Std Time,USSR Zone 8 */
|
|
||||||
"jt", Tz, 45, /* Java Time */
|
|
||||||
"jul", Month, 7,
|
|
||||||
"july", Month, 7,
|
|
||||||
"jun", Month, 6,
|
|
||||||
"june", Month, 6,
|
|
||||||
"kst", Tz, 54, /* Korea Standard Time */
|
|
||||||
"ligt", Tz, 60, /* From Melbourne, Australia */
|
|
||||||
"mar", Month, 3,
|
|
||||||
"march", Month, 3,
|
|
||||||
"may", Month, 5,
|
|
||||||
"mdt", Dtz, -36, /* Mountain Daylight Time */
|
|
||||||
"mest", Dtz, 12, /* Middle Europe Summer Time */
|
|
||||||
"met", Tz, 6, /* Middle Europe Time */
|
|
||||||
"metdst", Dtz, 12, /* Middle Europe Daylight Time*/
|
|
||||||
"mewt", Tz, 6, /* Middle Europe Winter Time */
|
|
||||||
"mez", Tz, 6, /* Middle Europe Zone */
|
|
||||||
"mon", Ignore, 1,
|
|
||||||
"monday", Ignore, 1,
|
|
||||||
"mst", Tz, -42, /* Mountain Standard Time */
|
|
||||||
"mt", Tz, 51, /* Moluccas Time */
|
|
||||||
"ndt", Dtz, -15, /* Nfld. Daylight Time */
|
|
||||||
"nft", Tz, -21, /* Newfoundland Standard Time */
|
|
||||||
"nor", Tz, 6, /* Norway Standard Time */
|
|
||||||
"nov", Month, 11,
|
|
||||||
"novemb", Month, 11,
|
|
||||||
"nst", Tz, -21, /* Nfld. Standard Time */
|
|
||||||
"nt", Tz, -66, /* Nome Time */
|
|
||||||
"nzdt", Dtz, 78, /* New Zealand Daylight Time */
|
|
||||||
"nzst", Tz, 72, /* New Zealand Standard Time */
|
|
||||||
"nzt", Tz, 72, /* New Zealand Time */
|
|
||||||
"oct", Month, 10,
|
|
||||||
"octobe", Month, 10,
|
|
||||||
"on", Ignore, 0, /* "on" (throwaway) */
|
|
||||||
"pdt", Dtz, -42, /* Pacific Daylight Time */
|
|
||||||
"pm", Ampm, PM,
|
|
||||||
"pst", Tz, -48, /* Pacific Standard Time */
|
|
||||||
"sadt", Dtz, 63, /* S. Australian Dayl. Time */
|
|
||||||
"sast", Tz, 57, /* South Australian Std Time */
|
|
||||||
"sat", Ignore, 6,
|
|
||||||
"saturd", Ignore, 6,
|
|
||||||
"sep", Month, 9,
|
|
||||||
"sept", Month, 9,
|
|
||||||
"septem", Month, 9,
|
|
||||||
"set", Tz, -6, /* Seychelles Time ?? */
|
|
||||||
"sst", Dtz, 12, /* Swedish Summer Time */
|
|
||||||
"sun", Ignore, 0,
|
|
||||||
"sunday", Ignore, 0,
|
|
||||||
"swt", Tz, 6, /* Swedish Winter Time */
|
|
||||||
"thu", Ignore, 4,
|
|
||||||
"thur", Ignore, 4,
|
|
||||||
"thurs", Ignore, 4,
|
|
||||||
"thursd", Ignore, 4,
|
|
||||||
"tue", Ignore, 2,
|
|
||||||
"tues", Ignore, 2,
|
|
||||||
"tuesda", Ignore, 2,
|
|
||||||
"ut", Tz, 0,
|
|
||||||
"utc", Tz, 0,
|
|
||||||
"wadt", Dtz, 48, /* West Australian DST */
|
|
||||||
"wast", Tz, 42, /* West Australian Std Time */
|
|
||||||
"wat", Tz, -6, /* West Africa Time */
|
|
||||||
"wdt", Dtz, 54, /* West Australian DST */
|
|
||||||
"wed", Ignore, 3,
|
|
||||||
"wednes", Ignore, 3,
|
|
||||||
"weds", Ignore, 3,
|
|
||||||
"wet", Tz, 0, /* Western Europe */
|
|
||||||
"wetdst", Dtz, 6, /* Western Europe */
|
|
||||||
"wst", Tz, 48, /* West Australian Std Time */
|
|
||||||
"ydt", Dtz, -48, /* Yukon Daylight Time */
|
|
||||||
"yst", Tz, -54, /* Yukon Standard Time */
|
|
||||||
"zp4", Tz, -24, /* GMT +4 hours. */
|
|
||||||
"zp5", Tz, -30, /* GMT +5 hours. */
|
|
||||||
"zp6", Tz, -36, /* GMT +6 hours. */
|
|
||||||
};
|
|
||||||
static unsigned szdatetktbl = nelem(datetktbl);
|
|
||||||
|
|
Loading…
Reference in a new issue