date 2.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -70,7 +70,7 @@ static size_t
70
70
  digit_span(const char *s, const char *e)
71
71
  {
72
72
  size_t i = 0;
73
- while (s + i < e && isdigit(s[i])) i++;
73
+ while (s + i < e && isdigit((unsigned char)s[i])) i++;
74
74
  return i;
75
75
  }
76
76
 
@@ -110,7 +110,7 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
110
110
 
111
111
  s = RSTRING_PTR(y);
112
112
  ep = RSTRING_END(y);
113
- while (s < ep && !issign(*s) && !isdigit(*s))
113
+ while (s < ep && !issign(*s) && !isdigit((unsigned char)*s))
114
114
  s++;
115
115
  if (s >= ep) goto no_date;
116
116
  bp = s;
@@ -162,7 +162,7 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
162
162
 
163
163
  s = RSTRING_PTR(y);
164
164
  ep = RSTRING_END(y);
165
- while (s < ep && !issign(*s) && !isdigit(*s))
165
+ while (s < ep && !issign(*s) && !isdigit((unsigned char)*s))
166
166
  s++;
167
167
  if (s >= ep) goto no_year;
168
168
  bp = s;
@@ -199,7 +199,7 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
199
199
 
200
200
  s = RSTRING_PTR(m);
201
201
  ep = RSTRING_END(m);
202
- while (s < ep && !isdigit(*s))
202
+ while (s < ep && !isdigit((unsigned char)*s))
203
203
  s++;
204
204
  if (s >= ep) goto no_month;
205
205
  bp = s;
@@ -225,7 +225,7 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
225
225
 
226
226
  s = RSTRING_PTR(d);
227
227
  ep = RSTRING_END(d);
228
- while (s < ep && !isdigit(*s))
228
+ while (s < ep && !isdigit((unsigned char)*s))
229
229
  s++;
230
230
  if (s >= ep) goto no_mday;
231
231
  bp = s;
