📄 mtime.mx
字号:
/* matches regardless of case and extra spaces */static INLINE intfleximatch(str s, str pat, int min){ int hit, spacy = 0; if (min == 0) { min = (int) strlen(pat); /* default mininum required hits */ } for (hit = 0; *pat; s++, hit++) { if (LOWER(*s) != *pat) { if (GDKisspace(*s) && spacy) { min++; continue; /* extra spaces */ } break; } spacy = GDKisspace(*pat); pat++; } return (hit >= min) ? hit : 0;}static INLINE intparse_substr(int *ret, str s, int min, str list[], int size){ int j = 0, i = 0; *ret = int_nil; while (++i <= size) { if ((j = fleximatch(s, list[i], min)) > 0) { *ret = i; break; } } return j;}static INLINE intdate_dayofweek(date v){ v %= 7; return (v <= 0) ? v + 7 : v;}#define SKIP_DAYS(d,w,i) d += i; w = (w + i)%7; if (w <= 0) w += 7;static INLINE datecompute_rule(rule *val, int y){ int m = val->s.month, cnt = ABS(val->s.day - DAY_ZERO); date d = todate(1, m, y); int dayofweek = date_dayofweek(d); int w = ABS(val->s.weekday - WEEKDAY_ZERO); if (val->s.weekday == WEEKDAY_ZERO) { /* cnt-th of month */ d += cnt - 1; } else if (val->s.day > DAY_ZERO) { if (val->s.weekday < WEEKDAY_ZERO) { /* first weekday on or after cnt-th of month */ SKIP_DAYS(d, dayofweek, cnt - 1); cnt = 1; } /* ELSE cnt-th weekday of month */ while (dayofweek != w || --cnt > 0) { if (++dayofweek == 8) dayofweek = 1; d++; } } else { if (val->s.weekday > WEEKDAY_ZERO) { /* cnt-last weekday from end of month */ SKIP_DAYS(d, dayofweek, MONTHDAYS(m, y) - 1); } else { /* first weekday on or before cnt-th of month */ SKIP_DAYS(d, dayofweek, cnt - 1); cnt = 1; } while (dayofweek != w || --cnt > 0) { if (--dayofweek == 0) dayofweek = 7; d--; } } return d;}static int dummy;#define BEFORE(d1,m1,d2,m2) (d1 < d2 || (d1 == d2 && m1 <= m2))int timestamp_add(timestamp *ret, timestamp *v, lng *msecs);static INLINE inttimestamp_inside(timestamp *ret, timestamp *t, tzone *z, lng offset){ /* starts with GMT time t, and returns whether it is in the DST for z */ lng add = (offset != (lng) 0) ? offset : (get_offset(z)) * (lng) 60000; int start_days, start_msecs, end_days, end_msecs, year; rule start, end; timestamp_add(ret, t, &add); if (ts_isnil(*ret) || z->dst == 0) { return 0; } set_rule(start, z->dst_start); set_rule(end, z->dst_end); start_msecs = start.s.minutes * 60000; end_msecs = end.s.minutes * 60000; fromdate((int) ret->days, &dummy, &dummy, &year); start_days = compute_rule(&start, year); end_days = compute_rule(&end, year); return BEFORE(start_days, start_msecs, end_days, end_msecs) ? (BEFORE(start_days, start_msecs, ret->days, ret->msecs) && BEFORE(ret->days, ret->msecs, end_days, end_msecs)) : (BEFORE(start_days, start_msecs, ret->days, ret->msecs) || BEFORE(ret->days, ret->msecs, end_days, end_msecs));}@+ ADT implementations@- date@cintdate_fromstr(str buf, int *len, date **d){ int day = 0, month = int_nil, year = 0, yearneg = (buf[0] == '-'), yearlast = 0, pos = 0, sep; if (*len < (int) sizeof(date)) { if (*d) GDKfree(*d); *d = (date *) GDKmalloc(*len = sizeof(date)); } **d = date_nil; if (yearneg == 0 && !GDKisdigit(buf[0])) { if (synonyms == 0) return 0; yearlast = 1; sep = ' '; } else { for (pos = yearneg; GDKisdigit(buf[pos]); pos++) { year = (buf[pos] - '0') + year * 10; if (year > YEAR_MAX) break; } sep = buf[pos++]; if (synonyms == 0 && sep != '-') { return 0; } sep = LOWER(sep); if (sep >= 'a' && sep <= 'z') { sep = 0; } else if (sep == ' ') { while (buf[pos] == ' ') pos++; } else if (sep != '-' && sep != '/' && sep != '\\') { return 0; /* syntax error */ } } if (GDKisdigit(buf[pos])) { month = buf[pos++] - '0'; if (GDKisdigit(buf[pos])) { month = (buf[pos++] - '0') + month * 10; } } else if (synonyms == 0) { return 0; } else { pos += parse_substr(&month, buf + pos, 3, MONTHS, 12); } if (month == int_nil || (sep && buf[pos++] != sep)) { return 0; /* syntax error */ } if (sep == ' ') { while (buf[pos] == ' ') pos++; } if (!GDKisdigit(buf[pos])) { return 0; /* syntax error */ } while (GDKisdigit(buf[pos])) { day = (buf[pos++] - '0') + day * 10; if (day > 31) break; } if (yearlast && buf[pos] == ',') { while (buf[++pos] == ' ') ; if (buf[pos] == '-') { yearneg = 1; pos++; } while (GDKisdigit(buf[pos])) { year = (buf[pos++] - '0') + year * 10; if (year > YEAR_MAX) break; } } /* handle semantic error here (returns nil in that case) */ **d = todate(day, month, yearneg ? -year : year); return pos;}intdate_tostr(str *buf, int *len, date *val){ int day, month, year; fromdate((int) *val, &day, &month, &year); /* longest possible string: "-5867411-01-01" i.e. 14 chars without NUL (see definition of YEAR_MIN/YEAR_MAX above) */ if (*len < 15) { if (*buf) GDKfree(*buf); *buf = (str) GDKmalloc(*len = 15); } if (*val == date_nil || !DATE(day, month, year)) { strcpy(*buf, "nil"); return 3; } sprintf(*buf, "%d-%02d-%02d", year, month, day); return (int) strlen(*buf);}@- daytime@cintdaytime_fromstr(str buf, int *len, daytime **ret){ int hour, min, sec = 0, msec = 0, pos = 0; if (*len < (int) sizeof(daytime)) { if (*ret) GDKfree(*ret); *ret = (daytime *) GDKmalloc(*len = sizeof(daytime)); } **ret = daytime_nil; if (!GDKisdigit(buf[pos])) { return 0; /* syntax error */ } for (hour = 0; GDKisdigit(buf[pos]); pos++) { if (hour <= 24) hour = (buf[pos] - '0') + hour * 10; } if ((buf[pos++] != ':') || !GDKisdigit(buf[pos])) { return 0; /* syntax error */ } for (min = 0; GDKisdigit(buf[pos]); pos++) { if (min <= 60) min = (buf[pos] - '0') + min * 10; } if ((buf[pos] == ':') && GDKisdigit(buf[pos + 1])) { for (pos++, sec = 0; GDKisdigit(buf[pos]); pos++) { if (sec <= 60) sec = (buf[pos] - '0') + sec * 10; } if ((buf[pos] == '.' || (synonyms && buf[pos] == ':')) && GDKisdigit(buf[pos + 1])) { int fac = 100; for (pos++, msec = 0; GDKisdigit(buf[pos]); pos++) { msec += (buf[pos] - '0') * fac; fac /= 10; } } } /* handle semantic error here (returns nil in that case) */ **ret = totime(hour, min, sec, msec); return pos;}intdaytime_tz_fromstr(str buf, int *len, daytime **ret){ str s = buf; int pos = daytime_fromstr(s, len, ret); lng val, offset = 0; daytime mtime = 24 * 60 * 60 * 1000; if (!*ret || **ret == daytime_nil) return pos; s = buf + pos; pos = 0; while (GDKisspace(*s)) s++; /* incase of gmt we need to add the time zone */ if (fleximatch(s, "gmt", 0) == 3) { s += 3; } if ((s[0] == '-' || s[0] == '+') && GDKisdigit(s[1]) && GDKisdigit(s[2]) && GDKisdigit(s[pos = 4]) && ((s[3] == ':' && GDKisdigit(s[5])) || GDKisdigit(s[pos = 3]))) { offset = (((s[1] - '0') * (lng) 10 + (s[2] - '0')) * (lng) 60 + (s[pos] - '0') * (lng) 10 + (s[pos + 1] - '0')) * (lng) 60000; pos++; if (s[0] != '-') offset = -offset; s += pos; } else { /* if no tzone is specified; work with the local */ offset = get_offset(&tzone_local) * (lng) -60000; } val = **ret + offset; if (val < 0) val = mtime + val; if (val >= mtime) val = val - mtime; **ret = (daytime) val; return (int) (s - buf);}intdaytime_tostr(str *buf, int *len, daytime *val){ int hour, min, sec, msec; fromtime((int) *val, &hour, &min, &sec, &msec); if (*len < 12) { if (*buf) GDKfree(*buf); *buf = (str) GDKmalloc(*len = 13); } if (*val == daytime_nil || !TIME(hour, min, sec, msec)) { strcpy(*buf, "nil"); return 3; } sprintf(*buf, "%02d:%02d:%02d.%03d", hour, min, sec, msec); return 12;}@- timestamp@cinttimestamp_fromstr(str buf, int *len, timestamp **ret){ str s = buf; int pos; date *d; daytime *t; if (*len < (int) sizeof(timestamp)) { if (*ret) GDKfree(*ret); *ret = (timestamp *) GDKmalloc(*len = sizeof(timestamp)); } d = &(*ret)->days; t = &(*ret)->msecs; s += date_fromstr(buf, len, &d); if (s > buf && (*(s) == '@' || *s == ' ' || *s == '-')) { while (*(++s) == ' ') ; pos = daytime_fromstr(s, len, &t); s = pos ? s + pos : buf; } else { (*ret)->msecs = daytime_nil; } if (s <= buf || (*ret)->days == date_nil || (*ret)->msecs == daytime_nil) { **ret = *ts_nilptr; } else { lng offset = 0; while (GDKisspace(*s)) s++; /* incase of gmt we need to add the time zone */ if (fleximatch(s, "gmt", 0) == 3) { s += 3; } if ((s[0] == '-' || s[0] == '+') && GDKisdigit(s[1]) && GDKisdigit(s[2]) && GDKisdigit(s[pos = 4]) && ((s[3] == ':' && GDKisdigit(s[5])) || GDKisdigit(s[pos = 3]))) { offset = (((s[1] - '0') * (lng) 10 + (s[2] - '0')) * (lng) 60 + (s[pos] - '0') * (lng) 10 + (s[pos + 1] - '0')) * (lng) 60000; pos++; if (s[0] != '-') offset = -offset; s += pos; } else { /* if no tzone is specified; work with the local */ timestamp tmp = **ret; offset = get_offset(&tzone_local) * (lng) -60000; if (timestamp_inside(&tmp, &tmp, &tzone_local, (lng) -3600000)) { **ret = tmp; } } timestamp_add(*ret, *ret, &offset); } return (int) (s - buf);}inttimestamp_tostr(str *buf, int *len, timestamp *val){ int len1, len2, big = 128, off = get_offset(&tzone_local); char buf1[128], buf2[128], *s, *s1 = buf1, *s2 = buf2; timestamp tmp = *val; if (!ts_isnil(tmp) && timestamp_inside(&tmp, val, &tzone_local, (lng) 0)) { lng add = (lng) 3600000; timestamp_add(&tmp, &tmp, &add); off += 60; } len1 = date_tostr(&s1, &big, &tmp.days); len2 = daytime_tostr(&s2, &big, &tmp.msecs); if (*len < 2 + len1 + len2) { if (*buf) GDKfree(*buf); *buf = (str) GDKmalloc(*len = len1 + len2 + 2); } s = *buf; if (ts_isnil(tmp)) { strcpy(s, "nil"); return 3; } strcpy(s, buf1); s += len1; *s++ = ' '; strcpy(s, buf2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -