date 3.2.2 → 3.3.0

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.
@@ -253,6 +253,8 @@ s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc)
253
253
  #define ABBR_DAYS "sun|mon|tue|wed|thu|fri|sat"
254
254
  #define ABBR_MONTHS "jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec"
255
255
 
256
+ #define NUMBER "(?<!\\d)\\d"
257
+
256
258
  #ifdef TIGHT_PARSER
257
259
  #define VALID_DAYS "(?:" DAYS ")" "|(?:tues|wednes|thurs|thur|" ABBR_DAYS ")\\.?"
258
260
  #define VALID_MONTHS "(?:" MONTHS ")" "|(?:sept|" ABBR_MONTHS ")\\.?"
@@ -411,7 +413,6 @@ VALUE
411
413
  date_zone_to_diff(VALUE str)
412
414
  {
413
415
  VALUE offset = Qnil;
414
- VALUE vbuf = 0;
415
416
  long l = RSTRING_LEN(str);
416
417
  const char *s = RSTRING_PTR(str);
417
418
 
@@ -437,16 +438,26 @@ date_zone_to_diff(VALUE str)
437
438
  l -= w;
438
439
  dst = 1;
439
440
  }
441
+
440
442
  {
443
+ const char *zn = s;
441
444
  long sl = shrunk_size(s, l);
445
+ char shrunk_buff[MAX_WORD_LENGTH]; /* no terminator to be added */
446
+ const struct zone *z = 0;
447
+
448
+ if (sl <= 0) {
449
+ sl = l;
450
+ }
451
+ else if (sl <= MAX_WORD_LENGTH) {
452
+ char *d = shrunk_buff;
453
+ sl = shrink_space(d, s, l);
454
+ zn = d;
455
+ }
456
+
442
457
  if (sl > 0 && sl <= MAX_WORD_LENGTH) {
443
- char *d = ALLOCV_N(char, vbuf, sl);
444
- l = shrink_space(d, s, l);
445
- s = d;
458
+ z = zonetab(zn, (unsigned int)sl);
446
459
  }
447
- }
448
- if (l > 0 && l <= MAX_WORD_LENGTH) {
449
- const struct zone *z = zonetab(s, (unsigned int)l);
460
+
450
461
  if (z) {
451
462
  int d = z->offset;
452
463
  if (dst)
@@ -455,6 +466,7 @@ date_zone_to_diff(VALUE str)
455
466
  goto ok;
456
467
  }
457
468
  }
469
+
458
470
  {
459
471
  char *p;
460
472
  int sign = 0;
@@ -471,27 +483,53 @@ date_zone_to_diff(VALUE str)
471
483
  s++;
472
484
  l--;
473
485
 
486
+ #define out_of_range(v, min, max) ((v) < (min) || (max) < (v))
474
487
  hour = STRTOUL(s, &p, 10);
475
488
  if (*p == ':') {
489
+ if (out_of_range(hour, 0, 23)) return Qnil;
476
490
  s = ++p;
477
491
  min = STRTOUL(s, &p, 10);
492
+ if (out_of_range(min, 0, 59)) return Qnil;
478
493
  if (*p == ':') {
479
494
  s = ++p;
480
495
  sec = STRTOUL(s, &p, 10);
496
+ if (out_of_range(sec, 0, 59)) return Qnil;
481
497
  }
482
- goto num;
483
498
  }
484
- if (*p == ',' || *p == '.') {
485
- char *e = 0;
486
- p++;
487
- min = STRTOUL(p, &e, 10) * 3600;
499
+ else if (*p == ',' || *p == '.') {
500
+ /* fractional hour */
501
+ size_t n;
502
+ int ov;
503
+ /* no over precision for offset; 10**-7 hour = 0.36
504
+ * milliseconds should be enough. */
505
+ const size_t max_digits = 7; /* 36 * 10**7 < 32-bit FIXNUM_MAX */
506
+
507
+ if (out_of_range(hour, 0, 23)) return Qnil;
508
+
509
+ n = (s + l) - ++p;
510
+ if (n > max_digits) n = max_digits;
511
+ sec = ruby_scan_digits(p, n, 10, &n, &ov);
512
+ if ((p += n) < s + l && *p >= ('5' + !(sec & 1)) && *p <= '9') {
513
+ /* round half to even */
514
+ sec++;
515
+ }
516
+ sec *= 36;
488
517
  if (sign) {
489
518
  hour = -hour;
490
- min = -min;
519
+ sec = -sec;
520
+ }
521
+ if (n <= 2) {
522
+ /* HH.nn or HH.n */
523
+ if (n == 1) sec *= 10;
524
+ offset = INT2FIX(sec + hour * 3600);
525
+ }
526
+ else {
527
+ VALUE denom = rb_int_positive_pow(10, (int)(n - 2));
528
+ offset = f_add(rb_rational_new(INT2FIX(sec), denom), INT2FIX(hour * 3600));
529
+ if (rb_rational_den(offset) == INT2FIX(1)) {
530
+ offset = rb_rational_num(offset);
531
+ }
491
532
  }
492
- offset = rb_rational_new(INT2FIX(min),
493
- rb_int_positive_pow(10, (int)(e - p)));
494
- offset = f_add(INT2FIX(hour * 3600), offset);
495
533
  goto ok;
496
534
  }
497
535
  else if (l > 2) {
@@ -504,18 +542,16 @@ date_zone_to_diff(VALUE str)
504
542
  min = ruby_scan_digits(&s[2 - l % 2], 2, 10, &n, &ov);
505
543
  if (l >= 5)
506
544
  sec = ruby_scan_digits(&s[4 - l % 2], 2, 10, &n, &ov);
507
- goto num;
508
545
  }
509
- num:
510
546
  sec += min * 60 + hour * 3600;
511
547
  if (sign) sec = -sec;
512
548
  offset = INT2FIX(sec);
549
+ #undef out_of_range
513
550
  }
514
551
  }
515
552
  }
516
553
  RB_GC_GUARD(str);
517
554
  ok:
518
- ALLOCV_END(vbuf);
519
555
  return offset;
520
556
  }
521
557
 
@@ -652,24 +688,27 @@ parse_time(VALUE str, VALUE hash)
652
688
  {
653
689
  static const char pat_source[] =
654
690
  "("
691
+ "" NUMBER "+\\s*"
655
692
  "(?:"
656
- "\\d+\\s*:\\s*\\d+"
657
693
  "(?:"
694
+ ":\\s*\\d+"
695
+ "(?:"
658
696
  #ifndef TIGHT_PARSER
659
- "\\s*:\\s*\\d+(?:[,.]\\d*)?"
697
+ "\\s*:\\s*\\d+(?:[,.]\\d*)?"
660
698
  #else
661
- "\\s*:\\s*\\d+(?:[,.]\\d+)?"
699
+ "\\s*:\\s*\\d+(?:[,.]\\d+)?"
662
700
  #endif
701
+ ")?"
702
+ "|"
703
+ "h(?:\\s*\\d+m?(?:\\s*\\d+s?)?)?"
704
+ ")"
705
+ "(?:"
706
+ "\\s*"
707
+ "[ap](?:m\\b|\\.m\\.)"
663
708
  ")?"
664
709
  "|"
665
- "\\d+\\s*h(?:\\s*\\d+m?(?:\\s*\\d+s?)?)?"
666
- ")"
667
- "(?:"
668
- "\\s*"
669
710
  "[ap](?:m\\b|\\.m\\.)"
670
- ")?"
671
- "|"
672
- "\\d+\\s*[ap](?:m\\b|\\.m\\.)"
711
+ ")"
673
712
  ")"
674
713
  "(?:"
675
714
  "\\s*"
@@ -691,6 +730,9 @@ parse_time(VALUE str, VALUE hash)
691
730
  #endif
692
731
  }
693
732
 
733
+ #define BEGIN_ERA "\\b"
734
+ #define END_ERA "(?!(?<!\\.)[a-z])"
735
+
694
736
  #ifdef TIGHT_PARSER
695
737
  static int
696
738
  parse_era1_cb(VALUE m, VALUE hash)
@@ -702,7 +744,7 @@ static int
702
744
  parse_era1(VALUE str, VALUE hash)
703
745
  {
704
746
  static const char pat_source[] =
705
- "(a(?:d|\\.d\\.))";
747
+ BEGIN_ERA "(a(?:d\\b|\\.d\\.))" END_ERA;
706
748
  static VALUE pat = Qnil;
707
749
 
708
750
  REGCOMP_I(pat);
@@ -724,8 +766,9 @@ parse_era2_cb(VALUE m, VALUE hash)
724
766
  static int
725
767
  parse_era2(VALUE str, VALUE hash)
726
768
  {
727
- static const char pat_source[] =
728
- "(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|b(?:c|\\.c\\.))";
769
+ static const char pat_source[] = BEGIN_ERA
770
+ "(c(?:e\\b|\\.e\\.)|b(?:ce\\b|\\.c\\.e\\.)|b(?:c\\b|\\.c\\.))"
771
+ END_ERA;
729
772
  static VALUE pat = Qnil;
730
773
 
731
774
  REGCOMP_I(pat);
@@ -829,7 +872,7 @@ parse_eu(VALUE str, VALUE hash)
829
872
  FPW_COM FPT_COM
830
873
  #endif
831
874
  #ifndef TIGHT_PARSER
832
- "('?\\d+)[^-\\d\\s]*"
875
+ "('?" NUMBER "+)[^-\\d\\s]*"
833
876
  #else
834
877
  "(\\d+)(?:(?:st|nd|rd|th)\\b)?"
835
878
  #endif
@@ -842,7 +885,11 @@ parse_eu(VALUE str, VALUE hash)
842
885
  "(?:"
843
886
  "\\s*"
844
887
  #ifndef TIGHT_PARSER
845
- "(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))?"
888
+ "(?:"
889
+ BEGIN_ERA
890
+ "(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))"
891
+ END_ERA
892
+ ")?"
846
893
  "\\s*"
847
894
  "('?-?\\d+(?:(?:st|nd|rd|th)\\b)?)"
848
895
  #else
@@ -919,8 +966,8 @@ parse_us(VALUE str, VALUE hash)
919
966
  COM_FPT
920
967
  #endif
921
968
  "(?:"
922
- "\\s*,?"
923
- "\\s*"
969
+ "\\s*+,?"
970
+ "\\s*+"
924
971
  #ifndef TIGHT_PARSER
925
972
  "(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))?"
926
973
  "\\s*"
@@ -967,7 +1014,7 @@ parse_iso(VALUE str, VALUE hash)
967
1014
  {
968
1015
  static const char pat_source[] =
969
1016
  #ifndef TIGHT_PARSER
970
- "('?[-+]?\\d+)-(\\d+)-('?-?\\d+)"
1017
+ "('?[-+]?" NUMBER "+)-(\\d+)-('?-?\\d+)"
971
1018
  #else
972
1019
  BOS
973
1020
  FPW_COM FPT_COM
@@ -1321,7 +1368,7 @@ parse_vms11(VALUE str, VALUE hash)
1321
1368
  {
1322
1369
  static const char pat_source[] =
1323
1370
  #ifndef TIGHT_PARSER
1324
- "('?-?\\d+)-(" ABBR_MONTHS ")[^-/.]*"
1371
+ "('?-?" NUMBER "+)-(" ABBR_MONTHS ")[^-/.]*"
1325
1372
  "-('?-?\\d+)"
1326
1373
  #else
1327
1374
  BOS
@@ -1416,7 +1463,7 @@ parse_sla(VALUE str, VALUE hash)
1416
1463
  {
1417
1464
  static const char pat_source[] =
1418
1465
  #ifndef TIGHT_PARSER
1419
- "('?-?\\d+)/\\s*('?\\d+)(?:\\D\\s*('?-?\\d+))?"
1466
+ "('?-?" NUMBER "+)/\\s*('?\\d+)(?:\\D\\s*('?-?\\d+))?"
1420
1467
  #else
1421
1468
  BOS
1422
1469
  FPW_COM FPT_COM
@@ -1524,7 +1571,7 @@ parse_dot(VALUE str, VALUE hash)
1524
1571
  {
1525
1572
  static const char pat_source[] =
1526
1573
  #ifndef TIGHT_PARSER
1527
- "('?-?\\d+)\\.\\s*('?\\d+)\\.\\s*('?-?\\d+)"
1574
+ "('?-?" NUMBER "+)\\.\\s*('?\\d+)\\.\\s*('?-?\\d+)"
1528
1575
  #else
1529
1576
  BOS
1530
1577
  FPW_COM FPT_COM
@@ -1684,7 +1731,7 @@ parse_mday(VALUE str, VALUE hash)
1684
1731
  {
1685
1732
  static const char pat_source[] =
1686
1733
  #ifndef TIGHT_PARSER
1687
- "(\\d+)(st|nd|rd|th)\\b"
1734
+ "(" NUMBER "+)(st|nd|rd|th)\\b"
1688
1735
  #else
1689
1736
  BOS
1690
1737
  FPW_COM FPT_COM
@@ -1922,7 +1969,7 @@ parse_ddd(VALUE str, VALUE hash)
1922
1969
  #ifdef TIGHT_PARSER
1923
1970
  BOS
1924
1971
  #endif
1925
- "([-+]?)(\\d{2,14})"
1972
+ "([-+]?)(" NUMBER "{2,14})"
1926
1973
  "(?:"
1927
1974
  "\\s*"
1928
1975
  "t?"
data/ext/date/extconf.rb CHANGED
@@ -3,6 +3,7 @@ require 'mkmf'
3
3
 
4
4
  config_string("strict_warnflags") {|w| $warnflags += " #{w}"}
5
5
 
6
+ have_func("rb_category_warn")
6
7
  with_werror("", {:werror => true}) do |opt, |
7
8
  have_var("timezone", "time.h", opt)
8
9
  have_var("altzone", "time.h", opt)
data/ext/date/zonetab.h CHANGED
@@ -36,7 +36,7 @@ struct zone {
36
36
  int name;
37
37
  int offset;
38
38
  };
39
- static const struct zone *zonetab();
39
+ static const struct zone *zonetab(register const char *str, register size_t len);
40
40
  #line 9 "zonetab.list"
41
41
  struct zone;
42
42
 
@@ -49,7 +49,7 @@ struct zone;
49
49
 
50
50
  #ifndef GPERF_DOWNCASE
51
51
  #define GPERF_DOWNCASE 1
52
- static unsigned char gperf_downcase[256] =
52
+ static const unsigned char gperf_downcase[256] =
53
53
  {
54
54
  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
55
55
  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
@@ -3,7 +3,7 @@ struct zone {
3
3
  int name;
4
4
  int offset;
5
5
  };
6
- static const struct zone *zonetab();
6
+ static const struct zone *zonetab(register const char *str, register size_t len);
7
7
  %}
8
8
 
9
9
  struct zone;
data/lib/date.rb CHANGED
@@ -4,8 +4,12 @@
4
4
  require 'date_core'
5
5
 
6
6
  class Date
7
- VERSION = '3.2.2' # :nodoc:
7
+ VERSION = "3.3.0" # :nodoc:
8
8
 
9
+ # call-seq:
10
+ # infinite? -> false
11
+ #
12
+ # Returns +false+
9
13
  def infinite?
10
14
  false
11
15
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: date
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.2
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tadayoshi Funaba
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-18 00:00:00.000000000 Z
11
+ date: 2022-12-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A subclass of Object includes Comparable module for handling dates.
14
14
  email:
@@ -18,6 +18,7 @@ extensions:
18
18
  - ext/date/extconf.rb
19
19
  extra_rdoc_files: []
20
20
  files:
21
+ - README.md
21
22
  - ext/date/date_core.c
22
23
  - ext/date/date_parse.c
23
24
  - ext/date/date_strftime.c
@@ -48,7 +49,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
48
49
  - !ruby/object:Gem::Version
49
50
  version: '0'
50
51
  requirements: []
51
- rubygems_version: 3.3.0.dev
52
+ rubygems_version: 3.4.0.dev
52
53
  signing_key:
53
54
  specification_version: 4
54
55
  summary: A subclass of Object includes Comparable module for handling dates.