@@ -361,66 +361,90 @@ do { \
361
361
  #include "zonetab.h"
362
362
 
363
363
  static int
364
- str_end_with(const char *s, long l, const char *w)
364
+ str_end_with_word(const char *s, long l, const char *w)
365
365
  {
366
366
  int n = (int)strlen(w);
367
- return (l >= n && strncmp(s - n, w, n) == 0);
367
+ if (l <= n || !isspace((unsigned char)s[l - n - 1])) return 0;
368
+ if (strncasecmp(&s[l - n], w, n)) return 0;
369
+ do ++n; while (l > n && isspace((unsigned char)s[l - n - 1]));
370
+ return n;
368
371
  }
369
372
 
370
- VALUE
371
- date_zone_to_diff(VALUE str)
373
+ static long
374
+ shrunk_size(const char *s, long l)
372
375
  {
373
- VALUE offset = Qnil;
374
- VALUE vbuf = 0;
375
-
376
- long l, i;
377
- char *s, *dest, *d;
378
- int sp = 1;
379
-
380
- l = RSTRING_LEN(str);
381
- s = RSTRING_PTR(str);
382
-
383
- dest = d = ALLOCV_N(char, vbuf, l + 1);
384
-
385
- for (i = 0; i < l; i++) {
386
- if (isspace((unsigned char)s[i]) || s[i] == '\0') {
387
- if (!sp)
388
- *d++ = ' ';
389
- sp = 1;
376
+ long i, ni;
377
+ int sp = 0;
378
+ for (i = ni = 0; i < l; ++i) {
379
+ if (!isspace((unsigned char)s[i])) {
380
+ if (sp) ni++;
381
+ sp = 0;
382
+ ni++;
390
383
  }
391
384
  else {
392
- if (isalpha((unsigned char)s[i]))
393
- *d++ = tolower((unsigned char)s[i]);
394
- else
395
- *d++ = s[i];
396
- sp = 0;
385
+ sp = 1;
397
386
  }
398
387
  }
399
- if (d > dest) {
400
- if (*(d - 1) == ' ')
401
- --d;
402
- *d = '\0';
388
+ return ni < l ? ni : 0;
389
+ }
390
+
391
+ static long
392
+ shrink_space(char *d, const char *s, long l)
393
+ {
394
+ long i, ni;
395
+ int sp = 0;
396
+ for (i = ni = 0; i < l; ++i) {
397
+ if (!isspace((unsigned char)s[i])) {
398
+ if (sp) d[ni++] = ' ';
399
+ sp = 0;
400
+ d[ni++] = s[i];
401
+ }
402
+ else {
403
+ sp = 1;
404
+ }
403
405
  }
404
- l = d - dest;
405
- s = dest;
406
+ return ni;
407
+ }
408
+
409
+ VALUE
410
+ date_zone_to_diff(VALUE str)
411
+ {
412
+ VALUE offset = Qnil;
413
+ VALUE vbuf = 0;
414
+ long l = RSTRING_LEN(str);
415
+ const char *s = RSTRING_PTR(str);
416
+
406
417
  {
407
- static const char STD[] = " standard time";
408
- static const char DST1[] = " daylight time";
409
- static const char DST2[] = " dst";
410
418
  int dst = 0;
419
+ int w;
411
420
 
412
- if (str_end_with(d, l, STD)) {
413
- l -= sizeof(STD) - 1;
414
- }
415
- else if (str_end_with(d, l, DST1)) {
416
- l -= sizeof(DST1) - 1;
417
- dst = 1;
421
+ if ((w = str_end_with_word(s, l, "time")) > 0) {
422
+ int wtime = w;
423
+ l -= w;
424
+ if ((w = str_end_with_word(s, l, "standard")) > 0) {
425
+ l -= w;
426
+ }
427
+ else if ((w = str_end_with_word(s, l, "daylight")) > 0) {
428
+ l -= w;
429
+ dst = 1;
430
+ }
431
+ else {
432
+ l += wtime;
433
+ }
418
434
  }
419
- else if (str_end_with(d, l, DST2)) {
420
- l -= sizeof(DST2) - 1;
435
+ else if ((w = str_end_with_word(s, l, "dst")) > 0) {
436
+ l -= w;
421
437
  dst = 1;
422
438
  }
423
439
  {
440
+ long sl = shrunk_size(s, l);
441
+ if (sl > 0 && sl <= MAX_WORD_LENGTH) {
442
+ char *d = ALLOCV_N(char, vbuf, sl);
443
+ l = shrink_space(d, s, l);
444
+ s = d;
445
+ }
446
+ }
447
+ if (l > 0 && l <= MAX_WORD_LENGTH) {
424
448
  const struct zone *z = zonetab(s, (unsigned int)l);
425
449
  if (z) {
426
450
  int d = z->offset;
@@ -436,8 +460,8 @@ date_zone_to_diff(VALUE str)
436
460
  long hour = 0, min = 0, sec = 0;
437
461
 
438
462
  if (l > 3 &&
439
- (strncmp(s, "gmt", 3) == 0 ||
440
- strncmp(s, "utc", 3) == 0)) {
463
+ (strncasecmp(s, "gmt", 3) == 0 ||
464
+ strncasecmp(s, "utc", 3) == 0)) {
441
465
  s += 3;
442
466
  l -= 3;
443
467
  }
@@ -730,8 +754,8 @@ check_year_width(VALUE y)
730
754
  l = RSTRING_LEN(y);
731
755
  if (l < 2) return 0;
732
756
  s = RSTRING_PTR(y);
733
- if (!isdigit(s[1])) return 0;
734
- return (l == 2 || !isdigit(s[2]));
757
+ if (!isdigit((unsigned char)s[1])) return 0;
758
+ return (l == 2 || !isdigit((unsigned char)s[2]));
735
759
  }
736
760
 
737
761
  static int
@@ -1212,6 +1236,9 @@ parse_iso2(VALUE str, VALUE hash)
1212
1236
  return 1;
1213
1237
  }
1214
1238
 
1239
+ #define JISX0301_ERA_INITIALS "mtshr"
1240
+ #define JISX0301_DEFAULT_ERA 'H' /* obsolete */
1241
+
1215
1242
  static int
1216
1243
  gengo(int c)
1217
1244
  {
@@ -1222,6 +1249,7 @@ gengo(int c)
1222
1249
  case 'T': case 't': e = 1911; break;
1223
1250
  case 'S': case 's': e = 1925; break;
1224
1251
  case 'H': case 'h': e = 1988; break;
1252
+ case 'R': case 'r': e = 2018; break;
1225
1253
  default: e = 0; break;
1226
1254
  }
1227
1255
  return e;
@@ -1252,11 +1280,11 @@ parse_jis(VALUE str, VALUE hash)
1252
1280
  {
1253
1281
  static const char pat_source[] =
1254
1282
  #ifndef TIGHT_PARSER
1255
- "\\b([mtsh])(\\d+)\\.(\\d+)\\.(\\d+)"
1283
+ "\\b([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)"
1256
1284
  #else
1257
1285
  BOS
1258
1286
  FPW_COM FPT_COM
1259
- "([mtsh])(\\d+)\\.(\\d+)\\.(\\d+)"
1287
+ "([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)"
1260
1288
  TEE_FPT COM_FPW
1261
1289
  EOS
1262
1290
  #endif
@@ -1859,30 +1887,26 @@ parse_ddd_cb(VALUE m, VALUE hash)
1859
1887
  set_hash("zone", s5);
1860
1888
 
1861
1889
  if (*cs5 == '[') {
1862
- VALUE vbuf = 0;
1863
- char *buf = ALLOCV_N(char, vbuf, l5 + 1);
1864
- char *s1, *s2, *s3;
1890
+ const char *s1, *s2;
1865
1891
  VALUE zone;
1866
1892
 
1867
- memcpy(buf, cs5, l5);
1868
- buf[l5 - 1] = '\0';
1869
-
1870
- s1 = buf + 1;
1871
- s2 = strchr(buf, ':');
1893
+ l5 -= 2;
1894
+ s1 = cs5 + 1;
1895
+ s2 = memchr(s1, ':', l5);
1872
1896
  if (s2) {
1873
- *s2 = '\0';
1874
1897
  s2++;
1898
+ zone = rb_str_subseq(s5, s2 - cs5, l5 - (s2 - s1));
1899
+ s5 = rb_str_subseq(s5, 1, s2 - s1);
1875
1900
  }
1876
- if (s2)
1877
- s3 = s2;
1878
- else
1879
- s3 = s1;
1880
- zone = rb_str_new2(s3);
1901
+ else {
1902
+ zone = rb_str_subseq(s5, 1, l5);
1903
+ if (isdigit((unsigned char)*s1))
1904
+ s5 = rb_str_append(rb_str_new_cstr("+"), zone);
1905
+ else
1906
+ s5 = zone;
1907
+ }
1881
1908
  set_hash("zone", zone);
1882
- if (isdigit((unsigned char)*s1))
1883
- *--s1 = '+';
1884
- set_hash("offset", date_zone_to_diff(rb_str_new2(s1)));
1885
- ALLOCV_END(vbuf);
1909
+ set_hash("offset", date_zone_to_diff(s5));
1886
1910
  }
1887
1911
  RB_GC_GUARD(s5);
1888
1912
  }
@@ -2175,7 +2199,7 @@ date__parse(VALUE str, VALUE comp)
2175
2199
  #endif
2176
2200
 
2177
2201
  {
2178
- if (RTEST(ref_hash("_bc"))) {
2202
+ if (RTEST(del_hash("_bc"))) {
2179
2203
  VALUE y;
2180
2204
 
2181
2205
  y = ref_hash("cwyear");
@@ -2190,7 +2214,7 @@ date__parse(VALUE str, VALUE comp)
2190
2214
  }
2191
2215
  }
2192
2216
 
2193
- if (RTEST(ref_hash("_comp"))) {
2217
+ if (RTEST(del_hash("_comp"))) {
2194
2218
  VALUE y;
2195
2219
 
2196
2220
  y = ref_hash("cwyear");
@@ -2213,9 +2237,6 @@ date__parse(VALUE str, VALUE comp)
2213
2237
 
2214
2238
  }
2215
2239
 
2216
- del_hash("_bc");
2217
- del_hash("_comp");
2218
-
2219
2240
  {
2220
2241
  VALUE zone = ref_hash("zone");
2221
2242
  if (!NIL_P(zone) && NIL_P(ref_hash("offset")))
@@ -2265,8 +2286,8 @@ iso8601_ext_datetime_cb(VALUE m, VALUE hash)
2265
2286
  s[i] = rb_reg_nth_match(i, m);
2266
2287
  }
2267
2288
 
2268
- if (!NIL_P(s[3])) {
2269
- set_hash("mday", str2num(s[3]));
2289
+ if (!NIL_P(s[1])) {
2290
+ if (!NIL_P(s[3])) set_hash("mday", str2num(s[3]));
2270
2291
  if (strcmp(RSTRING_PTR(s[1]), "-") != 0) {
2271
2292
  y = str2num(s[1]);
2272
2293
  if (RSTRING_LEN(s[1]) < 4)
@@ -2323,7 +2344,7 @@ static int
2323
2344
  iso8601_ext_datetime(VALUE str, VALUE hash)
2324
2345
  {
2325
2346
  static const char pat_source[] =
2326
- "\\A\\s*(?:([-+]?\\d{2,}|-)-(\\d{2})?-(\\d{2})|"
2347
+ "\\A\\s*(?:([-+]?\\d{2,}|-)-(\\d{2})?(?:-(\\d{2}))?|"
2327
2348
  "([-+]?\\d{2,})?-(\\d{3})|"
2328
2349
  "(\\d{4}|\\d{2})?-w(\\d{2})-(\\d)|"
2329
2350
  "-w-(\\d))"
@@ -2954,7 +2975,7 @@ jisx0301_cb(VALUE m, VALUE hash)
2954
2975
  s[i] = rb_reg_nth_match(i, m);
2955
2976
  }
2956
2977
 
2957
- ep = gengo(NIL_P(s[1]) ? 'h' : *RSTRING_PTR(s[1]));
2978
+ ep = gengo(NIL_P(s[1]) ? JISX0301_DEFAULT_ERA : *RSTRING_PTR(s[1]));
2958
2979
  set_hash("year", f_add(str2num(s[2]), INT2FIX(ep)));
2959
2980
  set_hash("mon", str2num(s[3]));
2960
2981
  set_hash("mday", str2num(s[4]));
@@ -2979,7 +3000,7 @@ static int
2979
3000
  jisx0301(VALUE str, VALUE hash)
2980
3001
  {
2981
3002
  static const char pat_source[] =
2982
- "\\A\\s*([mtsh])?(\\d{2})\\.(\\d{2})\\.(\\d{2})"
3003
+ "\\A\\s*([" JISX0301_ERA_INITIALS "])?(\\d{2})\\.(\\d{2})\\.(\\d{2})"
2983
3004
  "(?:t"
2984
3005
  "(?:(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d*))?)?"
2985
3006
  "(z|[-+]\\d{2}(?::?\\d{2})?)?)?)?\\s*\\z";
@@ -669,7 +669,7 @@ date__strptime(const char *str, size_t slen,
669
669
  if (fail_p())
670
670
  return Qnil;
671
671
 
672
- cent = ref_hash("_cent");
672
+ cent = del_hash("_cent");
673
673
  if (!NIL_P(cent)) {
674
674
  VALUE year;
675
675
 
@@ -679,10 +679,9 @@ date__strptime(const char *str, size_t slen,
679
679
  year = ref_hash("year");
680
680
  if (!NIL_P(year))
681
681
  set_hash("year", f_add(year, f_mul(cent, INT2FIX(100))));
682
- del_hash("_cent");
683
682
  }
684
683
 
685
- merid = ref_hash("_merid");
684
+ merid = del_hash("_merid");
686
685
  if (!NIL_P(merid)) {
687
686
  VALUE hour;
688
687
 
@@ -691,7 +690,6 @@ date__strptime(const char *str, size_t slen,
691
690
  hour = f_mod(hour, INT2FIX(12));
692
691
  set_hash("hour", f_add(hour, merid));
693
692
  }
694
- del_hash("_merid");
695
693
  }
696
694
 
697
695
  return hash;
data/ext/date/prereq.mk CHANGED
@@ -1,8 +1,12 @@
1
1
  .SUFFIXES: .list
2
2
 
3
3
  .list.h:
4
- gperf -E -C -c -P -p -j1 -i 1 -g -o -t -N $(*F) $< \
4
+ gperf --ignore-case -C -c -P -p -j1 -i 1 -g -o -t -N $(*F) $< \
5
5
  | sed -f $(top_srcdir)/tool/gperf.sed \
6
6
  > $(@F)
7
7
 
8
8
  zonetab.h: zonetab.list
9
+
10
+ .PHONY: update-zonetab
11
+ update-zonetab:
12
+ $(RUBY) -C $(srcdir) update-abbr.rb