📄 getdate.y
字号:
{ "hdt", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */
{ "cat", tZONE, HOUR(10) }, /* Central Alaska */
{ "ahst", tZONE, HOUR(10) }, /* Alaska-Hawaii Standard */
{ "nt", tZONE, HOUR(11) }, /* Nome */
{ "idlw", tZONE, HOUR(12) }, /* International Date Line West */
{ "cet", tZONE, -HOUR(1) }, /* Central European */
{ "met", tZONE, -HOUR(1) }, /* Middle European */
{ "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */
{ "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */
{ "swt", tZONE, -HOUR(1) }, /* Swedish Winter */
{ "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */
{ "fwt", tZONE, -HOUR(1) }, /* French Winter */
{ "fst", tDAYZONE, -HOUR(1) }, /* French Summer */
{ "eet", tZONE, -HOUR(2) }, /* Eastern Europe, USSR Zone 1 */
{ "bt", tZONE, -HOUR(3) }, /* Baghdad, USSR Zone 2 */
#if 0
{ "it", tZONE, -HOUR(3.5) },/* Iran */
#endif
{ "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */
{ "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */
#if 0
{ "ist", tZONE, -HOUR(5.5) },/* Indian Standard */
#endif
{ "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */
#if 0
/* For completeness. NST is also Newfoundland Stanard, and SST is
* also Swedish Summer. */
{ "nst", tZONE, -HOUR(6.5) },/* North Sumatra */
{ "sst", tZONE, -HOUR(7) }, /* South Sumatra, USSR Zone 6 */
#endif /* 0 */
{ "wast", tZONE, -HOUR(7) }, /* West Australian Standard */
{ "wadt", tDAYZONE, -HOUR(7) }, /* West Australian Daylight */
#if 0
{ "jt", tZONE, -HOUR(7.5) },/* Java (3pm in Cronusland!) */
#endif
{ "cct", tZONE, -HOUR(8) }, /* China Coast, USSR Zone 7 */
{ "jst", tZONE, -HOUR(9) }, /* Japan Standard, USSR Zone 8 */
#if 0
{ "cast", tZONE, -HOUR(9.5) },/* Central Australian Standard */
{ "cadt", tDAYZONE, -HOUR(9.5) },/* Central Australian Daylight */
#endif
{ "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */
{ "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */
{ "gst", tZONE, -HOUR(10) }, /* Guam Standard, USSR Zone 9 */
{ "nzt", tZONE, -HOUR(12) }, /* New Zealand */
{ "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */
{ "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */
{ "idle", tZONE, -HOUR(12) }, /* International Date Line East */
{ NULL }
};
/* Military timezone table. */
static TABLE const MilitaryTable[] = {
{ "a", tMILZONE, HOUR( 1) },
{ "b", tMILZONE, HOUR( 2) },
{ "c", tMILZONE, HOUR( 3) },
{ "d", tMILZONE, HOUR( 4) },
{ "e", tMILZONE, HOUR( 5) },
{ "f", tMILZONE, HOUR( 6) },
{ "g", tMILZONE, HOUR( 7) },
{ "h", tMILZONE, HOUR( 8) },
{ "i", tMILZONE, HOUR( 9) },
{ "k", tMILZONE, HOUR( 10) },
{ "l", tMILZONE, HOUR( 11) },
{ "m", tMILZONE, HOUR( 12) },
{ "n", tMILZONE, HOUR(- 1) },
{ "o", tMILZONE, HOUR(- 2) },
{ "p", tMILZONE, HOUR(- 3) },
{ "q", tMILZONE, HOUR(- 4) },
{ "r", tMILZONE, HOUR(- 5) },
{ "s", tMILZONE, HOUR(- 6) },
{ "t", tMILZONE, HOUR(- 7) },
{ "u", tMILZONE, HOUR(- 8) },
{ "v", tMILZONE, HOUR(- 9) },
{ "w", tMILZONE, HOUR(-10) },
{ "x", tMILZONE, HOUR(-11) },
{ "y", tMILZONE, HOUR(-12) },
{ "z", tZONE, HOUR( 0) }, /* Deliberately tZONE */
{ NULL }
};
static int LookupWord(char * buff, YYSTYPE * yylval)
{
register char *p;
register char *q;
register const TABLE *tp;
int i;
int abbrev;
/* Make it lowercase. */
for (p = buff; *p != '\0'; p++)
*p = (char)tolower(*p);
if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
yylval->Meridian = MERam;
return tMERIDIAN;
}
if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
yylval->Meridian = MERpm;
return tMERIDIAN;
}
/* See if we have an abbreviation for a month. */
if (strlen(buff) == 3)
abbrev = 1;
else if (strlen(buff) == 4 && buff[3] == '.') {
abbrev = 1;
buff[3] = '\0';
}
else
abbrev = 0;
for (tp = MonthDayTable; tp->name; tp++) {
if (abbrev) {
if (strncmp(buff, tp->name, 3) == 0) {
yylval->Number = tp->value;
return tp->type;
}
}
else if (strcmp(buff, tp->name) == 0) {
yylval->Number = tp->value;
return tp->type;
}
}
for (tp = TimezoneTable; tp->name; tp++)
if (strcmp(buff, tp->name) == 0) {
yylval->Number = tp->value;
return tp->type;
}
if (strcmp(buff, "dst") == 0)
return tDST;
for (tp = UnitsTable; tp->name; tp++)
if (strcmp(buff, tp->name) == 0) {
yylval->Number = tp->value;
return tp->type;
}
/* Strip off any plural and try the units table again. */
i = strlen(buff) - 1;
if (buff[i] == 's') {
buff[i] = '\0';
for (tp = UnitsTable; tp->name; tp++)
if (strcmp(buff, tp->name) == 0) {
yylval->Number = tp->value;
return tp->type;
}
buff[i] = 's'; /* Put back for "this" in OtherTable. */
}
for (tp = OtherTable; tp->name; tp++)
if (strcmp(buff, tp->name) == 0) {
yylval->Number = tp->value;
return tp->type;
}
/* Military timezones. */
if (buff[1] == '\0' && isalpha(*buff)) {
for (tp = MilitaryTable; tp->name; tp++)
if (strcmp(buff, tp->name) == 0) {
yylval->Number = tp->value;
return tp->type;
}
}
/* Drop out any periods and try the timezone table again. */
for (i = 0, p = q = buff; *q; q++)
if (*q != '.')
*p++ = *q;
else
i++;
*p = '\0';
if (i)
for (tp = TimezoneTable; tp->name; tp++)
if (strcmp(buff, tp->name) == 0) {
yylval->Number = tp->value;
return tp->type;
}
for (i = 1; i <= 12; i++)
for (abbrev = 0; abbrev < 2; abbrev++)
if (PTimeIsMonthName(buff, i, abbrev)) {
yylval->Number = i;
return tMONTH;
}
for (i = 1; i <= 7; i++)
for (abbrev = 0; abbrev < 2; abbrev++)
if (PTimeIsDayName(buff, i, abbrev)) {
yylval->Number = i;
return tDAY;
}
return tID;
}
#ifdef _MSC_VER
#pragma warning(disable:4211)
#endif
#ifndef __GNUC__
static
#endif
int yylex(YYSTYPE * yylval, void * yyInput)
{
register char *p;
char buff[20];
int Count;
int sign;
register int c = PTimeGetChar(yyInput);
while (c != EOF && c != '\0' && c != '\n') {
while (isspace(c))
c = PTimeGetChar(yyInput);
if (isdigit(c) || c == '-' || c == '+') {
if (c == '-' || c == '+') {
sign = c == '-' ? -1 : 1;
if (!isdigit(c = PTimeGetChar(yyInput)))
/* skip the '-' sign */
continue;
}
else
sign = 0;
yylval->Number = 0;
Count = 0; /* Count number of digits */
while (isdigit(c)) {
yylval->Number = 10 * yylval->Number + c - '0';
c = PTimeGetChar(yyInput);
Count++;
}
PTimeUngetChar(yyInput, c);
if (sign < 0)
yylval->Number = -yylval->Number;
if (sign)
return tSNUMBER;
if (Count == 4)
return t4DIGITNUMBER;
if (Count == 6)
return t6DIGITNUMBER;
return tUNUMBER;
}
if (isalpha(c)) {
for (p = buff; isalpha(c) || c == '.'; c = PTimeGetChar(yyInput)) {
if (p < &buff[sizeof(buff)-1])
*p++ = (char)c;
}
*p = '\0';
PTimeUngetChar(yyInput, c);
return LookupWord(buff, yylval);
}
if (c != '(')
return c;
Count = 0;
do {
c = PTimeGetChar(yyInput);
if (c == '\0' || c == EOF)
return c;
if (c == '(')
Count++;
else if (c == ')')
Count--;
} while (Count > 0);
}
return EOF;
}
#ifdef _MSC_VER
#pragma warning(default:4211)
#endif
static time_t ToSeconds(time_t Hours, time_t Minutes, time_t Seconds,
MERIDIAN Meridian)
{
if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
return -1;
switch (Meridian) {
case MER24:
if (Hours < 0 || Hours > 23)
return -1;
return (Hours * 60L + Minutes) * 60L + Seconds;
case MERam:
if (Hours < 1 || Hours > 12)
return -1;
if (Hours == 12)
Hours = 0;
return (Hours * 60L + Minutes) * 60L + Seconds;
case MERpm:
if (Hours < 1 || Hours > 12)
return -1;
if (Hours == 12)
Hours = 0;
return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
}
return -1;
}
static time_t Convert(time_t Month, time_t Day, time_t Year,
time_t Hours, time_t Minutes, time_t Seconds,
MERIDIAN Meridian, DSTMODE DSTmode, time_t yyTimezone)
{
static int DaysInMonth[12] = {
31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
time_t tod;
time_t Julian;
int i;
if (Year < 0)
Year = -Year;
if (Year < 70)
Year += 2000;
else if (Year < 100)
Year += 1900;
DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
? 29 : 28;
/* 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. */
if (Year < EPOCH || Year > 2038
|| Month < 1 || Month > 12
/* Lint fluff: "conversion from long may lose accuracy" */
|| Day < 1 || Day > DaysInMonth[(int)--Month])
return -1;
for (Julian = Day - 1, i = 0; i < Month; i++)
Julian += DaysInMonth[i];
for (i = EPOCH; i < Year; i++)
Julian += 365 + (i % 4 == 0);
Julian *= SECSPERDAY;
Julian += yyTimezone * 60L;
if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
return -1;
Julian += tod;
if (DSTmode == DSTon
|| (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
Julian -= 60 * 60;
return Julian;
}
static time_t DSTcorrect(time_t Start, time_t Future)
{
time_t StartDay;
time_t FutureDay;
StartDay = (localtime(&Start)->tm_hour + 1) % 24;
FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
}
static time_t RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber)
{
struct tm *tm;
time_t now;
now = Start;
tm = localtime(&now);
now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
return DSTcorrect(Start, now);
}
static time_t RelativeMonth(time_t Start, time_t RelMonth, time_t yyTimezone)
{
struct tm *tm;
time_t Month;
time_t Year;
if (RelMonth == 0)
return 0;
tm = localtime(&Start);
Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
Year = Month / 12 + 1900;
Month = Month % 12 + 1;
return DSTcorrect(Start,
Convert(Month, (time_t)tm->tm_mday, Year,
(time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
MER24, DSTmaybe, yyTimezone));
}
static void SetPossibleDate(struct Variables * var,
time_t possible_day,
time_t possible_month,
time_t possible_year)
{
int date_order;
if (possible_day > 31) /* test for ymd */
date_order = 2;
else if (possible_day > 12) /* test for dmy */
date_order = 1;
else if (possible_month > 12) /* test for mdy */
date_order = 0;
else {
static int default_date_order = -1;
if (default_date_order < 0)
default_date_order = PTimeGetDateOrder();
date_order = default_date_order;
}
switch (date_order) {
case 0 :
var->yyDay = possible_month;
var->yyMonth = possible_day;
var->yyYear = possible_year;
break;
case 1 :
var->yyDay = possible_day;
var->yyMonth = possible_month;
var->yyYear = possible_year;
break;
default :
var->yyDay = possible_year;
var->yyMonth = possible_month;
var->yyYear = possible_day;
}
}
time_t STDAPICALLTYPE PTimeParse(void * inputStream, struct tm * now, int timezone)
{
time_t Start;
struct Variables var;
var.yyInput = inputStream;
var.yyYear = now->tm_year + 1900;
var.yyMonth = now->tm_mon + 1;
var.yyDay = now->tm_mday;
var.yyTimezone = -timezone;
var.yyDSTmode = DSTmaybe;
var.yyHour = 0;
var.yyMinutes = 0;
var.yySeconds = 0;
var.yyMeridian = MER24;
var.yyRelSeconds = 0;
var.yyRelMonth = 0;
var.yyHaveDate = 0;
var.yyHaveDay = 0;
var.yyHaveRel = 0;
var.yyHaveTime = 0;
var.yyHaveZone = 0;
yyparse(&var);
if (var.yyHaveTime > 1 || var.yyHaveZone > 1 ||
var.yyHaveDate > 1 || var.yyHaveDay > 1)
return -1;
if (var.yyHaveTime == 0 && var.yyHaveZone == 0 &&
var.yyHaveDate == 0 && var.yyHaveDay == 0 && var.yyHaveRel == 0)
return -1;
if (var.yyHaveDate || var.yyHaveTime || var.yyHaveDay) {
Start = Convert(var.yyMonth, var.yyDay, var.yyYear,
var.yyHour, var.yyMinutes, var.yySeconds,
var.yyMeridian, var.yyDSTmode, var.yyTimezone);
if (Start < 0)
return -1;
}
else {
time(&Start);
if (!var.yyHaveRel)
Start -= ((now->tm_hour * 60L + now->tm_min) * 60L) + now->tm_sec;
}
Start += var.yyRelSeconds;
Start += RelativeMonth(Start, var.yyRelMonth, var.yyTimezone);
if (var.yyHaveDay && !var.yyHaveDate)
Start += RelativeDate(Start, var.yyDayOrdinal, var.yyDayNumber);
/* Have to do *something* with a legitimate -1 so it's distinguishable
* from the error return value. (Alternately could set errno on error.) */
return Start == -1 ? 0 : Start;
}
#ifdef _MSC_VER
#pragma warning(disable:4100 4211)
#endif
#ifdef __GNUC__
int yyerror(const char * s)
{
return 0;
}
#else
static void yyerror(const char * s)
{
}
#endif
#ifdef _MSC_VER
#pragma warning(default:4100 4211)
#endif
/* End of file ***************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -