📄 mtime.mx
字号:
s += len2;/* omit GMT distance in order not to cinfuse the confused user strcpy(s, "GMT"); s += 3; if (off) { *s++ = (off>=0)?'+':'-'; sprintf(s, "%02d%02d", ABS(off)/60, ABS(off)%60); s += 4; } */ return (int) (s - *buf);}strcount1(int i){ static char buf[16]; if (i <= 0) { return "(illegal number)"; } else if (i < 6) { return COUNT1[i]; } sprintf(buf, "%dth", i); return buf;}@- rule@cintrule_tostr(str *buf, int *len, rule *r){ int hours = r->s.minutes / 60; int minutes = r->s.minutes % 60; if (*len < 64) { if (*buf) GDKfree(*buf); *buf = (str) GDKmalloc(*len = 64); } if (r->asint == int_nil) { strcpy(*buf, "nil"); } else if (r->s.weekday == WEEKDAY_ZERO) { sprintf(*buf, "%s %d\@%02d:%02d", MONTHS[r->s.month], r->s.day - DAY_ZERO, hours, minutes); } else if (r->s.weekday > WEEKDAY_ZERO && r->s.day > DAY_ZERO) { sprintf(*buf, "%s %s from start of %s\@%02d:%02d", count1(r->s.day - DAY_ZERO), DAYS[r->s.weekday - WEEKDAY_ZERO], MONTHS[r->s.month], hours, minutes); } else if (r->s.weekday > WEEKDAY_ZERO && r->s.day < DAY_ZERO) { sprintf(*buf, "%s %s from end of %s\@%02d:%02d", count1(DAY_ZERO - r->s.day), DAYS[r->s.weekday - WEEKDAY_ZERO], MONTHS[r->s.month], hours, minutes); } else if (r->s.day > DAY_ZERO) { sprintf(*buf, "first %s on or after %s %d\@%02d:%02d", DAYS[WEEKDAY_ZERO - r->s.weekday], MONTHS[r->s.month], r->s.day - DAY_ZERO, hours, minutes); } else { sprintf(*buf, "last %s on or before %s %d\@%02d:%02d", DAYS[WEEKDAY_ZERO - r->s.weekday], MONTHS[r->s.month], DAY_ZERO - r->s.day, hours, minutes); } return (int) strlen(*buf);}intrule_fromstr(str buf, int *len, rule **d){ int day = 0, month = 0, weekday = 0, hours = 0, minutes = 0; int neg_day = 0, neg_weekday = 0, pos; str cur = buf; if (*len < (int) sizeof(rule)) { if (*d) GDKfree(*d); *d = (rule *) GDKmalloc(*len = sizeof(rule)); } (*d)->asint = int_nil; /* start parsing something like "first", "second", .. etc */ pos = parse_substr(&day, cur, 0, COUNT1, 6); if (pos == 0) { pos = parse_substr(&day, cur, 0, COUNT2, 6); } if (pos && cur[pos++] == ' ') { /* now we must see a weekday */ cur += pos; cur += parse_substr(&weekday, cur, 3, DAYS, 7); if (weekday == int_nil) { return 0; /* syntax error */ } pos = fleximatch(cur, " from start of ", 0); if (pos == 0) { pos = fleximatch(cur, " from end of ", 0); if (pos) neg_day = 1; } if (pos && day < 6) { /* RULE 1+2: X-th weekday from start/end of month */ pos = parse_substr(&month, cur += pos, 3, MONTHS, 12); } else if (day == 1) { /* RULE 3: first weekday on or after-th of month */ pos = fleximatch(cur, " on or after ", 0); neg_weekday = 1; day = int_nil; /* re-read below */ } else if (day == 6) { /* RULE 4: last weekday on or before X-th of month */ pos = fleximatch(cur, " on or before ", 0); neg_weekday = neg_day = 1; day = int_nil; /* re-read below */ } if (pos == 0) { return 0; /* syntax error */ } cur += pos; } if (day == int_nil) { /* RULE 5: X-th of month */ cur += parse_substr(&month, cur, 3, MONTHS, 12); if (month == int_nil || *cur++ != ' ' || !GDKisdigit(*cur)) { return 0; /* syntax error */ } day = 0; while (GDKisdigit(*cur) && day < 31) { day = (*(cur++) - '0') + day * 10; } } /* parse hours:minutes */ if (*cur++ != '\@' || !GDKisdigit(*cur)) { return 0; /* syntax error */ } while (GDKisdigit(*cur) && hours < 24) { hours = (*(cur++) - '0') + hours * 10; } if (*cur++ != ':' || !GDKisdigit(*cur)) { return 0; /* syntax error */ } while (GDKisdigit(*cur) && minutes < 60) { minutes = (*(cur++) - '0') + minutes * 10; } /* assign if semantically ok */ if (day >= 1 && day <= NODAYS[month] && hours >= 0 && hours < 60 && minutes >= 0 && minutes < 60) { (*d)->s.month = month; (*d)->s.weekday = WEEKDAY_ZERO + (neg_weekday ? -weekday : weekday); (*d)->s.day = DAY_ZERO + (neg_day ? -day : day); (*d)->s.minutes = hours * 60 + minutes; } return (int) (cur - buf);}@- tzone@cinttzone_fromstr(str buf, int *len, tzone **d){ int hours = 0, minutes = 0, neg_offset = 0, pos = 0; rule r1, *rp1 = &r1, r2, *rp2 = &r2; str cur = buf; rp1->asint = rp2->asint = 0; if (*len < (int) sizeof(tzone)) { if (*d) GDKfree(*d); *d = (tzone *) GDKmalloc(*len = sizeof(tzone)); } **d = *tz_nilptr; /* syntax checks */ if (fleximatch(cur, "gmt", 0) == 0) { return 0; /* syntax error */ } cur += 3; if (*cur == '-' || *cur == '+') { str bak = cur + 1; neg_offset = (*cur++ == '-'); if (!GDKisdigit(*cur)) { return 0; /* syntax error */ } while (GDKisdigit(*cur) && hours < 9999) { hours = (*(cur++) - '0') + hours * 10; } if (*cur == ':' && GDKisdigit(cur[1])) { cur++; do { minutes = (*(cur++) - '0') + minutes * 10; } while (GDKisdigit(*cur) && minutes < 60); } else if (*cur != ':' && (cur - bak) == 4) { minutes = hours % 100; hours = hours / 100; } else { return 0; /* syntax error */ } } if (fleximatch(cur, "-dst[", 0)) { pos = rule_fromstr(cur += 5, len, &rp1); if (pos == 0 || cur[pos++] != ',') { return 0; /* syntax error */ } pos = rule_fromstr(cur += pos, len, &rp2); if (pos == 0 || cur[pos++] != ']') { return 0; /* syntax error */ } cur += pos; } /* semantic check */ if (hours < 24 && minutes < 60 && rp1->asint != int_nil && rp2->asint != int_nil) { minutes += hours * 60; set_offset(*d, neg_offset ? -minutes : minutes); if (pos) { (*d)->dst = TRUE; (*d)->dst_start = get_rule(r1); (*d)->dst_end = get_rule(r2); } else { (*d)->dst = FALSE; } } return (int) (cur - buf);}inttzone_tostr(str *buf, int *len, tzone *z){ str s; if (*len < 160) { if (*buf) GDKfree(*buf); *buf = (str) GDKmalloc(*len = 160); } s = *buf; if (tz_isnil(*z)) { strcpy(s, "nil"); s += 3; } else { rule dst_start, dst_end; int mins = get_offset(z); set_rule(dst_start, z->dst_start); set_rule(dst_end, z->dst_end); strcpy(*buf, "GMT"); s += 3; if (mins > 0) { sprintf(s, "+%02d:%02d", mins / 60, mins % 60); s += 6; } else if (mins < 0) { sprintf(s, "-%02d:%02d", (-mins) / 60, (-mins) % 60); s += 6; } if (z->dst) { strcpy(s, "-DST["); s += 5; s += rule_tostr(&s, len, &dst_start); *s++ = ','; s += rule_tostr(&s, len, &dst_end); *s++ = ']'; *s = 0; } } return (int) (s - *buf);}@+ operator implementations@cstatic voiddate_prelude(void){ MONTHS[0] = (str)str_nil; DAYS[0] = (str)str_nil; NODAYS[0] = int_nil; DATE_MAX = todate(31, 12, YEAR_MAX); DATE_MIN = todate(1, 1, YEAR_MIN); tzone_local.dst = 0; set_offset(&tzone_local, 0);}intoldduration(int *ndays, str s){ int year = 0, month = 0, day = 0; int hour = 0 /*, min=0 */ ; char *snew = s; int v = 0; while (*snew != '\0') { if (GDKisdigit(*snew)) { v = 0; while (GDKisdigit(*snew)) { v = v * 10 + (*snew) - '0'; snew++; } } else if (isupper((int) (*snew)) || islower((int) (*snew))) { switch (*snew++) { case 'y': case 'Y': year = v; v = 0; break; case 'm': case 'M': if (month || day || hour) /*min = v */ ; else month = v; v = 0; break; case 'd': case 'D': day = v; v = 0; break; case 'h': case 'H': hour = v; v = 0; break; case 's': case 'S': v = 0; break; default: /* GDKerror("duration_fromstr: wrong duration '%s'!\n",s); */ *ndays = int_nil; return GDK_SUCCEED; } } else { snew++; } } *ndays = year * 365 + month * 30 + day; return GDK_SUCCEED;}intolddate(date *d, str buf){ int day = 0, month, year, yearneg = (buf[0] == '-'), pos = yearneg; *d = date_nil; if (!GDKisdigit(buf[pos])) { return GDK_FAIL; /* syntax error */ } for (year = 0; GDKisdigit(buf[pos]); pos++) { year = (buf[pos] - '0') + year * 10; if (year > YEAR_MAX) break; } pos += parse_substr(&month, buf + pos, 3, MONTHS, 12); if (month == int_nil) { return GDK_FAIL; /* syntax error */ } if (!GDKisdigit(buf[pos])) { return GDK_FAIL; /* syntax error */ } while (GDKisdigit(buf[pos])) { day = (buf[pos] - '0') + day * 10; pos++; if (day > 31) break; } /* handle semantic error here (returns nil in that case) */ *d = todate(day, month, yearneg ? -year : year); return GDK_SUCCEED;}inttzone_set_local(tzone *z){ tzone_local = *z; return GDK_SUCCEED;}inttzone_get_local(tzone *z){ *z = tzone_local; return GDK_SUCCEED;}/* Returns month number [1-12] from a string (or nil if does not match any). */intmonth_from_str(int *ret, str month){ parse_substr(ret, month, 3, MONTHS, 12); return GDK_SUCCEED;}/* Returns month name from a number between [1-7], str(nil) otherwise. */intmonth_to_str(str *ret, int *month){ *ret = GDKstrdup(MONTHS[(*month < 1 || *month > 12) ? 0 : *month]); return GDK_SUCCEED;}/* Returns number of day [1-7] from a string (or nil if does not match any). */intday_from_str(int *ret, str day){ parse_substr(ret, day, 3, DAYS, 7); return GDK_SUCCEED;}/* Returns day name from a number between [1-7], str(nil) otherwise. */intday_to_str(str *ret, int *day){ *ret = GDKstrdup(DAYS[(*day < 1 || *day > 7) ? 0 : *day]); return GDK_SUCCEED;}/* creates a date from (day,month,year) parameters */intdate_create(date *ret, int *year, int *month, int *day){ *ret = todate(*day, *month, *year); return GDK_SUCCEED;}/* creates a daytime from (hours,minutes,seconds,milliseconds) parameters */intdaytime_create(daytime *ret, int *hour, in
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -