2
date_parse.c: Coded by Tadayoshi Funaba 2011
6
#include "ruby/encoding.h"
10
#define sizeof_array(o) (sizeof o / sizeof o[0])
12
#define f_negate(x) rb_funcall(x, rb_intern("-@"), 0)
13
#define f_add(x,y) rb_funcall(x, '+', 1, y)
14
#define f_sub(x,y) rb_funcall(x, '-', 1, y)
15
#define f_mul(x,y) rb_funcall(x, '*', 1, y)
16
#define f_div(x,y) rb_funcall(x, '/', 1, y)
17
#define f_idiv(x,y) rb_funcall(x, rb_intern("div"), 1, y)
18
#define f_mod(x,y) rb_funcall(x, '%', 1, y)
19
#define f_expt(x,y) rb_funcall(x, rb_intern("**"), 1, y)
21
#define f_lt_p(x,y) rb_funcall(x, '<', 1, y)
22
#define f_gt_p(x,y) rb_funcall(x, '>', 1, y)
23
#define f_le_p(x,y) rb_funcall(x, rb_intern("<="), 1, y)
24
#define f_ge_p(x,y) rb_funcall(x, rb_intern(">="), 1, y)
26
#define f_to_s(x) rb_funcall(x, rb_intern("to_s"), 0)
28
#define f_match(r,s) rb_funcall(r, rb_intern("match"), 1, s)
29
#define f_aref(o,i) rb_funcall(o, rb_intern("[]"), 1, i)
30
#define f_aref2(o,i,j) rb_funcall(o, rb_intern("[]"), 2, i, j)
31
#define f_begin(o,i) rb_funcall(o, rb_intern("begin"), 1, i)
32
#define f_end(o,i) rb_funcall(o, rb_intern("end"), 1, i)
33
#define f_aset(o,i,v) rb_funcall(o, rb_intern("[]="), 2, i, v)
34
#define f_aset2(o,i,j,v) rb_funcall(o, rb_intern("[]="), 3, i, j, v)
35
#define f_sub_bang(s,r,x) rb_funcall(s, rb_intern("sub!"), 2, r, x)
36
#define f_gsub_bang(s,r,x) rb_funcall(s, rb_intern("gsub!"), 2, r, x)
38
#define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k)), v)
39
#define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k)))
40
#define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k)))
42
#define cstr2num(s) rb_cstr_to_inum(s, 10, 0)
43
#define str2num(s) rb_str_to_inum(s, 10, 0)
45
static const char *abbr_days[] = {
46
"sun", "mon", "tue", "wed",
50
static const char *abbr_months[] = {
51
"jan", "feb", "mar", "apr", "may", "jun",
52
"jul", "aug", "sep", "oct", "nov", "dec"
55
#define issign(c) ((c) == '-' || (c) == '+')
56
#define asp_string() rb_str_new(" ", 1)
59
s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
63
if (TYPE(m) != T_STRING)
66
if (!NIL_P(y) && !NIL_P(m) && NIL_P(d)) {
77
if (!NIL_P(d) && RSTRING_LEN(d) > 2) {
81
if (!NIL_P(d) && *RSTRING_PTR(d) == '\'') {
88
const char *s, *bp, *ep;
92
while (!issign(*s) && !isdigit(*s))
97
l = strspn(s, "0123456789");
101
d = rb_str_new(bp, ep - bp);
109
if (*s == '\'' || RSTRING_LEN(m) > 2) {
125
if (*s == '\'' || RSTRING_LEN(d) > 2) {
135
const char *s, *bp, *ep;
141
while (!issign(*s) && !isdigit(*s))
150
l = strspn(s, "0123456789");
157
buf = ALLOCA_N(char, ep - bp + 1);
158
memcpy(buf, bp, ep - bp);
163
iy = f_add(f_negate(iy), INT2FIX(1));
164
set_hash("year", iy);
168
const char *s, *bp, *ep;
176
l = strspn(s, "0123456789");
181
buf = ALLOCA_N(char, ep - bp + 1);
182
memcpy(buf, bp, ep - bp);
190
const char *s, *bp, *ep;
198
l = strspn(s, "0123456789");
203
buf = ALLOCA_N(char, ep - bp + 1);
204
memcpy(buf, bp, ep - bp);
208
set_hash("mday", id);
212
set_hash("_comp", c);
215
#define DAYS "sunday|monday|tuesday|wednesday|thursday|friday|saturday"
216
#define MONTHS "january|february|march|april|may|june|july|august|september|october|november|december"
217
#define ABBR_DAYS "sun|mon|tue|wed|thu|fri|sat"
218
#define ABBR_MONTHS "jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec"
221
regcomp(const char *source, long len, int opt)
225
pat = rb_reg_new(source, len, opt);
226
rb_gc_register_mark_object(pat);
230
#define REGCOMP(pat,opt) \
233
pat = regcomp(pat##_source, sizeof pat##_source - 1, opt); \
236
#define REGCOMP_0(pat) REGCOMP(pat, 0)
237
#define REGCOMP_I(pat) REGCOMP(pat, ONIG_OPTION_IGNORECASE)
239
#define SUBS(s,p,c) \
241
return subs(s, p, hash, c); \
245
subs(VALUE str, VALUE pat, VALUE hash, int (*cb)(VALUE, VALUE))
249
m = f_match(pat, str);
257
be = f_begin(m, INT2FIX(0));
258
en = f_end(m, INT2FIX(0));
259
f_aset2(str, be, LONG2NUM(NUM2LONG(en) - NUM2LONG(be)), asp_string());
271
static struct zone zones_source[] = {
272
{"ut", 0*3600}, {"gmt", 0*3600}, {"est", -5*3600}, {"edt", -4*3600},
273
{"cst", -6*3600}, {"cdt", -5*3600}, {"mst", -7*3600}, {"mdt", -6*3600},
274
{"pst", -8*3600}, {"pdt", -7*3600},
275
{"a", 1*3600}, {"b", 2*3600}, {"c", 3*3600}, {"d", 4*3600},
276
{"e", 5*3600}, {"f", 6*3600}, {"g", 7*3600}, {"h", 8*3600},
277
{"i", 9*3600}, {"k", 10*3600}, {"l", 11*3600}, {"m", 12*3600},
278
{"n", -1*3600}, {"o", -2*3600}, {"p", -3*3600}, {"q", -4*3600},
279
{"r", -5*3600}, {"s", -6*3600}, {"t", -7*3600}, {"u", -8*3600},
280
{"v", -9*3600}, {"w", -10*3600}, {"x", -11*3600}, {"y", -12*3600},
283
{"utc", 0*3600}, {"wet", 0*3600},
284
{"at", -2*3600}, {"brst",-2*3600}, {"ndt", -(2*3600+1800)},
285
{"art", -3*3600}, {"adt", -3*3600}, {"brt", -3*3600}, {"clst",-3*3600},
286
{"nst", -(3*3600+1800)},
287
{"ast", -4*3600}, {"clt", -4*3600},
288
{"akdt",-8*3600}, {"ydt", -8*3600},
289
{"akst",-9*3600}, {"hadt",-9*3600}, {"hdt", -9*3600}, {"yst", -9*3600},
290
{"ahst",-10*3600},{"cat",-10*3600}, {"hast",-10*3600},{"hst",-10*3600},
293
{"bst", 1*3600}, {"cet", 1*3600}, {"fwt", 1*3600}, {"met", 1*3600},
294
{"mewt", 1*3600}, {"mez", 1*3600}, {"swt", 1*3600}, {"wat", 1*3600},
296
{"cest", 2*3600}, {"eet", 2*3600}, {"fst", 2*3600}, {"mest", 2*3600},
297
{"mesz", 2*3600}, {"sast", 2*3600}, {"sst", 2*3600},
298
{"bt", 3*3600}, {"eat", 3*3600}, {"eest", 3*3600}, {"msk", 3*3600},
299
{"msd", 4*3600}, {"zp4", 4*3600},
300
{"zp5", 5*3600}, {"ist", (5*3600+1800)},
303
{"cct", 8*3600}, {"sgt", 8*3600}, {"wadt", 8*3600},
304
{"jst", 9*3600}, {"kst", 9*3600},
305
{"east",10*3600}, {"gst", 10*3600},
307
{"idle",12*3600}, {"nzst",12*3600}, {"nzt", 12*3600},
310
{"afghanistan", 16200}, {"alaskan", -32400},
311
{"arab", 10800}, {"arabian", 14400},
312
{"arabic", 10800}, {"atlantic", -14400},
313
{"aus central", 34200}, {"aus eastern", 36000},
314
{"azores", -3600}, {"canada central", -21600},
315
{"cape verde", -3600}, {"caucasus", 14400},
316
{"cen. australia", 34200}, {"central america", -21600},
317
{"central asia", 21600}, {"central europe", 3600},
318
{"central european", 3600}, {"central pacific", 39600},
319
{"central", -21600}, {"china", 28800},
320
{"dateline", -43200}, {"e. africa", 10800},
321
{"e. australia", 36000}, {"e. europe", 7200},
322
{"e. south america", -10800}, {"eastern", -18000},
323
{"egypt", 7200}, {"ekaterinburg", 18000},
324
{"fiji", 43200}, {"fle", 7200},
325
{"greenland", -10800}, {"greenwich", 0},
326
{"gtb", 7200}, {"hawaiian", -36000},
327
{"india", 19800}, {"iran", 12600},
328
{"jerusalem", 7200}, {"korea", 32400},
329
{"mexico", -21600}, {"mid-atlantic", -7200},
330
{"mountain", -25200}, {"myanmar", 23400},
331
{"n. central asia", 21600}, {"nepal", 20700},
332
{"new zealand", 43200}, {"newfoundland", -12600},
333
{"north asia east", 28800}, {"north asia", 25200},
334
{"pacific sa", -14400}, {"pacific", -28800},
335
{"romance", 3600}, {"russian", 10800},
336
{"sa eastern", -10800}, {"sa pacific", -18000},
337
{"sa western", -14400}, {"samoa", -39600},
338
{"se asia", 25200}, {"malay peninsula", 28800},
339
{"south africa", 7200}, {"sri lanka", 21600},
340
{"taipei", 28800}, {"tasmania", 36000},
341
{"tokyo", 32400}, {"tonga", 46800},
342
{"us eastern", -18000}, {"us mountain", -25200},
343
{"vladivostok", 36000}, {"w. australia", 28800},
344
{"w. central africa", 3600}, {"w. europe", 3600},
345
{"west asia", 18000}, {"west pacific", 36000},
350
date_zone_to_diff(VALUE str)
358
l = RSTRING_LEN(str);
359
s = RSTRING_PTR(str);
361
dest = d = ALLOCA_N(char, l + 1);
363
for (i = 0; i < l; i++) {
364
if (isspace(s[i]) || s[i] == '\0') {
371
*d++ = tolower(s[i]);
382
str = rb_str_new2(dest);
384
#define STD " standard time"
385
#define DST " daylight time"
390
sl = RSTRING_LEN(str) - (sizeof STD - 1);
391
ss = RSTRING_PTR(str) + sl;
392
dl = RSTRING_LEN(str) - (sizeof DST - 1);
393
ds = RSTRING_PTR(str) + dl;
395
if (sl >= 0 && strcmp(ss, STD) == 0) {
396
str = rb_str_new(RSTRING_PTR(str), sl);
398
else if (dl >= 0 && strcmp(ds, DST) == 0) {
399
str = rb_str_new(RSTRING_PTR(str), dl);
409
dl = RSTRING_LEN(str) - (sizeof DST - 1);
410
ds = RSTRING_PTR(str) + dl;
412
if (dl >= 0 && strcmp(ds, DST) == 0) {
413
str = rb_str_new(RSTRING_PTR(str), dl);
419
static VALUE zones = Qnil;
424
zones = rb_hash_new();
425
rb_gc_register_mark_object(zones);
426
for (i = 0; i < (int)sizeof_array(zones_source); i++) {
427
VALUE name = rb_str_new2(zones_source[i].name);
428
VALUE offset = INT2FIX(zones_source[i].offset);
429
rb_hash_aset(zones, name, offset);
433
offset = f_aref(zones, str);
434
if (!NIL_P(offset)) {
436
offset = f_add(offset, INT2FIX(3600));
443
VALUE hour = Qnil, min = Qnil, sec = Qnil;
446
s = RSTRING_PTR(str);
449
if (strncmp(s, "gmt", 3) == 0 ||
450
strncmp(s, "utc", 3) == 0)
453
sign = rb_str_new(s, 1);
456
str = rb_str_new2(s);
458
if (p = strchr(s, ':')) {
459
hour = rb_str_new(s, p - s);
461
if (p = strchr(s, ':')) {
462
min = rb_str_new(s, p - s);
464
if (p = strchr(s, ':')) {
465
sec = rb_str_new(s, p - s);
468
sec = rb_str_new2(s);
471
min = rb_str_new2(s);
472
RB_GC_GUARD(str_orig);
475
if (strpbrk(RSTRING_PTR(str), ",.")) {
478
a = ALLOCA_N(char, RSTRING_LEN(str) + 1);
479
strcpy(a, RSTRING_PTR(str));
480
b = strpbrk(a, ",.");
485
min = f_mul(rb_rational_new2
488
LONG2NUM((long)strlen(b)))),
493
const char *cs = RSTRING_PTR(str);
494
long cl = RSTRING_LEN(str);
498
hour = rb_str_new(&cs[0], 1);
500
min = rb_str_new(&cs[1], 2);
502
min = rb_str_new(&cs[3], 2);
506
hour = rb_str_new(&cs[0], 2);
508
min = rb_str_new(&cs[2], 2);
510
sec = rb_str_new(&cs[4], 2);
518
if (TYPE(hour) == T_STRING)
519
hour = str2num(hour);
520
offset = f_mul(hour, INT2FIX(3600));
523
if (TYPE(min) == T_STRING)
525
offset = f_add(offset, f_mul(min, INT2FIX(60)));
528
offset = f_add(offset, str2num(sec));
530
RSTRING_LEN(sign) == 1 &&
531
*RSTRING_PTR(sign) == '-')
532
offset = f_negate(offset);
546
for (i = 0; i < (int)sizeof_array(abbr_days); i++)
547
if (strncasecmp(abbr_days[i], RSTRING_PTR(s), 3) == 0)
557
for (i = 0; i < (int)sizeof_array(abbr_months); i++)
558
if (strncasecmp(abbr_months[i], RSTRING_PTR(s), 3) == 0)
564
parse_day_cb(VALUE m, VALUE hash)
568
s = rb_reg_nth_match(1, m);
569
set_hash("wday", INT2FIX(day_num(s)));
574
parse_day(VALUE str, VALUE hash)
576
static const char pat_source[] = "\\b(" ABBR_DAYS ")[^-\\d\\s]*";
577
static VALUE pat = Qnil;
580
SUBS(str, pat, parse_day_cb);
584
parse_time2_cb(VALUE m, VALUE hash)
586
VALUE h, min, s, f, p;
588
h = rb_reg_nth_match(1, m);
591
min = rb_reg_nth_match(2, m);
595
s = rb_reg_nth_match(3, m);
599
f = rb_reg_nth_match(4, m);
602
f = rb_rational_new2(str2num(f),
603
f_expt(INT2FIX(10), LONG2NUM(RSTRING_LEN(f))));
605
p = rb_reg_nth_match(5, m);
610
if (*RSTRING_PTR(p) == 'P' || *RSTRING_PTR(p) == 'p')
617
set_hash("min", min);
621
set_hash("sec_fraction", f);
627
parse_time_cb(VALUE m, VALUE hash)
629
static const char pat_source[] =
631
"(?:\\s*:?\\s*(\\d+)m?"
633
"\\s*:?\\s*(\\d+)(?:[,.](\\d+))?s?"
636
"(?:\\s*([ap])(?:m\\b|\\.m\\.))?";
637
static VALUE pat = Qnil;
640
s1 = rb_reg_nth_match(1, m);
641
s2 = rb_reg_nth_match(2, m);
644
set_hash("zone", s2);
649
VALUE m = f_match(pat, s1);
653
parse_time2_cb(m, hash);
660
parse_time(VALUE str, VALUE hash)
662
static const char pat_source[] =
667
"\\s*:\\s*\\d+(?:[,.]\\d*)?"
670
"\\d+\\s*h(?:\\s*\\d+m?(?:\\s*\\d+s?)?)?"
674
"[ap](?:m\\b|\\.m\\.)"
677
"\\d+\\s*[ap](?:m\\b|\\.m\\.)"
682
"(?:gmt|utc?)?[-+]\\d+(?:[,.:]\\d+(?::\\d+)?)?"
684
"[[:alpha:].\\s]+(?:standard|daylight)\\stime\\b"
686
"[[:alpha:]]+(?:\\sdst)?\\b"
689
static VALUE pat = Qnil;
692
SUBS(str, pat, parse_time_cb);
696
parse_eu_cb(VALUE m, VALUE hash)
700
d = rb_reg_nth_match(1, m);
701
mon = rb_reg_nth_match(2, m);
702
b = rb_reg_nth_match(3, m);
703
y = rb_reg_nth_match(4, m);
705
mon = INT2FIX(mon_num(mon));
707
s3e(hash, y, mon, d, !NIL_P(b) &&
708
(*RSTRING_PTR(b) == 'B' ||
709
*RSTRING_PTR(b) == 'b'));
714
parse_eu(VALUE str, VALUE hash)
716
static const char pat_source[] =
717
"'?(\\d+)[^-\\d\\s]*"
719
"(" ABBR_MONTHS ")[^-\\d\\s']*"
722
"(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))?"
724
"('?-?\\d+(?:(?:st|nd|rd|th)\\b)?)"
726
static VALUE pat = Qnil;
729
SUBS(str, pat, parse_eu_cb);
733
parse_us_cb(VALUE m, VALUE hash)
737
mon = rb_reg_nth_match(1, m);
738
d = rb_reg_nth_match(2, m);
739
b = rb_reg_nth_match(3, m);
740
y = rb_reg_nth_match(4, m);
742
mon = INT2FIX(mon_num(mon));
744
s3e(hash, y, mon, d, !NIL_P(b) &&
745
(*RSTRING_PTR(b) == 'B' ||
746
*RSTRING_PTR(b) == 'b'));
751
parse_us(VALUE str, VALUE hash)
753
static const char pat_source[] =
754
"\\b(" ABBR_MONTHS ")[^-\\d\\s']*"
756
"('?\\d+)[^-\\d\\s']*"
759
"(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))?"
763
static VALUE pat = Qnil;
766
SUBS(str, pat, parse_us_cb);
770
parse_iso_cb(VALUE m, VALUE hash)
774
y = rb_reg_nth_match(1, m);
775
mon = rb_reg_nth_match(2, m);
776
d = rb_reg_nth_match(3, m);
778
s3e(hash, y, mon, d, 0);
783
parse_iso(VALUE str, VALUE hash)
785
static const char pat_source[] = "('?[-+]?\\d+)-(\\d+)-('?-?\\d+)";
786
static VALUE pat = Qnil;
789
SUBS(str, pat, parse_iso_cb);
793
parse_iso21_cb(VALUE m, VALUE hash)
797
y = rb_reg_nth_match(1, m);
798
w = rb_reg_nth_match(2, m);
799
d = rb_reg_nth_match(3, m);
802
set_hash("cwyear", str2num(y));
803
set_hash("cweek", str2num(w));
805
set_hash("cwday", str2num(d));
811
parse_iso21(VALUE str, VALUE hash)
813
static const char pat_source[] =
814
"\\b(\\d{2}|\\d{4})?-?w(\\d{2})(?:-?(\\d))?\\b";
815
static VALUE pat = Qnil;
818
SUBS(str, pat, parse_iso21_cb);
822
parse_iso22_cb(VALUE m, VALUE hash)
826
d = rb_reg_nth_match(1, m);
827
set_hash("cwday", str2num(d));
832
parse_iso22(VALUE str, VALUE hash)
834
static const char pat_source[] = "-w-(\\d)\\b";
835
static VALUE pat = Qnil;
838
SUBS(str, pat, parse_iso22_cb);
842
parse_iso23_cb(VALUE m, VALUE hash)
846
mon = rb_reg_nth_match(1, m);
847
d = rb_reg_nth_match(2, m);
850
set_hash("mon", str2num(mon));
851
set_hash("mday", str2num(d));
857
parse_iso23(VALUE str, VALUE hash)
859
static const char pat_source[] = "--(\\d{2})?-(\\d{2})\\b";
860
static VALUE pat = Qnil;
863
SUBS(str, pat, parse_iso23_cb);
867
parse_iso24_cb(VALUE m, VALUE hash)
871
mon = rb_reg_nth_match(1, m);
872
d = rb_reg_nth_match(2, m);
874
set_hash("mon", str2num(mon));
876
set_hash("mday", str2num(d));
882
parse_iso24(VALUE str, VALUE hash)
884
static const char pat_source[] = "--(\\d{2})(\\d{2})?\\b";
885
static VALUE pat = Qnil;
888
SUBS(str, pat, parse_iso24_cb);
892
parse_iso25_cb(VALUE m, VALUE hash)
896
y = rb_reg_nth_match(1, m);
897
d = rb_reg_nth_match(2, m);
899
set_hash("year", str2num(y));
900
set_hash("yday", str2num(d));
906
parse_iso25(VALUE str, VALUE hash)
908
static const char pat0_source[] = "[,.](\\d{2}|\\d{4})-\\d{3}\\b";
909
static VALUE pat0 = Qnil;
910
static const char pat_source[] = "\\b(\\d{2}|\\d{4})-(\\d{3})\\b";
911
static VALUE pat = Qnil;
916
if (!NIL_P(f_match(pat0, str)))
918
SUBS(str, pat, parse_iso25_cb);
922
parse_iso26_cb(VALUE m, VALUE hash)
926
d = rb_reg_nth_match(1, m);
927
set_hash("yday", str2num(d));
932
parse_iso26(VALUE str, VALUE hash)
934
static const char pat0_source[] = "\\d-\\d{3}\\b";
935
static VALUE pat0 = Qnil;
936
static const char pat_source[] = "\\b-(\\d{3})\\b";
937
static VALUE pat = Qnil;
942
if (!NIL_P(f_match(pat0, str)))
944
SUBS(str, pat, parse_iso26_cb);
948
parse_iso2(VALUE str, VALUE hash)
950
if (parse_iso21(str, hash))
952
if (parse_iso22(str, hash))
954
if (parse_iso23(str, hash))
956
if (parse_iso24(str, hash))
958
if (parse_iso25(str, hash))
960
if (parse_iso26(str, hash))
974
case 'M': case 'm': e = 1867; break;
975
case 'T': case 't': e = 1911; break;
976
case 'S': case 's': e = 1925; break;
977
case 'H': case 'h': e = 1988; break;
978
default: e = 0; break;
984
parse_jis_cb(VALUE m, VALUE hash)
989
e = rb_reg_nth_match(1, m);
990
y = rb_reg_nth_match(2, m);
991
mon = rb_reg_nth_match(3, m);
992
d = rb_reg_nth_match(4, m);
994
ep = gengo(*RSTRING_PTR(e));
996
set_hash("year", f_add(str2num(y), INT2FIX(ep)));
997
set_hash("mon", str2num(mon));
998
set_hash("mday", str2num(d));
1004
parse_jis(VALUE str, VALUE hash)
1006
static const char pat_source[] = "\\b([mtsh])(\\d+)\\.(\\d+)\\.(\\d+)";
1007
static VALUE pat = Qnil;
1010
SUBS(str, pat, parse_jis_cb);
1014
parse_vms11_cb(VALUE m, VALUE hash)
1018
d = rb_reg_nth_match(1, m);
1019
mon = rb_reg_nth_match(2, m);
1020
y = rb_reg_nth_match(3, m);
1022
mon = INT2FIX(mon_num(mon));
1024
s3e(hash, y, mon, d, 0);
1029
parse_vms11(VALUE str, VALUE hash)
1031
static const char pat_source[] =
1032
"('?-?\\d+)-(" ABBR_MONTHS ")[^-]*"
1034
static VALUE pat = Qnil;
1037
SUBS(str, pat, parse_vms11_cb);
1041
parse_vms12_cb(VALUE m, VALUE hash)
1045
mon = rb_reg_nth_match(1, m);
1046
d = rb_reg_nth_match(2, m);
1047
y = rb_reg_nth_match(3, m);
1049
mon = INT2FIX(mon_num(mon));
1051
s3e(hash, y, mon, d, 0);
1056
parse_vms12(VALUE str, VALUE hash)
1058
static const char pat_source[] =
1059
"\\b(" ABBR_MONTHS ")[^-]*"
1060
"-('?-?\\d+)(?:-('?-?\\d+))?";
1061
static VALUE pat = Qnil;
1064
SUBS(str, pat, parse_vms12_cb);
1068
parse_vms(VALUE str, VALUE hash)
1070
if (parse_vms11(str, hash))
1072
if (parse_vms12(str, hash))
1081
parse_sla_cb(VALUE m, VALUE hash)
1085
y = rb_reg_nth_match(1, m);
1086
mon = rb_reg_nth_match(2, m);
1087
d = rb_reg_nth_match(3, m);
1089
s3e(hash, y, mon, d, 0);
1094
parse_sla(VALUE str, VALUE hash)
1096
static const char pat_source[] =
1097
"('?-?\\d+)/\\s*('?\\d+)(?:\\D\\s*('?-?\\d+))?";
1098
static VALUE pat = Qnil;
1101
SUBS(str, pat, parse_sla_cb);
1105
parse_dot_cb(VALUE m, VALUE hash)
1109
y = rb_reg_nth_match(1, m);
1110
mon = rb_reg_nth_match(2, m);
1111
d = rb_reg_nth_match(3, m);
1113
s3e(hash, y, mon, d, 0);
1118
parse_dot(VALUE str, VALUE hash)
1120
static const char pat_source[] =
1121
"('?-?\\d+)\\.\\s*('?\\d+)\\.\\s*('?-?\\d+)";
1122
static VALUE pat = Qnil;
1125
SUBS(str, pat, parse_dot_cb);
1129
parse_year_cb(VALUE m, VALUE hash)
1133
y = rb_reg_nth_match(1, m);
1134
set_hash("year", str2num(y));
1139
parse_year(VALUE str, VALUE hash)
1141
static const char pat_source[] = "'(\\d+)\\b";
1142
static VALUE pat = Qnil;
1145
SUBS(str, pat, parse_year_cb);
1149
parse_mon_cb(VALUE m, VALUE hash)
1153
mon = rb_reg_nth_match(1, m);
1154
set_hash("mon", INT2FIX(mon_num(mon)));
1159
parse_mon(VALUE str, VALUE hash)
1161
static const char pat_source[] = "\\b(" ABBR_MONTHS ")\\S*";
1162
static VALUE pat = Qnil;
1165
SUBS(str, pat, parse_mon_cb);
1169
parse_mday_cb(VALUE m, VALUE hash)
1173
d = rb_reg_nth_match(1, m);
1174
set_hash("mday", str2num(d));
1179
parse_mday(VALUE str, VALUE hash)
1181
static const char pat_source[] = "(\\d+)(st|nd|rd|th)\\b";
1182
static VALUE pat = Qnil;
1185
SUBS(str, pat, parse_mday_cb);
1189
n2i(const char *s, long f, long w)
1196
for (i = f; i < e; i++) {
1204
parse_ddd_cb(VALUE m, VALUE hash)
1206
VALUE s1, s2, s3, s4, s5;
1207
const char *cs2, *cs3, *cs5;
1208
long l2, l3, l4, l5;
1210
s1 = rb_reg_nth_match(1, m);
1211
s2 = rb_reg_nth_match(2, m);
1212
s3 = rb_reg_nth_match(3, m);
1213
s4 = rb_reg_nth_match(4, m);
1214
s5 = rb_reg_nth_match(5, m);
1216
cs2 = RSTRING_PTR(s2);
1217
l2 = RSTRING_LEN(s2);
1221
if (NIL_P(s3) && !NIL_P(s4))
1222
set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1224
set_hash("mday", INT2FIX(n2i(cs2, 0, 2)));
1227
if (NIL_P(s3) && !NIL_P(s4)) {
1228
set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1229
set_hash("min", INT2FIX(n2i(cs2, l2-4, 2)));
1232
set_hash("mon", INT2FIX(n2i(cs2, 0, 2)));
1233
set_hash("mday", INT2FIX(n2i(cs2, 2, 2)));
1237
if (NIL_P(s3) && !NIL_P(s4)) {
1238
set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1239
set_hash("min", INT2FIX(n2i(cs2, l2-4, 2)));
1240
set_hash("hour", INT2FIX(n2i(cs2, l2-6, 2)));
1243
int y = n2i(cs2, 0, 2);
1244
if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-')
1246
set_hash("year", INT2FIX(y));
1247
set_hash("mon", INT2FIX(n2i(cs2, 2, 2)));
1248
set_hash("mday", INT2FIX(n2i(cs2, 4, 2)));
1255
if (NIL_P(s3) && !NIL_P(s4)) {
1256
set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1257
set_hash("min", INT2FIX(n2i(cs2, l2-4, 2)));
1258
set_hash("hour", INT2FIX(n2i(cs2, l2-6, 2)));
1259
set_hash("mday", INT2FIX(n2i(cs2, l2-8, 2)));
1261
set_hash("mon", INT2FIX(n2i(cs2, l2-10, 2)));
1263
int y = n2i(cs2, l2-12, 2);
1264
if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-')
1266
set_hash("year", INT2FIX(y));
1269
int y = n2i(cs2, l2-14, 4);
1270
if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-')
1272
set_hash("year", INT2FIX(y));
1273
set_hash("_comp", Qfalse);
1277
int y = n2i(cs2, 0, 4);
1278
if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-')
1280
set_hash("year", INT2FIX(y));
1281
set_hash("mon", INT2FIX(n2i(cs2, 4, 2)));
1282
set_hash("mday", INT2FIX(n2i(cs2, 6, 2)));
1284
set_hash("hour", INT2FIX(n2i(cs2, 8, 2)));
1286
set_hash("min", INT2FIX(n2i(cs2, 10, 2)));
1288
set_hash("sec", INT2FIX(n2i(cs2, 12, 2)));
1289
set_hash("_comp", Qfalse);
1293
if (NIL_P(s3) && !NIL_P(s4)) {
1294
set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1295
set_hash("min", INT2FIX(n2i(cs2, l2-3, 1)));
1298
set_hash("yday", INT2FIX(n2i(cs2, 0, 3)));
1301
if (NIL_P(s3) && !NIL_P(s4)) {
1302
set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1303
set_hash("min", INT2FIX(n2i(cs2, l2-4, 2)));
1304
set_hash("hour", INT2FIX(n2i(cs2, l2-5, 1)));
1307
int y = n2i(cs2, 0, 2);
1308
if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-')
1310
set_hash("year", INT2FIX(y));
1311
set_hash("yday", INT2FIX(n2i(cs2, 2, 3)));
1315
if (NIL_P(s3) && !NIL_P(s4)) {
1316
set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2)));
1317
set_hash("min", INT2FIX(n2i(cs2, l2-4, 2)));
1318
set_hash("hour", INT2FIX(n2i(cs2, l2-6, 2)));
1319
set_hash("mday", INT2FIX(n2i(cs2, l2-7, 1)));
1322
int y = n2i(cs2, 0, 4);
1323
if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-')
1325
set_hash("year", INT2FIX(y));
1326
set_hash("yday", INT2FIX(n2i(cs2, 4, 3)));
1332
cs3 = RSTRING_PTR(s3);
1333
l3 = RSTRING_LEN(s3);
1340
set_hash("sec", INT2FIX(n2i(cs3, l3-2, 2)));
1342
set_hash("min", INT2FIX(n2i(cs3, l3-4, 2)));
1344
set_hash("hour", INT2FIX(n2i(cs3, l3-6, 2)));
1353
set_hash("hour", INT2FIX(n2i(cs3, 0, 2)));
1355
set_hash("min", INT2FIX(n2i(cs3, 2, 2)));
1357
set_hash("sec", INT2FIX(n2i(cs3, 4, 2)));
1364
l4 = RSTRING_LEN(s4);
1366
set_hash("sec_fraction",
1367
rb_rational_new2(str2num(s4),
1368
f_expt(INT2FIX(10), LONG2NUM(l4))));
1371
cs5 = RSTRING_PTR(s5);
1372
l5 = RSTRING_LEN(s5);
1374
set_hash("zone", s5);
1377
char *buf = ALLOCA_N(char, l5 + 1);
1381
memcpy(buf, cs5, l5);
1385
s2 = strchr(buf, ':');
1394
zone = rb_str_new2(s3);
1395
set_hash("zone", zone);
1398
set_hash("offset", date_zone_to_diff(rb_str_new2(s1)));
1407
parse_ddd(VALUE str, VALUE hash)
1409
static const char pat_source[] =
1410
"([-+]?)(\\d{2,14})"
1415
"(\\d{2,6})?(?:[,.](\\d*))?"
1424
"\\[[-+]?\\d[^\\]]*\\]"
1427
static VALUE pat = Qnil;
1430
SUBS(str, pat, parse_ddd_cb);
1434
parse_bc_cb(VALUE m, VALUE hash)
1438
y = ref_hash("year");
1440
set_hash("year", f_add(f_negate(y), INT2FIX(1)));
1446
parse_bc(VALUE str, VALUE hash)
1448
static const char pat_source[] =
1449
"\\b(bc\\b|bce\\b|b\\.c\\.|b\\.c\\.e\\.)";
1450
static VALUE pat = Qnil;
1453
SUBS(str, pat, parse_bc_cb);
1457
parse_frag_cb(VALUE m, VALUE hash)
1461
s = rb_reg_nth_match(1, m);
1463
if (!NIL_P(ref_hash("hour")) && NIL_P(ref_hash("mday"))) {
1465
if (f_ge_p(n, INT2FIX(1)) &&
1466
f_le_p(n, INT2FIX(31)))
1467
set_hash("mday", n);
1469
if (!NIL_P(ref_hash("mday")) && NIL_P(ref_hash("hour"))) {
1471
if (f_ge_p(n, INT2FIX(0)) &&
1472
f_le_p(n, INT2FIX(24)))
1473
set_hash("hour", n);
1480
parse_frag(VALUE str, VALUE hash)
1482
static const char pat_source[] = "\\A\\s*(\\d{1,2})\\s*\\z";
1483
static VALUE pat = Qnil;
1486
SUBS(str, pat, parse_frag_cb);
1489
#define HAVE_ALPHA (1<<0)
1490
#define HAVE_DIGIT (1<<1)
1491
#define HAVE_DASH (1<<2)
1492
#define HAVE_DOT (1<<3)
1493
#define HAVE_SLASH (1<<4)
1496
check_class(VALUE s)
1502
for (i = 0; i < RSTRING_LEN(s); i++) {
1503
if (isalpha(RSTRING_PTR(s)[i]))
1504
flags |= HAVE_ALPHA;
1505
if (isdigit(RSTRING_PTR(s)[i]))
1506
flags |= HAVE_DIGIT;
1507
if (RSTRING_PTR(s)[i] == '-')
1509
if (RSTRING_PTR(s)[i] == '.')
1511
if (RSTRING_PTR(s)[i] == '/')
1512
flags |= HAVE_SLASH;
1517
#define HAVE_ELEM_P(x) ((check_class(str) & (x)) == (x))
1520
date__parse(VALUE str, VALUE comp)
1522
VALUE backref, hash;
1524
backref = rb_backref_get();
1525
rb_match_busy(backref);
1528
static const char pat_source[] = "[^-+',./:@[:alnum:]\\[\\]]+";
1529
static VALUE pat = Qnil;
1532
str = rb_str_dup(str);
1533
f_gsub_bang(str, pat, asp_string());
1536
hash = rb_hash_new();
1537
set_hash("_comp", comp);
1539
if (HAVE_ELEM_P(HAVE_ALPHA))
1540
parse_day(str, hash);
1541
if (HAVE_ELEM_P(HAVE_DIGIT))
1542
parse_time(str, hash);
1544
if (HAVE_ELEM_P(HAVE_ALPHA|HAVE_DIGIT))
1545
if (parse_eu(str, hash))
1547
if (HAVE_ELEM_P(HAVE_ALPHA|HAVE_DIGIT))
1548
if (parse_us(str, hash))
1550
if (HAVE_ELEM_P(HAVE_DIGIT|HAVE_DASH))
1551
if (parse_iso(str, hash))
1553
if (HAVE_ELEM_P(HAVE_DIGIT|HAVE_DOT))
1554
if (parse_jis(str, hash))
1556
if (HAVE_ELEM_P(HAVE_ALPHA|HAVE_DIGIT|HAVE_DASH))
1557
if (parse_vms(str, hash))
1559
if (HAVE_ELEM_P(HAVE_DIGIT|HAVE_SLASH))
1560
if (parse_sla(str, hash))
1562
if (HAVE_ELEM_P(HAVE_DIGIT|HAVE_DOT))
1563
if (parse_dot(str, hash))
1565
if (HAVE_ELEM_P(HAVE_DIGIT))
1566
if (parse_iso2(str, hash))
1568
if (HAVE_ELEM_P(HAVE_DIGIT))
1569
if (parse_year(str, hash))
1571
if (HAVE_ELEM_P(HAVE_ALPHA))
1572
if (parse_mon(str, hash))
1574
if (HAVE_ELEM_P(HAVE_DIGIT))
1575
if (parse_mday(str, hash))
1577
if (HAVE_ELEM_P(HAVE_DIGIT))
1578
if (parse_ddd(str, hash))
1582
if (HAVE_ELEM_P(HAVE_ALPHA))
1583
parse_bc(str, hash);
1584
if (HAVE_ELEM_P(HAVE_DIGIT))
1585
parse_frag(str, hash);
1588
if (RTEST(ref_hash("_comp"))) {
1591
y = ref_hash("cwyear");
1593
if (f_ge_p(y, INT2FIX(0)) && f_le_p(y, INT2FIX(99))) {
1594
if (f_ge_p(y, INT2FIX(69)))
1595
set_hash("cwyear", f_add(y, INT2FIX(1900)));
1597
set_hash("cwyear", f_add(y, INT2FIX(2000)));
1599
y = ref_hash("year");
1601
if (f_ge_p(y, INT2FIX(0)) && f_le_p(y, INT2FIX(99))) {
1602
if (f_ge_p(y, INT2FIX(69)))
1603
set_hash("year", f_add(y, INT2FIX(1900)));
1605
set_hash("year", f_add(y, INT2FIX(2000)));
1613
VALUE zone = ref_hash("zone");
1614
if (!NIL_P(zone) && NIL_P(ref_hash("offset")))
1615
set_hash("offset", date_zone_to_diff(zone));
1618
rb_backref_set(backref);
1624
comp_year69(VALUE y)
1626
if (f_ge_p(y, INT2FIX(69)))
1627
return f_add(y, INT2FIX(1900));
1628
return f_add(y, INT2FIX(2000));
1632
comp_year50(VALUE y)
1634
if (f_ge_p(y, INT2FIX(50)))
1635
return f_add(y, INT2FIX(1900));
1636
return f_add(y, INT2FIX(2000));
1640
sec_fraction(VALUE f)
1642
return rb_rational_new2(str2num(f),
1644
LONG2NUM(RSTRING_LEN(f))));
1650
iso8601_ext_datetime_cb(VALUE m, VALUE hash)
1652
VALUE s[SNUM + 1], y;
1657
for (i = 1; i <= SNUM; i++)
1658
s[i] = rb_reg_nth_match(i, m);
1662
set_hash("mday", str2num(s[3]));
1663
if (strcmp(RSTRING_PTR(s[1]), "-") != 0) {
1665
if (RSTRING_LEN(s[1]) < 4)
1667
set_hash("year", y);
1670
if (strcmp(RSTRING_PTR(s[1]), "-") != 0)
1674
set_hash("mon", str2num(s[2]));
1676
else if (!NIL_P(s[5])) {
1677
set_hash("yday", str2num(s[5]));
1680
if (RSTRING_LEN(s[4]) < 4)
1682
set_hash("year", y);
1685
else if (!NIL_P(s[8])) {
1686
set_hash("cweek", str2num(s[7]));
1687
set_hash("cwday", str2num(s[8]));
1690
if (RSTRING_LEN(s[6]) < 4)
1692
set_hash("cwyear", y);
1695
else if (!NIL_P(s[9])) {
1696
set_hash("cwday", str2num(s[9]));
1698
if (!NIL_P(s[10])) {
1699
set_hash("hour", str2num(s[10]));
1700
set_hash("min", str2num(s[11]));
1702
set_hash("sec", str2num(s[12]));
1704
if (!NIL_P(s[13])) {
1705
set_hash("sec_fraction", sec_fraction(s[13]));
1707
if (!NIL_P(s[14])) {
1708
set_hash("zone", s[14]);
1709
set_hash("offset", date_zone_to_diff(s[14]));
1716
iso8601_ext_datetime(VALUE str, VALUE hash)
1718
static const char pat_source[] =
1719
"\\A\\s*(?:([-+]?\\d{2,}|-)-(\\d{2})?-(\\d{2})|"
1720
"([-+]?\\d{2,})?-(\\d{3})|"
1721
"(\\d{4}|\\d{2})?-w(\\d{2})-(\\d)|"
1724
"(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d+))?)?"
1725
"(z|[-+]\\d{2}(?::?\\d{2})?)?)?\\s*\\z";
1726
static VALUE pat = Qnil;
1729
SUBS(str, pat, iso8601_ext_datetime_cb);
1736
iso8601_bas_datetime_cb(VALUE m, VALUE hash)
1738
VALUE s[SNUM + 1], y;
1743
for (i = 1; i <= SNUM; i++)
1744
s[i] = rb_reg_nth_match(i, m);
1748
set_hash("mday", str2num(s[3]));
1749
if (strcmp(RSTRING_PTR(s[1]), "--") != 0) {
1751
if (RSTRING_LEN(s[1]) < 4)
1753
set_hash("year", y);
1755
if (*RSTRING_PTR(s[2]) == '-') {
1756
if (strcmp(RSTRING_PTR(s[1]), "--") != 0)
1760
set_hash("mon", str2num(s[2]));
1762
else if (!NIL_P(s[5])) {
1763
set_hash("yday", str2num(s[5]));
1765
if (RSTRING_LEN(s[4]) < 4)
1767
set_hash("year", y);
1769
else if (!NIL_P(s[6])) {
1770
set_hash("yday", str2num(s[6]));
1772
else if (!NIL_P(s[9])) {
1773
set_hash("cweek", str2num(s[8]));
1774
set_hash("cwday", str2num(s[9]));
1776
if (RSTRING_LEN(s[7]) < 4)
1778
set_hash("cwyear", y);
1780
else if (!NIL_P(s[11])) {
1781
set_hash("cweek", str2num(s[10]));
1782
set_hash("cwday", str2num(s[11]));
1784
else if (!NIL_P(s[12])) {
1785
set_hash("cwday", str2num(s[12]));
1787
if (!NIL_P(s[13])) {
1788
set_hash("hour", str2num(s[13]));
1789
set_hash("min", str2num(s[14]));
1791
set_hash("sec", str2num(s[15]));
1793
if (!NIL_P(s[16])) {
1794
set_hash("sec_fraction", sec_fraction(s[16]));
1796
if (!NIL_P(s[17])) {
1797
set_hash("zone", s[17]);
1798
set_hash("offset", date_zone_to_diff(s[17]));
1805
iso8601_bas_datetime(VALUE str, VALUE hash)
1807
static const char pat_source[] =
1808
"\\A\\s*(?:([-+]?(?:\\d{4}|\\d{2})|--)(\\d{2}|-)(\\d{2})|"
1809
"([-+]?(?:\\d{4}|\\d{2}))(\\d{3})|"
1811
"(\\d{4}|\\d{2})w(\\d{2})(\\d)|"
1815
"(\\d{2})(\\d{2})(?:(\\d{2})(?:[,.](\\d+))?)?"
1816
"(z|[-+]\\d{2}(?:\\d{2})?)?)?\\s*\\z";
1817
static VALUE pat = Qnil;
1820
SUBS(str, pat, iso8601_bas_datetime_cb);
1827
iso8601_ext_time_cb(VALUE m, VALUE hash)
1834
for (i = 1; i <= SNUM; i++)
1835
s[i] = rb_reg_nth_match(i, m);
1838
set_hash("hour", str2num(s[1]));
1839
set_hash("min", str2num(s[2]));
1841
set_hash("sec", str2num(s[3]));
1843
set_hash("sec_fraction", sec_fraction(s[4]));
1845
set_hash("zone", s[5]);
1846
set_hash("offset", date_zone_to_diff(s[5]));
1852
#define iso8601_bas_time_cb iso8601_ext_time_cb
1855
iso8601_ext_time(VALUE str, VALUE hash)
1857
static const char pat_source[] =
1858
"\\A\\s*(?:(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d+))?)?"
1859
"(z|[-+]\\d{2}(:?\\d{2})?)?)?\\s*\\z";
1860
static VALUE pat = Qnil;
1863
SUBS(str, pat, iso8601_ext_time_cb);
1867
iso8601_bas_time(VALUE str, VALUE hash)
1869
static const char pat_source[] =
1870
"\\A\\s*(?:(\\d{2})(\\d{2})(?:(\\d{2})(?:[,.](\\d+))?)?"
1871
"(z|[-+]\\d{2}(\\d{2})?)?)?\\s*\\z";
1872
static VALUE pat = Qnil;
1875
SUBS(str, pat, iso8601_bas_time_cb);
1879
date__iso8601(VALUE str)
1881
VALUE backref, hash;
1883
backref = rb_backref_get();
1884
rb_match_busy(backref);
1886
hash = rb_hash_new();
1888
if (iso8601_ext_datetime(str, hash))
1890
if (iso8601_bas_datetime(str, hash))
1892
if (iso8601_ext_time(str, hash))
1894
if (iso8601_bas_time(str, hash))
1898
rb_backref_set(backref);
1907
rfc3339_cb(VALUE m, VALUE hash)
1914
for (i = 1; i <= SNUM; i++)
1915
s[i] = rb_reg_nth_match(i, m);
1918
set_hash("year", str2num(s[1]));
1919
set_hash("mon", str2num(s[2]));
1920
set_hash("mday", str2num(s[3]));
1921
set_hash("hour", str2num(s[4]));
1922
set_hash("min", str2num(s[5]));
1923
set_hash("sec", str2num(s[6]));
1924
set_hash("zone", s[8]);
1925
set_hash("offset", date_zone_to_diff(s[8]));
1927
set_hash("sec_fraction", sec_fraction(s[7]));
1933
rfc3339(VALUE str, VALUE hash)
1935
static const char pat_source[] =
1936
"\\A\\s*(-?\\d{4})-(\\d{2})-(\\d{2})"
1938
"(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?"
1939
"(z|[-+]\\d{2}:\\d{2})\\s*\\z";
1940
static VALUE pat = Qnil;
1943
SUBS(str, pat, rfc3339_cb);
1947
date__rfc3339(VALUE str)
1949
VALUE backref, hash;
1951
backref = rb_backref_get();
1952
rb_match_busy(backref);
1954
hash = rb_hash_new();
1956
rb_backref_set(backref);
1964
xmlschema_datetime_cb(VALUE m, VALUE hash)
1971
for (i = 1; i <= SNUM; i++)
1972
s[i] = rb_reg_nth_match(i, m);
1975
set_hash("year", str2num(s[1]));
1977
set_hash("mon", str2num(s[2]));
1979
set_hash("mday", str2num(s[3]));
1981
set_hash("hour", str2num(s[4]));
1983
set_hash("min", str2num(s[5]));
1985
set_hash("sec", str2num(s[6]));
1987
set_hash("sec_fraction", sec_fraction(s[7]));
1989
set_hash("zone", s[8]);
1990
set_hash("offset", date_zone_to_diff(s[8]));
1997
xmlschema_datetime(VALUE str, VALUE hash)
1999
static const char pat_source[] =
2000
"\\A\\s*(-?\\d{4,})(?:-(\\d{2})(?:-(\\d{2}))?)?"
2002
"(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?)?"
2003
"(z|[-+]\\d{2}:\\d{2})?\\s*\\z";
2004
static VALUE pat = Qnil;
2007
SUBS(str, pat, xmlschema_datetime_cb);
2014
xmlschema_time_cb(VALUE m, VALUE hash)
2021
for (i = 1; i <= SNUM; i++)
2022
s[i] = rb_reg_nth_match(i, m);
2025
set_hash("hour", str2num(s[1]));
2026
set_hash("min", str2num(s[2]));
2028
set_hash("sec", str2num(s[3]));
2030
set_hash("sec_fraction", sec_fraction(s[4]));
2032
set_hash("zone", s[5]);
2033
set_hash("offset", date_zone_to_diff(s[5]));
2040
xmlschema_time(VALUE str, VALUE hash)
2042
static const char pat_source[] =
2043
"\\A\\s*(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?"
2044
"(z|[-+]\\d{2}:\\d{2})?\\s*\\z";
2045
static VALUE pat = Qnil;
2048
SUBS(str, pat, xmlschema_time_cb);
2055
xmlschema_trunc_cb(VALUE m, VALUE hash)
2062
for (i = 1; i <= SNUM; i++)
2063
s[i] = rb_reg_nth_match(i, m);
2067
set_hash("mon", str2num(s[1]));
2069
set_hash("mday", str2num(s[2]));
2071
set_hash("mday", str2num(s[3]));
2073
set_hash("zone", s[4]);
2074
set_hash("offset", date_zone_to_diff(s[4]));
2081
xmlschema_trunc(VALUE str, VALUE hash)
2083
static const char pat_source[] =
2084
"\\A\\s*(?:--(\\d{2})(?:-(\\d{2}))?|---(\\d{2}))"
2085
"(z|[-+]\\d{2}:\\d{2})?\\s*\\z";
2086
static VALUE pat = Qnil;
2089
SUBS(str, pat, xmlschema_trunc_cb);
2093
date__xmlschema(VALUE str)
2095
VALUE backref, hash;
2097
backref = rb_backref_get();
2098
rb_match_busy(backref);
2100
hash = rb_hash_new();
2102
if (xmlschema_datetime(str, hash))
2104
if (xmlschema_time(str, hash))
2106
if (xmlschema_trunc(str, hash))
2110
rb_backref_set(backref);
2119
rfc2822_cb(VALUE m, VALUE hash)
2121
VALUE s[SNUM + 1], y;
2126
for (i = 1; i <= SNUM; i++)
2127
s[i] = rb_reg_nth_match(i, m);
2130
set_hash("wday", INT2FIX(day_num(s[1])));
2131
set_hash("mday", str2num(s[2]));
2132
set_hash("mon", INT2FIX(mon_num(s[3])));
2134
if (RSTRING_LEN(s[4]) < 4)
2136
set_hash("year", y);
2137
set_hash("hour", str2num(s[5]));
2138
set_hash("min", str2num(s[6]));
2140
set_hash("sec", str2num(s[7]));
2141
set_hash("zone", s[8]);
2142
set_hash("offset", date_zone_to_diff(s[8]));
2148
rfc2822(VALUE str, VALUE hash)
2150
static const char pat_source[] =
2151
"\\A\\s*(?:(" ABBR_DAYS ")\\s*,\\s+)?"
2153
"(" ABBR_MONTHS ")\\s+"
2155
"(\\d{2}):(\\d{2})(?::(\\d{2}))?\\s*"
2156
"([-+]\\d{4}|ut|gmt|e[sd]t|c[sd]t|m[sd]t|p[sd]t|[a-ik-z])\\s*\\z";
2157
static VALUE pat = Qnil;
2160
SUBS(str, pat, rfc2822_cb);
2164
date__rfc2822(VALUE str)
2166
VALUE backref, hash;
2168
backref = rb_backref_get();
2169
rb_match_busy(backref);
2171
hash = rb_hash_new();
2173
rb_backref_set(backref);
2181
httpdate_type1_cb(VALUE m, VALUE hash)
2188
for (i = 1; i <= SNUM; i++)
2189
s[i] = rb_reg_nth_match(i, m);
2192
set_hash("wday", INT2FIX(day_num(s[1])));
2193
set_hash("mday", str2num(s[2]));
2194
set_hash("mon", INT2FIX(mon_num(s[3])));
2195
set_hash("year", str2num(s[4]));
2196
set_hash("hour", str2num(s[5]));
2197
set_hash("min", str2num(s[6]));
2198
set_hash("sec", str2num(s[7]));
2199
set_hash("zone", s[8]);
2200
set_hash("offset", INT2FIX(0));
2206
httpdate_type1(VALUE str, VALUE hash)
2208
static const char pat_source[] =
2209
"\\A\\s*(" ABBR_DAYS ")\\s*,\\s+"
2211
"(" ABBR_MONTHS ")\\s+"
2213
"(\\d{2}):(\\d{2}):(\\d{2})\\s+"
2215
static VALUE pat = Qnil;
2218
SUBS(str, pat, httpdate_type1_cb);
2225
httpdate_type2_cb(VALUE m, VALUE hash)
2227
VALUE s[SNUM + 1], y;
2232
for (i = 1; i <= SNUM; i++)
2233
s[i] = rb_reg_nth_match(i, m);
2236
set_hash("wday", INT2FIX(day_num(s[1])));
2237
set_hash("mday", str2num(s[2]));
2238
set_hash("mon", INT2FIX(mon_num(s[3])));
2240
if (f_ge_p(y, INT2FIX(0)) && f_le_p(y, INT2FIX(99)))
2242
set_hash("year", y);
2243
set_hash("hour", str2num(s[5]));
2244
set_hash("min", str2num(s[6]));
2245
set_hash("sec", str2num(s[7]));
2246
set_hash("zone", s[8]);
2247
set_hash("offset", INT2FIX(0));
2253
httpdate_type2(VALUE str, VALUE hash)
2255
static const char pat_source[] =
2256
"\\A\\s*(" DAYS ")\\s*,\\s+"
2258
"(" ABBR_MONTHS ")\\s*-\\s*"
2260
"(\\d{2}):(\\d{2}):(\\d{2})\\s+"
2262
static VALUE pat = Qnil;
2265
SUBS(str, pat, httpdate_type2_cb);
2272
httpdate_type3_cb(VALUE m, VALUE hash)
2279
for (i = 1; i <= SNUM; i++)
2280
s[i] = rb_reg_nth_match(i, m);
2283
set_hash("wday", INT2FIX(day_num(s[1])));
2284
set_hash("mon", INT2FIX(mon_num(s[2])));
2285
set_hash("mday", str2num(s[3]));
2286
set_hash("hour", str2num(s[4]));
2287
set_hash("min", str2num(s[5]));
2288
set_hash("sec", str2num(s[6]));
2289
set_hash("year", str2num(s[7]));
2295
httpdate_type3(VALUE str, VALUE hash)
2297
static const char pat_source[] =
2298
"\\A\\s*(" ABBR_DAYS ")\\s+"
2299
"(" ABBR_MONTHS ")\\s+"
2301
"(\\d{2}):(\\d{2}):(\\d{2})\\s+"
2303
static VALUE pat = Qnil;
2306
SUBS(str, pat, httpdate_type3_cb);
2310
date__httpdate(VALUE str)
2312
VALUE backref, hash;
2314
backref = rb_backref_get();
2315
rb_match_busy(backref);
2317
hash = rb_hash_new();
2319
if (httpdate_type1(str, hash))
2321
if (httpdate_type2(str, hash))
2323
if (httpdate_type3(str, hash))
2327
rb_backref_set(backref);
2336
jisx0301_cb(VALUE m, VALUE hash)
2344
for (i = 1; i <= SNUM; i++)
2345
s[i] = rb_reg_nth_match(i, m);
2348
ep = gengo(NIL_P(s[1]) ? 'h' : *RSTRING_PTR(s[1]));
2349
set_hash("year", f_add(str2num(s[2]), INT2FIX(ep)));
2350
set_hash("mon", str2num(s[3]));
2351
set_hash("mday", str2num(s[4]));
2353
set_hash("hour", str2num(s[5]));
2355
set_hash("min", str2num(s[6]));
2357
set_hash("sec", str2num(s[7]));
2360
set_hash("sec_fraction", sec_fraction(s[8]));
2362
set_hash("zone", s[9]);
2363
set_hash("offset", date_zone_to_diff(s[9]));
2370
jisx0301(VALUE str, VALUE hash)
2372
static const char pat_source[] =
2373
"\\A\\s*([mtsh])?(\\d{2})\\.(\\d{2})\\.(\\d{2})"
2375
"(?:(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d*))?)?"
2376
"(z|[-+]\\d{2}(?::?\\d{2})?)?)?)?\\s*\\z";
2377
static VALUE pat = Qnil;
2380
SUBS(str, pat, jisx0301_cb);
2384
date__jisx0301(VALUE str)
2386
VALUE backref, hash;
2388
backref = rb_backref_get();
2389
rb_match_busy(backref);
2391
hash = rb_hash_new();
2392
if (jisx0301(str, hash))
2394
hash = date__iso8601(str);
2397
rb_backref_set(backref);
2403
c-file-style: "ruby"