📄 timefmt.y
字号:
{ "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 */ { "bt", tZONE, -HOUR(3) }, /* Baghdad */ { "it", tZONE, -(HOUR(3)+30) }, /* Iran */ { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */ { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */ { "ist", tZONE, -(HOUR(5)+30) }, /* Indian Standard */ { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */ { "nst", tZONE, -HOUR(7) }, /* North Sumatra */ { "sst", tZONE, -HOUR(7) }, /* South Sumatra */ { "jt", tZONE, -(HOUR(7)+30) }, /* Java (3pm in Cronusland!) */ { "nzt", tZONE, -HOUR(12) }, /* New Zealand */ { "idle", tZONE, -HOUR(12) }, /* International Date Line East */ { "cat", tZONE, HOUR(10) }, /* -- expired 1967 */ { "nt", tZONE, HOUR(11) }, /* -- expired 1967 */ { "ahst", tZONE, HOUR(10) }, /* -- expired 1983 */ { "hdt", tDAYZONE, HOUR(10) }, /* -- expired 1986 */#endif /* 0 */};/* ARGSUSED */static voiddate_error(s) char *s;{ /* NOTREACHED */}static time_tToSeconds(Hours, Minutes, Seconds, Meridian) time_t Hours; time_t Minutes; time_t Seconds; MERIDIAN Meridian;{ if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 61) return -1; if (Meridian == MER24) { if (Hours < 0 || Hours > 23) return -1; } else { if (Hours < 1 || Hours > 12) return -1; if (Meridian == MERpm) Hours += 12; } return (Hours * 60L + Minutes) * 60L + Seconds;}static time_tConvert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, dst) time_t Month; time_t Day; time_t Year; time_t Hours; time_t Minutes; time_t Seconds; MERIDIAN Meridian; DSTMODE dst;{ static int DaysNormal[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static int DaysLeap[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static int LeapYears[] = { 1972, 1976, 1980, 1984, 1988, 1992, 1996, 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036 }; register int *yp; register int *mp; register time_t Julian; register int i; time_t tod; if (Year < 0) Year = -Year; if (Year < 100) Year += 1900; if (Year < EPOCH) Year += 100; for (mp = DaysNormal, yp = LeapYears; yp < ENDOF(LeapYears); yp++) if (Year == *yp) { mp = DaysLeap; break; } if (Year < EPOCH || Year > END_OF_TIME || Month < 1 || Month > 12 /* NOSTRICT *//* conversion from long may lose accuracy */ || Day < 1 || Day > mp[(int)Month]) return -1; Julian = Day - 1 + (Year - EPOCH) * 365; for (yp = LeapYears; yp < ENDOF(LeapYears); yp++, Julian++) if (Year <= *yp) break; for (i = 1; i < Month; i++) Julian += *++mp; Julian *= SECSPERDAY; Julian += yyTimezone * 60L; if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0) return -1; Julian += tod; tod = Julian; if (dst == DSTon || (dst == DSTmaybe && localtime(&tod)->tm_isdst)) Julian -= DST_OFFSET * 60 * 60; return Julian;}static time_tDSTcorrect(Start, Future) 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) * DST_OFFSET * 60 * 60;}static time_tRelativeMonth(Start, RelMonth) time_t Start; time_t RelMonth;{ struct tm *tm; time_t Month; time_t Year; tm = localtime(&Start); Month = 12 * tm->tm_year + tm->tm_mon + RelMonth; Year = Month / 12; 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));}static intLookupWord(buff, length) char *buff; register int length;{ register char *p; register STRING q; register TABLE *tp; register int c; p = buff; c = p[0]; /* See if we have an abbreviation for a month. */ if (length == 3 || (length == 4 && p[3] == '.')) for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) { q = tp->name; if (c == q[0] && p[1] == q[1] && p[2] == q[2]) { yylval.Number = tp->value; return tp->type; } } else for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) if (c == tp->name[0] && strcmp(p, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } /* Try for a timezone. */ for (tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++) if (c == tp->name[0] && p[1] == tp->name[1] && strcmp(p, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } /* Try the units table. */ for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++) if (c == tp->name[0] && strcmp(p, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } /* Strip off any plural and try the units table again. */ if (--length > 0 && p[length] == 's') { p[length] = '\0'; for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++) if (c == tp->name[0] && strcmp(p, tp->name) == 0) { p[length] = 's'; yylval.Number = tp->value; return tp->type; } p[length] = 's'; } length++; /* Drop out any periods. */ for (p = buff, q = (STRING)buff; *q; q++) if (*q != '.') *p++ = *q; *p = '\0'; /* Try the meridians. */ if (buff[1] == 'm' && buff[2] == '\0') { if (buff[0] == 'a') { yylval.Meridian = MERam; return tMERIDIAN; } if (buff[0] == 'p') { yylval.Meridian = MERpm; return tMERIDIAN; } } /* If we saw any periods, try the timezones again. */ if (p - buff != length) { c = buff[0]; for (p = buff, tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++) if (c == tp->name[0] && p[1] == tp->name[1] && strcmp(p, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } } /* Unknown word -- assume GMT timezone. */ yylval.Number = 0; return tZONE;}static intdate_lex(){ register char c; register char *p; char buff[20]; register int sign; register int i; register int nesting; for ( ; ; ) { /* Get first character after the whitespace. */ for ( ; ; ) { while (CTYPE(isspace, *yyInput)) yyInput++; c = *yyInput; /* Ignore RFC 822 comments, typically time zone names. */ if (c != LPAREN) break; for (nesting = 1; (c = *++yyInput) != RPAREN || --nesting; ) if (c == LPAREN) nesting++; else if (!IS7BIT(c) || c == '\0' || c == '\r' || (c == '\\' && ((c = *++yyInput) == '\0' || !IS7BIT(c)))) /* Lexical error: bad comment. */ return '?'; yyInput++; } /* A number? */ if (CTYPE(isdigit, c) || c == '-' || c == '+') { if (c == '-' || c == '+') { sign = c == '-' ? -1 : 1; yyInput++; if (!CTYPE(isdigit, *yyInput)) /* Skip the plus or minus sign. */ continue; } else sign = 0; for (i = 0; (c = *yyInput++) != '\0' && CTYPE(isdigit, c); ) i = 10 * i + c - '0'; yyInput--; yylval.Number = sign < 0 ? -i : i; return sign ? tSNUMBER : tUNUMBER; } /* A word? */ if (CTYPE(isalpha, c)) { for (p = buff; (c = *yyInput++) == '.' || CTYPE(isalpha, c); ) if (p < &buff[sizeof buff - 1]) *p++ = CTYPE(isupper, c) ? tolower(c) : c; *p = '\0'; yyInput--; return LookupWord(buff, p - buff); } return *yyInput++; }}intGetTimeInfo(Now) TIMEINFO *Now;{ static time_t LastTime; static long LastTzone; struct tm *tm;#if defined(DO_HAVE_GETTIMEOFDAY) struct timeval tv;#endif /* defined(DO_HAVE_GETTIMEOFDAY) */#if !defined(WITH_TM_GMTOFF)# define DONT_HAVE_TM_GMTOFF#endif#if defined(DONT_HAVE_TM_GMTOFF) struct tm local; struct tm gmt;#endif /* !defined(DONT_HAVE_TM_GMTOFF) */ /* Get the basic time. */#if defined(DO_HAVE_GETTIMEOFDAY) if (gettimeofday(&tv, (struct timezone *)NULL) == -1) return -1; Now->time = tv.tv_sec; Now->usec = tv.tv_usec;#else /* Can't check for -1 since that might be a time, I guess. */ (void)time(&Now->time); Now->usec = 0;#endif /* defined(DO_HAVE_GETTIMEOFDAY) */ /* Now get the timezone if it's been an hour since the last time. */ if (Now->time - LastTime > 60 * 60) { LastTime = Now->time; if ((tm = localtime(&Now->time)) == NULL) return -1;#if defined(DONT_HAVE_TM_GMTOFF) /* To get the timezone, compare localtime with GMT. */ local = *tm; if ((tm = gmtime(&Now->time)) == NULL) return -1; gmt = *tm; /* Assume we are never more than 24 hours away. */ LastTzone = gmt.tm_yday - local.tm_yday; if (LastTzone > 1) LastTzone = -24; else if (LastTzone < -1) LastTzone = 24; else LastTzone *= 24; /* Scale in the hours and minutes; ignore seconds. */ LastTzone += gmt.tm_hour - local.tm_hour; LastTzone *= 60; LastTzone += gmt.tm_min - local.tm_min;#else LastTzone = (0 - tm->tm_gmtoff) / 60;#endif /* defined(DONT_HAVE_TM_GMTOFF) */ } Now->tzone = LastTzone; return 0;}time_tparsedate(p, now) char *p; TIMEINFO *now;{ extern int date_parse(); struct tm *tm; TIMEINFO ti; time_t Start; yyInput = p; if (now == NULL) { now = &ti; (void)GetTimeInfo(&ti); } tm = localtime(&now->time); yyYear = tm->tm_year; yyMonth = tm->tm_mon + 1; yyDay = tm->tm_mday; yyTimezone = now->tzone; yyDSTmode = DSTmaybe; yyHour = 0; yyMinutes = 0; yySeconds = 0; yyMeridian = MER24; yyRelSeconds = 0; yyRelMonth = 0; yyHaveDate = 0; yyHaveRel = 0; yyHaveTime = 0; if (date_parse() || yyHaveTime > 1 || yyHaveDate > 1) return -1; if (yyHaveDate || yyHaveTime) { Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds, yyMeridian, yyDSTmode); if (Start < 0) return -1; } else { Start = now->time; if (!yyHaveRel) Start -= (tm->tm_hour * 60L + tm->tm_min) * 60L + tm->tm_sec; } Start += yyRelSeconds; if (yyRelMonth) Start += RelativeMonth(Start, yyRelMonth); /* 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -