void make_answer(int* ans) { int y, m, d; y = 1 + rand() % MAX_YEAR; m = 1 + rand() % 12; d = monthdays(y, m); ans[0] = y; ans[1] = m; ans[2] = d; }
int get_first_month(int year, int month) { const int weeknum[7] = {1,2,3,4,5,6,0}; //数组的作用是对应不同余数的星期 int weeksum = yeardays(year) + monthdays(year,month) + 1; //计算这个月第一天到基准日的天数 int week = weeksum % 7; //计算这些天的星期余数 return weeknum[week]; }
int weekday(int year, int month, int day) //计算当前日期到基准日的星期 { const int weeknum[7] = {1,2,3,4,5,6,0}; int weeksum = yeardays(year) + monthdays(year,month)+ day; int week = weeksum % 7; return weeknum[week]; }
/* * Parse an RFC 3339 = ISO 8601 format date-time string. * Returns: number of characters in @s consumed, or -1 on error. */ EXPORTED int time_from_iso8601(const char *s, time_t *tp) { const char *origs = s; struct tm exp; int n, tm_off; /* parse the ISO 8601 date/time */ /* XXX should use strptime ? */ memset(&exp, 0, sizeof(struct tm)); n = sscanf(s, "%4d-%2d-%2dT%2d:%2d:%2d", &exp.tm_year, &exp.tm_mon, &exp.tm_mday, &exp.tm_hour, &exp.tm_min, &exp.tm_sec); if (n != 6) return -1; s += 19; if (*s == '.') { /* skip fractional secs */ while (Uisdigit(*(++s))); } /* handle offset */ switch (*s++) { case 'Z': tm_off = 0; break; case '-': tm_off = -1; break; case '+': tm_off = 1; break; default: return -1; } if (tm_off) { int tm_houroff, tm_minoff; n = sscanf(s, "%2d:%2d", &tm_houroff, &tm_minoff); if (n != 2) return -1; tm_off *= 60 * (60 * tm_houroff + tm_minoff); s += 5; } exp.tm_year -= 1900; /* normalize to years since 1900 */ exp.tm_mon--; /* normalize to months since January */ /* sanity check the date/time (including leap day & second) */ if (exp.tm_year < 70 || exp.tm_mon < 0 || exp.tm_mon > 11 || exp.tm_mday < 1 || exp.tm_mday > monthdays(exp.tm_year, exp.tm_mon) || exp.tm_hour > 23 || exp.tm_min > 59 || exp.tm_sec > 60) { return -1; } /* normalize to GMT */ *tp = mkgmtime(&exp) - tm_off; return s - origs; }
int returnMonthDiff(int *arr, int a, int b) { int i, sum = 0, max = 0; if (a < b){ i = a; max = b; } else{ i = b; max = a; } while (i <= max) { sum = sum + monthdays(arr, i); i++; } return sum; }
int main(void) { int total = 0; int weekday = 2; // 1901/1/1 == Tuesday for (int year = 1901; year <= 2000; year++) { for (int month = 0; month < 12; month++) { if (weekday == 0) total++; weekday = (weekday + monthdays(year, month)) % 7; } } printf("%d\n", total); return 0; }
BOOL EVAL::EvalFunction(INT nFunction, INT argc, double * argv, double * pValue) { switch( nFunction ) { case EVAL_FUNCTION_ABS: if( argc == 1 ) { * pValue = fabs( argv[0] ); return TRUE; } break; case EVAL_FUNCTION_MOD: if( argc == 2 ) { * pValue = fmod( argv[0], argv[1] ); return TRUE; } break; case EVAL_FUNCTION_CEIL: if( argc == 1 ) { * pValue = ceil( argv[0] ); return TRUE; } break; case EVAL_FUNCTION_FLOOR: if( argc == 1 ) { * pValue = floor( argv[0] ); return TRUE; } break; case EVAL_FUNCTION_ROUND: if( argc == 1 ) { * pValue = floor( argv[0] + 0.5 ); return TRUE; } break; case EVAL_FUNCTION_MIN: if( argc == 2 ) { * pValue = argv[0] < argv[1] ? argv[0] : argv[1]; return TRUE; } break; case EVAL_FUNCTION_MAX: if( argc == 2 ) { * pValue = argv[0] > argv[1] ? argv[0] : argv[1]; return TRUE; } break; case EVAL_FUNCTION_ACOS: if( argc == 1 ) { * pValue = acos(argv[0]); return TRUE; } break; case EVAL_FUNCTION_ASIN: if( argc == 1 ) { * pValue = asin(argv[0]); return TRUE; } break; case EVAL_FUNCTION_ATAN: if( argc == 1 ) { * pValue = atan(argv[0]); return TRUE; } break; case EVAL_FUNCTION_ATAN2: if( argc == 2 ) { * pValue = atan2(argv[0], argv[1]); return TRUE; } break; case EVAL_FUNCTION_COS: if( argc == 1 ) { * pValue = cos(argv[0]); return TRUE; } break; case EVAL_FUNCTION_SIN: if( argc == 1 ) { * pValue = sin(argv[0]); return TRUE; } break; case EVAL_FUNCTION_TAN: if( argc == 1 ) { * pValue = tan(argv[0]); return TRUE; } break; case EVAL_FUNCTION_COSH: if( argc == 1 ) { * pValue = cosh(argv[0]); return TRUE; } break; case EVAL_FUNCTION_SINH: if( argc == 1 ) { * pValue = sinh(argv[0]); return TRUE; } break; case EVAL_FUNCTION_TANH: if( argc == 1 ) { * pValue = tanh(argv[0]); return TRUE; } break; case EVAL_FUNCTION_EXP: if( argc == 1 ) { * pValue = exp(argv[0]); return TRUE; } break; case EVAL_FUNCTION_LOG: if( argc == 1 ) { * pValue = log(argv[0]); return TRUE; } break; case EVAL_FUNCTION_LOG10: if( argc == 1 ) { * pValue = log10(argv[0]); return TRUE; } break; case EVAL_FUNCTION_POW: if( argc == 2 ) { * pValue = pow(argv[0], argv[1]); return TRUE; } break; case EVAL_FUNCTION_SQR: if( argc == 1 ) { * pValue = argv[0] * argv[0]; return TRUE; } break; case EVAL_FUNCTION_SQRT: if( argc == 1 ) { * pValue = sqrt(argv[0]); return TRUE; } break; case EVAL_FUNCTION_TODAY: if( argc == 0 ) { * pValue = (double)today(); return TRUE; } break; case EVAL_FUNCTION_YEARDAYS: if( argc == 1 ) { * pValue = (double)yeardays((int)argv[0]); return TRUE; } break; case EVAL_FUNCTION_MONTHDAYS: if( argc == 2 ) { * pValue = (double)monthdays((int)argv[0], (int)argv[1]); return TRUE; } break; case EVAL_FUNCTION_DATE2DAYS: if( argc == 1 ) { * pValue = (double)date2days((int)argv[0]); return TRUE; } break; case EVAL_FUNCTION_DAYS2DATE: if( argc == 1 ) { * pValue = (double)days2date((int)argv[0]); return TRUE; } break; case EVAL_FUNCTION_EOMDAY: if( argc == 2 ) { * pValue = (double)eomday((int)argv[0], (int)argv[1]); return TRUE; } break; case EVAL_FUNCTION_EOMDATE: if( argc == 2 ) { * pValue = (double)eomdate((int)argv[0], (int)argv[1]); return TRUE; } break; case EVAL_FUNCTION_WEEKDAY: if( argc == 1 ) { * pValue = (double)weekday((int)argv[0]); return TRUE; } break; case EVAL_FUNCTION_ISBIZDATE: if( argc == 1 ) { * pValue = (double)isbizdate((int)argv[0], HDC_SUNSAT ); return TRUE; } if( argc == 2 ) { * pValue = (double)isbizdate((int)argv[0], (int)argv[1]); return TRUE; } break; case EVAL_FUNCTION_NBIZDATE: if( argc == 1 ) { * pValue = (double)nbizdate((int)argv[0], HDC_SUNSAT ); return TRUE; } if( argc == 2 ) { * pValue = (double)nbizdate((int)argv[0], (int)argv[1]); return TRUE; } break; case EVAL_FUNCTION_PBIZDATE: if( argc == 1 ) { * pValue = (double)pbizdate((int)argv[0], HDC_SUNSAT ); return TRUE; } if( argc == 2 ) { * pValue = (double)pbizdate((int)argv[0], (int)argv[1]); return TRUE; } break; case EVAL_FUNCTION_ADDDAYS: if( argc == 2 ) { * pValue = (double)adddays((int)argv[0], (int)argv[1]); return TRUE; } break; case EVAL_FUNCTION_ADDMONTHS: if( argc == 2 ) { * pValue = (double)addmonths((int)argv[0], (int)argv[1], EMR_ACTUAL ); return TRUE; } if( argc == 3 ) { * pValue = (double)addmonths((int)argv[0], (int)argv[1], (int)argv[2]); return TRUE; } break; case EVAL_FUNCTION_ADDTERMS: if( argc == 3 ) { * pValue = (double)addterms((int)argv[0], (int)argv[1], (int)argv[2], EMR_ACTUAL ); return TRUE; } if( argc == 4 ) { * pValue = (double)addterms((int)argv[0], (int)argv[1], (int)argv[2], (int)argv[3]); return TRUE; } break; case EVAL_FUNCTION_DAYS360: if( argc == 2 ) { * pValue = (double)days360((int)argv[0], (int)argv[1], 0 /* USA */ ); return TRUE; } if( argc == 3 ) { * pValue = (double)days360((int)argv[0], (int)argv[1], (int)argv[2]); return TRUE; } break; case EVAL_FUNCTION_DAYS365: if( argc == 2 ) { * pValue = (double)days365((int)argv[0], (int)argv[1]); return TRUE; } break; case EVAL_FUNCTION_DAYSACT: if( argc == 2 ) { * pValue = (double)daysact((int)argv[0], (int)argv[1]); return TRUE; } break; case EVAL_FUNCTION_DAYSBET: if( argc == 2 ) { * pValue = (double)daysbet((int)argv[0], (int)argv[1], DCB_ACTACT ); return TRUE; } if( argc == 3 ) { * pValue = (double)daysbet((int)argv[0], (int)argv[1], (int)argv[2]); return TRUE; } break; case EVAL_FUNCTION_MONTHSBET: if( argc == 2 ) { * pValue = (double)monthsbet((int)argv[0], (int)argv[1]); return TRUE; } break; case EVAL_FUNCTION_TERMSBET: if( argc == 3 ) { * pValue = (double)termsbet((int)argv[0], (int)argv[1], (int)argv[2]); return TRUE; } break; case EVAL_FUNCTION_TERMFRAC: if( argc == 3 ) { * pValue = termfrac((int)argv[0], (int)argv[1], (int)argv[2], DCB_ACTACT, EMR_ACTUAL ); return TRUE; } if( argc == 4 ) { * pValue = termfrac((int)argv[0], (int)argv[1], (int)argv[2], (int)argv[3], EMR_ACTUAL ); return TRUE; } if( argc == 5 ) { * pValue = termfrac((int)argv[0], (int)argv[1], (int)argv[2], (int)argv[3], (int)argv[4]); return TRUE; } break; case EVAL_FUNCTION_YEARFRAC: if( argc == 2 ) { * pValue = yearfrac((int)argv[0], (int)argv[1], DCB_ACTACT, EMR_ACTUAL ); return TRUE; } if( argc == 3 ) { * pValue = yearfrac((int)argv[0], (int)argv[1], (int)argv[2], EMR_ACTUAL ); return TRUE; } if( argc == 4 ) { * pValue = yearfrac((int)argv[0], (int)argv[1], (int)argv[2], (int)argv[3]); return TRUE; } break; } return FALSE; }
int main(int argc, char* argv[]) { int y1, m1, y2, m2; int ans[3]; int input[3]; int* records; int max_trial; int i, j; srand(time(NULL)); make_answer(ans); max_trial = (int)(log2(ans[0]) + log2(ans[1]) + log2(ans[2])); records = (int*)malloc(sizeof(int)*3*max_trial); printf("日付あてゲーム\n"); printf("正解の年/月/日を推測してください\n"); printf("年は 1 ~ %d の間です\n", MAX_YEAR); printf("答え: %5d 年 %2d 月 %2d 日\n", ans[0], ans[1], ans[2]); for (i = 0; i < max_trial; i++) { printf("%d 回目 (残り %d 回)\n", i+1, max_trial-i); while (1) { printf("年: "); scanf("%d", input); if (input[0] < 1 || input[0] > MAX_YEAR) printf("そんな年ねーよ\n"); else break; } while (1) { printf("月: "); scanf("%d", input+1); if (input[1] < 1 || input[1] > 12) printf("そんな月ねーよ\n"); else break; } while (1) { printf("日: "); scanf("%d", input+2); if (input[2] < 1 || input[2] > monthdays(input[0], input[1])) printf("そんな日ねーよ\n"); else break; } records[i] = input[0]; records[i+1] = input[1]; records[i+2] = input[2]; int chk = chk_answer(ans, input); if (chk == 0) { printf("正解!\n"); break; } printf("不正解...\n"); } printf("入力の履歴:\n"); for (j = 0; j <= i; j++) { printf("%d 回目\n", j+1); printf("%5d 年 %2d 月 %2d 日\n", records[j], records[j+1], records[j+2]); printf("正解との差\n"); printf("%5d, %2d, %2d\n", ans[0]-records[j], ans[1]-records[1], ans[2]-records[2]); } free(records); return 0; }
/* * Parse a string in IMAP date-time format (and some more * obscure legacy formats too) to a time_t. Parses both * date and time parts. * * Specific formats accepted are listed below. Note that only * the first two are compliant with RFC3501, the remainder * are legacy formats. Note that the " quotes are not part * of the format, they're just used in this comment to show * where the leading spaces are. * * "dd-mmm-yyyy HH:MM:SS zzzzz" * " d-mmm-yyyy HH:MM:SS zzzzz" * "dd-mmm-yy HH:MM:SS-z" * " d-mmm-yy HH:MM:SS-z" * "dd-mmm-yy HH:MM:SS-zz" * " d-mmm-yy HH:MM:SS-zz" * "dd-mmm-yy HH:MM:SS-zzz" * " d-mmm-yy HH:MM:SS-zzz" * * where: * dd is the day-of-month between 1 and 31 inclusive. * mmm is the three-letter abbreviation for the English * month name (case insensitive). * yy is the 2 digit year, between 00 (the year 1900) * and 99 (the year 1999) inclusive. * yyyy is the 4 digit year, between 1900 and disaster * (31b time_t wrapping in 2038 is not handled, sorry). * HH is the hour, zero padded, between 00 and 23 inclusive. * MM is the minute, zero padded, between 00 and 59 inclusive. * MM is the second, zero padded, between 00 and 60 inclusive * (to account for leap seconds). * z is a US military style single character time zone. * A (Alpha) is +0100 ... I (India) is +0900 * J (Juliet) is not defined * K (Kilo) is +1000 ... M (Mike) is +1200 * N (November) is -0100 ... Y (Yankee) is -1200 * Z (Zulu) is UTC * zz is the case-insensitive string "UT", denoting UTC time. * zzz is a three-character case insensitive North American * time zone name, one of the following (listed with the * UTC offsets and comments): * AST -0400 Atlantic Standard Time * ADT -0300 Atlantic Daylight Time * EST -0500 Eastern Standard Time * EDT -0400 Eastern Daylight Time * CST -0600 Central Standard Time * CDT -0500 Central Daylight Time * MST -0700 Mountain Standard Time * MDT -0600 Mountain Daylight Time * PST -0800 Pacific Standard Time * PDT -0700 Pacific Daylight Time * YST -0900 Yukon Standard Time * (Obsolete, now AKST = Alaska S.T.) * YDT -0800 Yukon Daylight Time * (Obsolete, now AKDT = Alaska D.T.) * HST -1000 Hawaiian Standard Time * (Obsolete, now HAST = Hawaiian/Aleutian S.T.) * HDT -0900 Hawaiian Daylight Time * (Obsolete, now HADT = Hawaiian/Aleutian D.T.) * BST -1100 Used in American Samoa & Midway Island * (Obsolete, now SST = Samoa S.T.) * BDT -1000 Nonsensical, standard time is used * all year around in the SST territories. * zzzzz is an numeric time zone offset in the form +HHMM * or -HMMM. * * Returns: Number of characters consumed from @s on success, * or -1 on error. */ EXPORTED int time_from_rfc3501(const char *s, time_t *date) { const char *origs = s; int c; struct tm tm; int old_format = 0; char month[4], zone[4], *p; time_t tmp_gmtime; int zone_off; /* timezone offset in minutes */ memset(&tm, 0, sizeof tm); /* Day of month */ c = *s++; if (c == ' ') c = '0'; else if (!isdigit(c)) goto baddate; tm.tm_mday = c - '0'; c = *s++; if (isdigit(c)) { tm.tm_mday = tm.tm_mday * 10 + c - '0'; c = *s++; if (tm.tm_mday <= 0 || tm.tm_mday > 31) goto baddate; } if (c != '-') goto baddate; c = *s++; /* Month name */ if (!isalpha(c)) goto baddate; month[0] = c; c = *s++; if (!isalpha(c)) goto baddate; month[1] = c; c = *s++; if (!isalpha(c)) goto baddate; month[2] = c; c = *s++; month[3] = '\0'; for (tm.tm_mon = 0; tm.tm_mon < 12; tm.tm_mon++) { if (!strcasecmp(month, monthname[tm.tm_mon])) break; } if (tm.tm_mon == 12) goto baddate; if (c != '-') goto baddate; c = *s++; /* Year */ if (!isdigit(c)) goto baddate; tm.tm_year = c - '0'; c = *s++; if (!isdigit(c)) goto baddate; tm.tm_year = tm.tm_year * 10 + c - '0'; c = *s++; if (isdigit(c)) { if (tm.tm_year < 19) goto baddate; tm.tm_year -= 19; tm.tm_year = tm.tm_year * 10 + c - '0'; c = *s++; if (!isdigit(c)) goto baddate; tm.tm_year = tm.tm_year * 10 + c - '0'; c = *s++; } else old_format++; if (tm.tm_mday > monthdays(tm.tm_year, tm.tm_mon)) goto baddate; /* Hour */ if (c != ' ') goto baddate; c = *s++; if (!isdigit(c)) goto baddate; tm.tm_hour = c - '0'; c = *s++; if (!isdigit(c)) goto baddate; tm.tm_hour = tm.tm_hour * 10 + c - '0'; c = *s++; if (tm.tm_hour > 23) goto baddate; /* Minute */ if (c != ':') goto baddate; c = *s++; if (!isdigit(c)) goto baddate; tm.tm_min = c - '0'; c = *s++; if (!isdigit(c)) goto baddate; tm.tm_min = tm.tm_min * 10 + c - '0'; c = *s++; if (tm.tm_min > 59) goto baddate; /* Second */ if (c != ':') goto baddate; c = *s++; if (!isdigit(c)) goto baddate; tm.tm_sec = c - '0'; c = *s++; if (!isdigit(c)) goto baddate; tm.tm_sec = tm.tm_sec * 10 + c - '0'; c = *s++; if (tm.tm_min > 60) goto baddate; /* Time zone */ if (old_format) { if (c != '-') goto baddate; c = *s++; if (!isalpha(c)) goto baddate; zone[0] = c; c = *s++; if (c == '\0') { /* Military (single-char) zones */ zone[1] = '\0'; lcase(zone); if (zone[0] <= 'i') { zone_off = (zone[0] - 'a' + 1)*60; } else if (zone[0] == 'j') { goto baddate; } else if (zone[0] <= 'm') { zone_off = (zone[0] - 'k' + 10)*60; } else if (zone[0] < 'z') { zone_off = ('m' - zone[0])*60; } else /* 'z' */ zone_off = 0; } else { /* UT (universal time) */ zone[1] = c; c = *s++; if (c == '\0') { zone[2] = '\0'; lcase(zone); if (!strcmp(zone, "ut")) goto baddate; zone_off = 0; } else { /* 3-char time zone */ zone[2] = c; c = *s++; if (c != '\0') goto baddate; zone[3] = '\0'; lcase(zone); p = strchr("aecmpyhb", zone[0]); if (c != '\0' || zone[2] != 't' || !p) goto baddate; zone_off = (strlen(p) - 12)*60; if (zone[1] == 'd') zone_off += 60; else if (zone[1] != 's') goto baddate; } } } else { if (c != ' ') goto baddate; c = *s++; if (c != '+' && c != '-') goto baddate; zone[0] = c; c = *s++; if (!isdigit(c)) goto baddate; zone_off = c - '0'; c = *s++; if (!isdigit(c)) goto baddate; zone_off = zone_off * 10 + c - '0'; c = *s++; if (!isdigit(c)) goto baddate; zone_off = zone_off * 6 + c - '0'; c = *s++; if (!isdigit(c)) goto baddate; zone_off = zone_off * 10 + c - '0'; if (zone[0] == '-') zone_off = -zone_off; c = *s++; if (c != '\0') goto baddate; } tm.tm_isdst = -1; tmp_gmtime = mkgmtime(&tm); if (tmp_gmtime == -1) goto baddate; *date = tmp_gmtime - zone_off*60; return s-1 - origs; baddate: return -1; }
static int parse_rfc822(const char *s, time_t *tp, int dayonly) { const char *origs = s; struct tm tm; time_t t; char month[4]; int zone_off = 0; if (!s) goto baddate; memset(&tm, 0, sizeof(tm)); s = skip_fws(s); if (!s) goto baddate; if (Uisalpha(*s)) { /* Day name -- skip over it */ s++; if (!Uisalpha(*s)) goto baddate; s++; if (!Uisalpha(*s)) goto baddate; s++; s = skip_fws(s); if (!s || *s++ != ',') goto baddate; s = skip_fws(s); if (!s) goto baddate; } if (!Uisdigit(*s)) goto baddate; tm.tm_mday = *s++ - '0'; if (Uisdigit(*s)) { tm.tm_mday = tm.tm_mday*10 + *s++ - '0'; } /* Parse month name */ s = skip_fws(s); if (!s) goto baddate; month[0] = *s++; if (!Uisalpha(month[0])) goto baddate; month[1] = *s++; if (!Uisalpha(month[1])) goto baddate; month[2] = *s++; if (!Uisalpha(month[2])) goto baddate; month[3] = '\0'; for (tm.tm_mon = 0; tm.tm_mon < 12; tm.tm_mon++) { if (!strcasecmp(month, monthname[tm.tm_mon])) break; } if (tm.tm_mon == 12) goto baddate; /* Parse year */ s = skip_fws(s); if (!s || !Uisdigit(*s)) goto baddate; tm.tm_year = *s++ - '0'; if (!Uisdigit(*s)) goto baddate; tm.tm_year = tm.tm_year * 10 + *s++ - '0'; if (Uisdigit(*s)) { if (tm.tm_year < 19) goto baddate; tm.tm_year -= 19; tm.tm_year = tm.tm_year * 10 + *s++ - '0'; if (!Uisdigit(*s)) goto baddate; tm.tm_year = tm.tm_year * 10 + *s++ - '0'; } else { if (tm.tm_year < 70) { /* two-digit year, probably after 2000. * This patent was overturned, right? */ tm.tm_year += 100; } } if (Uisdigit(*s)) { /* five-digit date */ goto baddate; } if (tm.tm_mday > monthdays(tm.tm_year, tm.tm_mon)) goto baddate; s = skip_fws(s); if (s && !dayonly) { /* Parse hour */ if (!s || !Uisdigit(*s)) goto badtime; tm.tm_hour = *s++ - '0'; if (!Uisdigit(*s)) goto badtime; tm.tm_hour = tm.tm_hour * 10 + *s++ - '0'; if (!s || *s++ != ':') goto badtime; /* Parse min */ if (!s || !Uisdigit(*s)) goto badtime; tm.tm_min = *s++ - '0'; if (!Uisdigit(*s)) goto badtime; tm.tm_min = tm.tm_min * 10 + *s++ - '0'; if (*s == ':') { /* Parse sec */ if (!++s || !Uisdigit(*s)) goto badtime; tm.tm_sec = *s++ - '0'; if (!Uisdigit(*s)) goto badtime; tm.tm_sec = tm.tm_sec * 10 + *s++ - '0'; } s = skip_fws(s); if (s) { /* Parse timezone offset */ if (*s == '+' || *s == '-') { /* Parse numeric offset */ int east = (*s++ == '-'); if (!s || !Uisdigit(*s)) goto badzone; zone_off = *s++ - '0'; if (!s || !Uisdigit(*s)) goto badzone; zone_off = zone_off * 10 + *s++ - '0'; if (!s || !Uisdigit(*s)) goto badzone; zone_off = zone_off * 6 + *s++ - '0'; if (!s || !Uisdigit(*s)) goto badzone; zone_off = zone_off * 10 + *s++ - '0'; if (east) zone_off = -zone_off; } else if (Uisalpha(*s)) { char zone[4]; zone[0] = *s++; if (!Uisalpha(*s)) { /* Parse military (single-char) zone */ zone[1] = '\0'; lcase(zone); if (zone[0] < 'j') zone_off = (zone[0] - 'a' + 1) * 60; else if (zone[0] == 'j') goto badzone; else if (zone[0] <= 'm') zone_off = (zone[0] - 'a') * 60; else if (zone[0] < 'z') zone_off = ('m' - zone[0]) * 60; else zone_off = 0; } else { zone[1] = *s++; if (!Uisalpha(*s)) { /* Parse UT (universal time) */ zone[2] = '\0'; lcase(zone); if (strcmp(zone, "ut")) goto badzone; zone_off = 0; } else { /* Parse 3-char time zone */ char *p; zone[2] = *s; zone[3] = '\0'; lcase(zone); /* GMT (Greenwich mean time) */ if (!strcmp(zone, "gmt")) zone_off = 0; /* US time zone */ else { p = strchr("aecmpyhb", zone[0]); if (!p || zone[2] != 't') goto badzone; zone_off = (strlen(p) - 12) * 60; if (zone[1] == 'd') zone_off += 60; else if (zone[1] != 's') goto badzone; } } } } else badzone: zone_off = 0; } } else badtime: tm.tm_hour = 12; tm.tm_isdst = -1; if (!dayonly) t = mkgmtime(&tm); else { assert(zone_off == 0); t = mktime(&tm); } if (t >= 0) { *tp = (t - zone_off * 60); return s - origs; } baddate: return -1; }