date 3.2.2 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.