version 1.2, 2005/03/24 03:07:04 |
version 1.3, 2005/03/24 15:40:43 |
|
|
|
|
#include "log.h" |
#include "log.h" |
|
|
#define EPOCH 1970 |
#define YEAR_EPOCH 1970 |
|
#define YEAR_TMORIGIN 1900 |
#define HOUR(x) ((time_t)(x) * 60) |
#define HOUR(x) ((time_t)(x) * 60) |
#define SECSPERDAY (24L * 60L * 60L) |
#define SECSPERDAY (24L * 60L * 60L) |
|
|
|
|
; |
; |
|
|
item : time { |
item : time { |
yyHaveTime++; |
yyHaveTime++; |
} |
} |
| zone { |
| zone { |
yyHaveZone++; |
yyHaveZone++; |
} |
} |
| date { |
| date { |
yyHaveDate++; |
yyHaveDate++; |
} |
} |
| day { |
| day { |
yyHaveDay++; |
yyHaveDay++; |
} |
} |
| rel { |
| rel { |
yyHaveRel++; |
yyHaveRel++; |
} |
} |
| number |
| number |
; |
; |
|
|
time : tUNUMBER tMERIDIAN { |
time : tUNUMBER tMERIDIAN { |
yyHour = $1; |
yyHour = $1; |
yyMinutes = 0; |
yyMinutes = 0; |
yySeconds = 0; |
yySeconds = 0; |
yyMeridian = $2; |
yyMeridian = $2; |
} |
} |
| tUNUMBER ':' tUNUMBER o_merid { |
| tUNUMBER ':' tUNUMBER o_merid { |
yyHour = $1; |
yyHour = $1; |
yyMinutes = $3; |
yyMinutes = $3; |
yySeconds = 0; |
yySeconds = 0; |
yyMeridian = $4; |
yyMeridian = $4; |
} |
} |
| tUNUMBER ':' tUNUMBER tSNUMBER { |
| tUNUMBER ':' tUNUMBER tSNUMBER { |
yyHour = $1; |
yyHour = $1; |
yyMinutes = $3; |
yyMinutes = $3; |
yyMeridian = MER24; |
yyMeridian = MER24; |
yyDSTmode = DSToff; |
yyDSTmode = DSToff; |
yyTimezone = - ($4 % 100 + ($4 / 100) * 60); |
yyTimezone = - ($4 % 100 + ($4 / 100) * 60); |
} |
} |
| tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid { |
| tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid { |
yyHour = $1; |
yyHour = $1; |
yyMinutes = $3; |
yyMinutes = $3; |
yySeconds = $5; |
yySeconds = $5; |
yyMeridian = $6; |
yyMeridian = $6; |
} |
} |
| tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER { |
| tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER { |
yyHour = $1; |
yyHour = $1; |
yyMinutes = $3; |
yyMinutes = $3; |
yySeconds = $5; |
yySeconds = $5; |
yyMeridian = MER24; |
yyMeridian = MER24; |
yyDSTmode = DSToff; |
yyDSTmode = DSToff; |
yyTimezone = - ($6 % 100 + ($6 / 100) * 60); |
yyTimezone = - ($6 % 100 + ($6 / 100) * 60); |
} |
} |
; |
; |
|
|
zone : tZONE { |
zone : tZONE { |
yyTimezone = $1; |
yyTimezone = $1; |
yyDSTmode = DSToff; |
yyDSTmode = DSToff; |
} |
} |
| tDAYZONE { |
| tDAYZONE { |
yyTimezone = $1; |
yyTimezone = $1; |
yyDSTmode = DSTon; |
yyDSTmode = DSTon; |
} |
} |
| |
| tZONE tDST { |
tZONE tDST { |
yyTimezone = $1; |
yyTimezone = $1; |
yyDSTmode = DSTon; |
yyDSTmode = DSTon; |
|
} |
} |
; |
; |
|
|
day : tDAY { |
day : tDAY { |
yyDayOrdinal = 1; |
yyDayOrdinal = 1; |
yyDayNumber = $1; |
yyDayNumber = $1; |
} |
} |
| tDAY ',' { |
| tDAY ',' { |
yyDayOrdinal = 1; |
yyDayOrdinal = 1; |
yyDayNumber = $1; |
yyDayNumber = $1; |
} |
} |
| tUNUMBER tDAY { |
| tUNUMBER tDAY { |
yyDayOrdinal = $1; |
yyDayOrdinal = $1; |
yyDayNumber = $2; |
yyDayNumber = $2; |
} |
} |
; |
; |
|
|
date : tUNUMBER '/' tUNUMBER { |
date : tUNUMBER '/' tUNUMBER { |
yyMonth = $1; |
|
yyDay = $3; |
|
} |
|
| tUNUMBER '/' tUNUMBER '/' tUNUMBER { |
|
if ($1 >= 100) { |
|
yyYear = $1; |
|
yyMonth = $3; |
|
yyDay = $5; |
|
} else { |
|
yyMonth = $1; |
yyMonth = $1; |
yyDay = $3; |
yyDay = $3; |
yyYear = $5; |
|
} |
|
} |
} |
| tUNUMBER tSNUMBER tSNUMBER { |
| tUNUMBER '/' tUNUMBER '/' tUNUMBER { |
/* ISO 8601 format. yyyy-mm-dd. */ |
if ($1 >= 100) { |
yyYear = $1; |
yyYear = $1; |
yyMonth = -$2; |
yyMonth = $3; |
yyDay = -$3; |
yyDay = $5; |
|
} else { |
|
yyMonth = $1; |
|
yyDay = $3; |
|
yyYear = $5; |
|
} |
} |
} |
|
| tUNUMBER tSNUMBER tSNUMBER { |
|
/* ISO 8601 format. yyyy-mm-dd. */ |
|
yyYear = $1; |
|
yyMonth = -$2; |
|
yyDay = -$3; |
|
} |
| tUNUMBER tMONTH tSNUMBER { |
| tUNUMBER tMONTH tSNUMBER { |
/* e.g. 17-JUN-1992. */ |
/* e.g. 17-JUN-1992. */ |
yyDay = $1; |
yyDay = $1; |
yyMonth = $2; |
yyMonth = $2; |
yyYear = -$3; |
yyYear = -$3; |
} |
} |
| tMONTH tUNUMBER { |
| tMONTH tUNUMBER { |
yyMonth = $1; |
yyMonth = $1; |
yyDay = $2; |
yyDay = $2; |
} |
} |
| tMONTH tUNUMBER ',' tUNUMBER { |
| tMONTH tUNUMBER ',' tUNUMBER { |
yyMonth = $1; |
yyMonth = $1; |
yyDay = $2; |
yyDay = $2; |
yyYear = $4; |
yyYear = $4; |
} |
} |
| tUNUMBER tMONTH { |
| tUNUMBER tMONTH { |
yyMonth = $2; |
yyMonth = $2; |
yyDay = $1; |
yyDay = $1; |
} |
} |
| tUNUMBER tMONTH tUNUMBER { |
| tUNUMBER tMONTH tUNUMBER { |
yyMonth = $2; |
yyMonth = $2; |
yyDay = $1; |
yyDay = $1; |
yyYear = $3; |
yyYear = $3; |
} |
} |
; |
; |
|
|
rel : relunit tAGO { |
rel : relunit tAGO { |
yyRelSeconds = -yyRelSeconds; |
yyRelSeconds = -yyRelSeconds; |
yyRelMonth = -yyRelMonth; |
yyRelMonth = -yyRelMonth; |
} |
} |
| relunit |
| relunit |
; |
; |
|
|
relunit : tUNUMBER tMINUTE_UNIT { |
relunit : tUNUMBER tMINUTE_UNIT { |
yyRelSeconds += $1 * $2 * 60L; |
yyRelSeconds += $1 * $2 * 60L; |
} |
} |
| tSNUMBER tMINUTE_UNIT { |
| tSNUMBER tMINUTE_UNIT { |
yyRelSeconds += $1 * $2 * 60L; |
yyRelSeconds += $1 * $2 * 60L; |
} |
} |
| tMINUTE_UNIT { |
| tMINUTE_UNIT { |
yyRelSeconds += $1 * 60L; |
yyRelSeconds += $1 * 60L; |
} |
} |
| tSNUMBER tSEC_UNIT { |
| tSNUMBER tSEC_UNIT { |
yyRelSeconds += $1; |
yyRelSeconds += $1; |
} |
} |
| tUNUMBER tSEC_UNIT { |
| tUNUMBER tSEC_UNIT { |
yyRelSeconds += $1; |
yyRelSeconds += $1; |
} |
} |
| tSEC_UNIT { |
| tSEC_UNIT { |
yyRelSeconds++; |
yyRelSeconds++; |
} |
} |
| tSNUMBER tMONTH_UNIT { |
| tSNUMBER tMONTH_UNIT { |
yyRelMonth += $1 * $2; |
yyRelMonth += $1 * $2; |
} |
} |
| tUNUMBER tMONTH_UNIT { |
| tUNUMBER tMONTH_UNIT { |
yyRelMonth += $1 * $2; |
yyRelMonth += $1 * $2; |
} |
} |
| tMONTH_UNIT { |
| tMONTH_UNIT { |
yyRelMonth += $1; |
yyRelMonth += $1; |
} |
} |
; |
; |
|
|
number : tUNUMBER { |
number : tUNUMBER { |
if (yyHaveTime && yyHaveDate && !yyHaveRel) |
if (yyHaveTime && yyHaveDate && !yyHaveRel) |
yyYear = $1; |
yyYear = $1; |
else { |
else { |
if($1>10000) { |
if ($1 > 10000) { |
yyHaveDate++; |
yyHaveDate++; |
yyDay= ($1)%100; |
yyDay= ($1)%100; |
yyMonth= ($1/100)%100; |
yyMonth= ($1/100)%100; |
yyYear = $1/10000; |
yyYear = $1/10000; |
} |
} else { |
else { |
|
yyHaveTime++; |
yyHaveTime++; |
if ($1 < 100) { |
if ($1 < 100) { |
yyHour = $1; |
yyHour = $1; |
yyMinutes = 0; |
yyMinutes = 0; |
} |
} else { |
else { |
|
yyHour = $1 / 100; |
yyHour = $1 / 100; |
yyMinutes = $1 % 100; |
yyMinutes = $1 % 100; |
} |
} |
yySeconds = 0; |
yySeconds = 0; |
yyMeridian = MER24; |
yyMeridian = MER24; |
} |
|
} |
} |
|
} |
} |
} |
; |
; |
|
|
|
|
Year += 2000; |
Year += 2000; |
else if (Year < 100) { |
else if (Year < 100) { |
Year += 1900; |
Year += 1900; |
if (Year < EPOCH) |
if (Year < YEAR_EPOCH) |
Year += 100; |
Year += 100; |
} |
} |
DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) |
DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) |
? 29 : 28; |
? 29 : 28; |
/* Checking for 2038 bogusly assumes that time_t is 32 bits. But |
/* Checking for 2038 bogusly assumes that time_t is 32 bits. But |
I'm too lazy to try to check for time_t overflow in another way. */ |
I'm too lazy to try to check for time_t overflow in another way. */ |
if (Year < EPOCH || Year > 2038 || Month < 1 || Month > 12 || |
if (Year < YEAR_EPOCH || Year > 2038 || Month < 1 || Month > 12 || |
/* Lint fluff: "conversion from long may lose accuracy" */ |
/* Lint fluff: "conversion from long may lose accuracy" */ |
Day < 1 || Day > DaysInMonth[(int)--Month]) |
Day < 1 || Day > DaysInMonth[(int)--Month]) |
return (-1); |
return (-1); |
|
|
for (julian = Day - 1, i = 0; i < Month; i++) |
for (julian = Day - 1, i = 0; i < Month; i++) |
julian += DaysInMonth[i]; |
julian += DaysInMonth[i]; |
|
|
for (i = EPOCH; i < Year; i++) |
for (i = YEAR_EPOCH; i < Year; i++) |
julian += 365 + (i % 4 == 0); |
julian += 365 + (i % 4 == 0); |
julian *= SECSPERDAY; |
julian *= SECSPERDAY; |
julian += yyTimezone * 60L; |
julian += yyTimezone * 60L; |
|
|
} |
} |
} |
} |
|
|
#define TM_YEAR_ORIGIN 1900 |
|
|
|
/* Yield A - B, measured in seconds. */ |
/* Yield A - B, measured in seconds. */ |
static long |
static long |
difftm (struct tm *a, struct tm *b) |
difftm(struct tm *a, struct tm *b) |
{ |
{ |
int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); |
int ay = a->tm_year + (YEAR_TMORIGIN - 1); |
int by = b->tm_year + (TM_YEAR_ORIGIN - 1); |
int by = b->tm_year + (YEAR_TMORIGIN - 1); |
int days = ( |
int days = ( |
/* difference in day of year */ |
/* difference in day of year */ |
a->tm_yday - b->tm_yday |
a->tm_yday - b->tm_yday |