date 3.5.0 → 3.6.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.
- checksums.yaml +4 -4
- data/ext/date/date_core.c +338 -123
- data/ext/date/date_parse.c +14 -4
- data/ext/date/date_strptime.c +13 -13
- data/ext/date/extconf.rb +6 -0
- data/lib/date.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e3e5e30902faa5fe0f946df02df28a7d52b64e6a78d39e9b16ec9f0d88377646
|
|
4
|
+
data.tar.gz: 5a0c7a8ae91bbfd3a0fe6a152465217070ccbd7f5b5892c9657a865f47d6d492
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bb10bbaa46008e4af4c8ba566aafbf71c45e3fcecd80b783b2ae06a0334df66ba49d4435ae969fb24b79e6ab2f53e16c80e1ae6f7b54f46314f87f7747702e89
|
|
7
|
+
data.tar.gz: b130c6501519228151df6df25cedae7457be32ed3c6f118f331ade479f14ec9bd7f7148ef48575e199cf987c2398d1688ddb3e9f45d6b08a8d919294998bda11
|
data/ext/date/date_core.c
CHANGED
|
@@ -27,7 +27,7 @@ static VALUE eDateError;
|
|
|
27
27
|
static VALUE half_days_in_day, day_in_nanoseconds;
|
|
28
28
|
static double positive_inf, negative_inf;
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
/* used by deconstruct_keys */
|
|
31
31
|
static VALUE sym_year, sym_month, sym_day, sym_yday, sym_wday;
|
|
32
32
|
static VALUE sym_hour, sym_min, sym_sec, sym_sec_fraction, sym_zone;
|
|
33
33
|
|
|
@@ -452,11 +452,43 @@ do {\
|
|
|
452
452
|
static int c_valid_civil_p(int, int, int, double,
|
|
453
453
|
int *, int *, int *, int *);
|
|
454
454
|
|
|
455
|
+
/* Check if using pure Gregorian calendar (sg == -Infinity) */
|
|
456
|
+
#define c_gregorian_only_p(sg) (isinf(sg) && (sg) < 0)
|
|
457
|
+
|
|
458
|
+
/*
|
|
459
|
+
* Fast path macros for pure Gregorian calendar.
|
|
460
|
+
* Sets *rjd to the JD value, *ns to 1 (new style), and returns.
|
|
461
|
+
*/
|
|
462
|
+
#define GREGORIAN_JD_FAST_PATH_RET(sg, jd_expr, rjd, ns) \
|
|
463
|
+
if (c_gregorian_only_p(sg)) { \
|
|
464
|
+
*(rjd) = (jd_expr); \
|
|
465
|
+
*(ns) = 1; \
|
|
466
|
+
return 1; \
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
#define GREGORIAN_JD_FAST_PATH(sg, jd_expr, rjd, ns) \
|
|
470
|
+
if (c_gregorian_only_p(sg)) { \
|
|
471
|
+
*(rjd) = (jd_expr); \
|
|
472
|
+
*(ns) = 1; \
|
|
473
|
+
return; \
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/* Forward declarations for Neri-Schneider optimized functions */
|
|
477
|
+
static int c_gregorian_civil_to_jd(int y, int m, int d);
|
|
478
|
+
static void c_gregorian_jd_to_civil(int jd, int *ry, int *rm, int *rd);
|
|
479
|
+
static int c_gregorian_fdoy(int y);
|
|
480
|
+
static int c_gregorian_ldoy(int y);
|
|
481
|
+
static int c_gregorian_ldom_jd(int y, int m);
|
|
482
|
+
static int ns_jd_in_range(int jd);
|
|
483
|
+
|
|
455
484
|
static int
|
|
456
485
|
c_find_fdoy(int y, double sg, int *rjd, int *ns)
|
|
457
486
|
{
|
|
458
487
|
int d, rm, rd;
|
|
459
488
|
|
|
489
|
+
GREGORIAN_JD_FAST_PATH_RET(sg, c_gregorian_fdoy(y), rjd, ns);
|
|
490
|
+
|
|
491
|
+
/* Keep existing loop for Julian/reform period */
|
|
460
492
|
for (d = 1; d < 31; d++)
|
|
461
493
|
if (c_valid_civil_p(y, 1, d, sg, &rm, &rd, rjd, ns))
|
|
462
494
|
return 1;
|
|
@@ -468,6 +500,9 @@ c_find_ldoy(int y, double sg, int *rjd, int *ns)
|
|
|
468
500
|
{
|
|
469
501
|
int i, rm, rd;
|
|
470
502
|
|
|
503
|
+
GREGORIAN_JD_FAST_PATH_RET(sg, c_gregorian_ldoy(y), rjd, ns);
|
|
504
|
+
|
|
505
|
+
/* Keep existing loop for Julian/reform period */
|
|
471
506
|
for (i = 0; i < 30; i++)
|
|
472
507
|
if (c_valid_civil_p(y, 12, 31 - i, sg, &rm, &rd, rjd, ns))
|
|
473
508
|
return 1;
|
|
@@ -493,6 +528,9 @@ c_find_ldom(int y, int m, double sg, int *rjd, int *ns)
|
|
|
493
528
|
{
|
|
494
529
|
int i, rm, rd;
|
|
495
530
|
|
|
531
|
+
GREGORIAN_JD_FAST_PATH_RET(sg, c_gregorian_ldom_jd(y, m), rjd, ns);
|
|
532
|
+
|
|
533
|
+
/* Keep existing loop for Julian/reform period */
|
|
496
534
|
for (i = 0; i < 30; i++)
|
|
497
535
|
if (c_valid_civil_p(y, m, 31 - i, sg, &rm, &rd, rjd, ns))
|
|
498
536
|
return 1;
|
|
@@ -502,55 +540,69 @@ c_find_ldom(int y, int m, double sg, int *rjd, int *ns)
|
|
|
502
540
|
static void
|
|
503
541
|
c_civil_to_jd(int y, int m, int d, double sg, int *rjd, int *ns)
|
|
504
542
|
{
|
|
505
|
-
|
|
543
|
+
int jd;
|
|
544
|
+
|
|
545
|
+
GREGORIAN_JD_FAST_PATH(sg, c_gregorian_civil_to_jd(y, m, d), rjd, ns);
|
|
546
|
+
|
|
547
|
+
/* Calculate Gregorian JD using optimized algorithm */
|
|
548
|
+
jd = c_gregorian_civil_to_jd(y, m, d);
|
|
506
549
|
|
|
507
|
-
if (m <= 2) {
|
|
508
|
-
y -= 1;
|
|
509
|
-
m += 12;
|
|
510
|
-
}
|
|
511
|
-
a = floor(y / 100.0);
|
|
512
|
-
b = 2 - a + floor(a / 4.0);
|
|
513
|
-
jd = floor(365.25 * (y + 4716)) +
|
|
514
|
-
floor(30.6001 * (m + 1)) +
|
|
515
|
-
d + b - 1524;
|
|
516
550
|
if (jd < sg) {
|
|
517
|
-
|
|
551
|
+
/* Before Gregorian switchover - use Julian calendar */
|
|
552
|
+
int y2 = y, m2 = m;
|
|
553
|
+
if (m2 <= 2) {
|
|
554
|
+
y2 -= 1;
|
|
555
|
+
m2 += 12;
|
|
556
|
+
}
|
|
557
|
+
jd = (int)(floor(365.25 * (y2 + 4716)) +
|
|
558
|
+
floor(30.6001 * (m2 + 1)) +
|
|
559
|
+
d - 1524);
|
|
518
560
|
*ns = 0;
|
|
519
561
|
}
|
|
520
|
-
else
|
|
562
|
+
else {
|
|
521
563
|
*ns = 1;
|
|
564
|
+
}
|
|
522
565
|
|
|
523
|
-
*rjd =
|
|
566
|
+
*rjd = jd;
|
|
524
567
|
}
|
|
525
568
|
|
|
526
569
|
static void
|
|
527
570
|
c_jd_to_civil(int jd, double sg, int *ry, int *rm, int *rdom)
|
|
528
571
|
{
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
else {
|
|
534
|
-
x = floor((jd - 1867216.25) / 36524.25);
|
|
535
|
-
a = jd + 1 + x - floor(x / 4.0);
|
|
536
|
-
}
|
|
537
|
-
b = a + 1524;
|
|
538
|
-
c = floor((b - 122.1) / 365.25);
|
|
539
|
-
d = floor(365.25 * c);
|
|
540
|
-
e = floor((b - d) / 30.6001);
|
|
541
|
-
dom = b - d - floor(30.6001 * e);
|
|
542
|
-
if (e <= 13) {
|
|
543
|
-
m = e - 1;
|
|
544
|
-
y = c - 4716;
|
|
545
|
-
}
|
|
546
|
-
else {
|
|
547
|
-
m = e - 13;
|
|
548
|
-
y = c - 4715;
|
|
572
|
+
/* Fast path: pure Gregorian or date after switchover, within safe range */
|
|
573
|
+
if ((c_gregorian_only_p(sg) || jd >= sg) && ns_jd_in_range(jd)) {
|
|
574
|
+
c_gregorian_jd_to_civil(jd, ry, rm, rdom);
|
|
575
|
+
return;
|
|
549
576
|
}
|
|
550
577
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
578
|
+
/* Original algorithm for Julian calendar or extreme dates */
|
|
579
|
+
{
|
|
580
|
+
double x, a, b, c, d, e, y, m, dom;
|
|
581
|
+
|
|
582
|
+
if (jd < sg)
|
|
583
|
+
a = jd;
|
|
584
|
+
else {
|
|
585
|
+
x = floor((jd - 1867216.25) / 36524.25);
|
|
586
|
+
a = jd + 1 + x - floor(x / 4.0);
|
|
587
|
+
}
|
|
588
|
+
b = a + 1524;
|
|
589
|
+
c = floor((b - 122.1) / 365.25);
|
|
590
|
+
d = floor(365.25 * c);
|
|
591
|
+
e = floor((b - d) / 30.6001);
|
|
592
|
+
dom = b - d - floor(30.6001 * e);
|
|
593
|
+
if (e <= 13) {
|
|
594
|
+
m = e - 1;
|
|
595
|
+
y = c - 4716;
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
m = e - 13;
|
|
599
|
+
y = c - 4715;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
*ry = (int)y;
|
|
603
|
+
*rm = (int)m;
|
|
604
|
+
*rdom = (int)dom;
|
|
605
|
+
}
|
|
554
606
|
}
|
|
555
607
|
|
|
556
608
|
static void
|
|
@@ -725,6 +777,147 @@ c_gregorian_last_day_of_month(int y, int m)
|
|
|
725
777
|
return monthtab[c_gregorian_leap_p(y) ? 1 : 0][m];
|
|
726
778
|
}
|
|
727
779
|
|
|
780
|
+
/*
|
|
781
|
+
* Neri-Schneider algorithm for optimized Gregorian date conversion.
|
|
782
|
+
* Reference: Neri & Schneider, "Euclidean Affine Functions and Applications
|
|
783
|
+
* to Calendar Algorithms", Software: Practice and Experience, 2023.
|
|
784
|
+
* https://arxiv.org/abs/2102.06959
|
|
785
|
+
*
|
|
786
|
+
* This algorithm provides ~2-3x speedup over traditional floating-point
|
|
787
|
+
* implementations by using pure integer arithmetic with multiplication
|
|
788
|
+
* and bit-shifts instead of expensive division operations.
|
|
789
|
+
*/
|
|
790
|
+
|
|
791
|
+
/* JDN of March 1, Year 0 in proleptic Gregorian calendar */
|
|
792
|
+
#define NS_EPOCH 1721120
|
|
793
|
+
|
|
794
|
+
/* Days in a 4-year cycle (3 normal years + 1 leap year) */
|
|
795
|
+
#define NS_DAYS_IN_4_YEARS 1461
|
|
796
|
+
|
|
797
|
+
/* Days in a 400-year Gregorian cycle (97 leap years in 400 years) */
|
|
798
|
+
#define NS_DAYS_IN_400_YEARS 146097
|
|
799
|
+
|
|
800
|
+
/* Years per century */
|
|
801
|
+
#define NS_YEARS_PER_CENTURY 100
|
|
802
|
+
|
|
803
|
+
/*
|
|
804
|
+
* Multiplier for extracting year within century using fixed-point arithmetic.
|
|
805
|
+
* This is ceil(2^32 / NS_DAYS_IN_4_YEARS) for the Euclidean affine function.
|
|
806
|
+
*/
|
|
807
|
+
#define NS_YEAR_MULTIPLIER 2939745
|
|
808
|
+
|
|
809
|
+
/*
|
|
810
|
+
* Coefficients for month calculation from day-of-year.
|
|
811
|
+
* Maps day-of-year to month using: month = (NS_MONTH_COEFF * doy + NS_MONTH_OFFSET) >> 16
|
|
812
|
+
*/
|
|
813
|
+
#define NS_MONTH_COEFF 2141
|
|
814
|
+
#define NS_MONTH_OFFSET 197913
|
|
815
|
+
|
|
816
|
+
/*
|
|
817
|
+
* Coefficients for civil date to JDN month contribution.
|
|
818
|
+
* Maps month to accumulated days: days = (NS_CIVIL_MONTH_COEFF * m - NS_CIVIL_MONTH_OFFSET) / 32
|
|
819
|
+
*/
|
|
820
|
+
#define NS_CIVIL_MONTH_COEFF 979
|
|
821
|
+
#define NS_CIVIL_MONTH_OFFSET 2919
|
|
822
|
+
#define NS_CIVIL_MONTH_DIVISOR 32
|
|
823
|
+
|
|
824
|
+
/* Days from March 1 to December 31 (for Jan/Feb year adjustment) */
|
|
825
|
+
#define NS_DAYS_BEFORE_NEW_YEAR 306
|
|
826
|
+
|
|
827
|
+
/*
|
|
828
|
+
* Safe bounds for Neri-Schneider algorithm to avoid integer overflow.
|
|
829
|
+
* These correspond to approximately years -1,000,000 to +1,000,000.
|
|
830
|
+
*/
|
|
831
|
+
#define NS_JD_MIN -364000000
|
|
832
|
+
#define NS_JD_MAX 538000000
|
|
833
|
+
|
|
834
|
+
inline static int
|
|
835
|
+
ns_jd_in_range(int jd)
|
|
836
|
+
{
|
|
837
|
+
return jd >= NS_JD_MIN && jd <= NS_JD_MAX;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/* Optimized: Gregorian date -> Julian Day Number */
|
|
841
|
+
static int
|
|
842
|
+
c_gregorian_civil_to_jd(int y, int m, int d)
|
|
843
|
+
{
|
|
844
|
+
/* Shift epoch to March 1 of year 0 (Jan/Feb belong to previous year) */
|
|
845
|
+
int j = (m < 3) ? 1 : 0;
|
|
846
|
+
int y0 = y - j;
|
|
847
|
+
int m0 = j ? m + 12 : m;
|
|
848
|
+
int d0 = d - 1;
|
|
849
|
+
|
|
850
|
+
/* Calculate year contribution with leap year correction */
|
|
851
|
+
int q1 = DIV(y0, NS_YEARS_PER_CENTURY);
|
|
852
|
+
int yc = DIV(NS_DAYS_IN_4_YEARS * y0, 4) - q1 + DIV(q1, 4);
|
|
853
|
+
|
|
854
|
+
/* Calculate month contribution using integer arithmetic */
|
|
855
|
+
int mc = (NS_CIVIL_MONTH_COEFF * m0 - NS_CIVIL_MONTH_OFFSET) / NS_CIVIL_MONTH_DIVISOR;
|
|
856
|
+
|
|
857
|
+
/* Combine and add epoch offset to get JDN */
|
|
858
|
+
return yc + mc + d0 + NS_EPOCH;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/* Optimized: Julian Day Number -> Gregorian date */
|
|
862
|
+
static void
|
|
863
|
+
c_gregorian_jd_to_civil(int jd, int *ry, int *rm, int *rd)
|
|
864
|
+
{
|
|
865
|
+
int r0, n1, q1, r1, n2, q2, r2, n3, q3, r3, y0, j;
|
|
866
|
+
uint64_t u2;
|
|
867
|
+
|
|
868
|
+
/* Convert JDN to rata die (March 1, Year 0 epoch) */
|
|
869
|
+
r0 = jd - NS_EPOCH;
|
|
870
|
+
|
|
871
|
+
/* Extract century and day within 400-year cycle */
|
|
872
|
+
/* Use Euclidean (floor) division for negative values */
|
|
873
|
+
n1 = 4 * r0 + 3;
|
|
874
|
+
q1 = DIV(n1, NS_DAYS_IN_400_YEARS);
|
|
875
|
+
r1 = MOD(n1, NS_DAYS_IN_400_YEARS) / 4;
|
|
876
|
+
|
|
877
|
+
/* Calculate year within century and day of year */
|
|
878
|
+
n2 = 4 * r1 + 3;
|
|
879
|
+
/* Use 64-bit arithmetic to avoid overflow */
|
|
880
|
+
u2 = (uint64_t)NS_YEAR_MULTIPLIER * (uint64_t)n2;
|
|
881
|
+
q2 = (int)(u2 >> 32);
|
|
882
|
+
r2 = (int)((uint32_t)u2 / NS_YEAR_MULTIPLIER / 4);
|
|
883
|
+
|
|
884
|
+
/* Calculate month and day using integer arithmetic */
|
|
885
|
+
n3 = NS_MONTH_COEFF * r2 + NS_MONTH_OFFSET;
|
|
886
|
+
q3 = n3 >> 16;
|
|
887
|
+
r3 = (n3 & 0xFFFF) / NS_MONTH_COEFF;
|
|
888
|
+
|
|
889
|
+
/* Combine century and year */
|
|
890
|
+
y0 = NS_YEARS_PER_CENTURY * q1 + q2;
|
|
891
|
+
|
|
892
|
+
/* Adjust for January/February (shift from fiscal year) */
|
|
893
|
+
j = (r2 >= NS_DAYS_BEFORE_NEW_YEAR) ? 1 : 0;
|
|
894
|
+
|
|
895
|
+
*ry = y0 + j;
|
|
896
|
+
*rm = j ? q3 - 12 : q3;
|
|
897
|
+
*rd = r3 + 1;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
/* O(1) first day of year for Gregorian calendar */
|
|
901
|
+
inline static int
|
|
902
|
+
c_gregorian_fdoy(int y)
|
|
903
|
+
{
|
|
904
|
+
return c_gregorian_civil_to_jd(y, 1, 1);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/* O(1) last day of year for Gregorian calendar */
|
|
908
|
+
inline static int
|
|
909
|
+
c_gregorian_ldoy(int y)
|
|
910
|
+
{
|
|
911
|
+
return c_gregorian_civil_to_jd(y, 12, 31);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/* O(1) last day of month (JDN) for Gregorian calendar */
|
|
915
|
+
inline static int
|
|
916
|
+
c_gregorian_ldom_jd(int y, int m)
|
|
917
|
+
{
|
|
918
|
+
return c_gregorian_civil_to_jd(y, m, c_gregorian_last_day_of_month(y, m));
|
|
919
|
+
}
|
|
920
|
+
|
|
728
921
|
static int
|
|
729
922
|
c_valid_julian_p(int y, int m, int d, int *rm, int *rd)
|
|
730
923
|
{
|
|
@@ -799,12 +992,16 @@ c_valid_commercial_p(int y, int w, int d, double sg,
|
|
|
799
992
|
if (w < 0) {
|
|
800
993
|
int rjd2;
|
|
801
994
|
|
|
995
|
+
if (w < -53) return 0;
|
|
802
996
|
c_commercial_to_jd(y + 1, 1, 1, sg, &rjd2, &ns2);
|
|
803
997
|
c_jd_to_commercial(rjd2 + w * 7, sg, &ry2, &rw2, &rd2);
|
|
804
998
|
if (ry2 != y)
|
|
805
999
|
return 0;
|
|
806
1000
|
w = rw2;
|
|
807
1001
|
}
|
|
1002
|
+
else {
|
|
1003
|
+
if (w < 1 || 53 < w) return 0;
|
|
1004
|
+
}
|
|
808
1005
|
c_commercial_to_jd(y, w, d, sg, rjd, ns);
|
|
809
1006
|
c_jd_to_commercial(*rjd, sg, &ry2, rw, rd);
|
|
810
1007
|
if (y != ry2 || w != *rw || d != *rd)
|
|
@@ -2428,9 +2625,9 @@ offset_to_sec(VALUE vof, int *rof)
|
|
|
2428
2625
|
if (!FIXNUM_P(vn))
|
|
2429
2626
|
return 0;
|
|
2430
2627
|
n = FIX2LONG(vn);
|
|
2431
|
-
if (n < -DAY_IN_SECONDS || n > DAY_IN_SECONDS)
|
|
2432
|
-
return 0;
|
|
2433
2628
|
}
|
|
2629
|
+
if (n < -DAY_IN_SECONDS || n > DAY_IN_SECONDS)
|
|
2630
|
+
return 0;
|
|
2434
2631
|
*rof = (int)n;
|
|
2435
2632
|
return 1;
|
|
2436
2633
|
}
|
|
@@ -2498,7 +2695,7 @@ date_s__valid_jd_p(int argc, VALUE *argv, VALUE klass)
|
|
|
2498
2695
|
*
|
|
2499
2696
|
* Date.valid_jd?(2451944) # => true
|
|
2500
2697
|
*
|
|
2501
|
-
* See argument {start}[rdoc-ref:
|
|
2698
|
+
* See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
2502
2699
|
*
|
|
2503
2700
|
* Related: Date.jd.
|
|
2504
2701
|
*/
|
|
@@ -2592,7 +2789,7 @@ date_s__valid_civil_p(int argc, VALUE *argv, VALUE klass)
|
|
|
2592
2789
|
* Date.valid_date?(2001, 2, 29) # => false
|
|
2593
2790
|
* Date.valid_date?(2001, 2, -1) # => true
|
|
2594
2791
|
*
|
|
2595
|
-
* See argument {start}[rdoc-ref:
|
|
2792
|
+
* See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
2596
2793
|
*
|
|
2597
2794
|
* Related: Date.jd, Date.new.
|
|
2598
2795
|
*/
|
|
@@ -2680,7 +2877,7 @@ date_s__valid_ordinal_p(int argc, VALUE *argv, VALUE klass)
|
|
|
2680
2877
|
* Date.valid_ordinal?(2001, 34) # => true
|
|
2681
2878
|
* Date.valid_ordinal?(2001, 366) # => false
|
|
2682
2879
|
*
|
|
2683
|
-
* See argument {start}[rdoc-ref:
|
|
2880
|
+
* See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
2684
2881
|
*
|
|
2685
2882
|
* Related: Date.jd, Date.ordinal.
|
|
2686
2883
|
*/
|
|
@@ -2770,7 +2967,7 @@ date_s__valid_commercial_p(int argc, VALUE *argv, VALUE klass)
|
|
|
2770
2967
|
*
|
|
2771
2968
|
* See Date.commercial.
|
|
2772
2969
|
*
|
|
2773
|
-
* See argument {start}[rdoc-ref:
|
|
2970
|
+
* See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
2774
2971
|
*
|
|
2775
2972
|
* Related: Date.jd, Date.commercial.
|
|
2776
2973
|
*/
|
|
@@ -3002,34 +3199,66 @@ date_s_gregorian_leap_p(VALUE klass, VALUE y)
|
|
|
3002
3199
|
return f_boolcast(c_gregorian_leap_p(ry));
|
|
3003
3200
|
}
|
|
3004
3201
|
|
|
3202
|
+
#ifndef HAVE_RB_GC_MARK_MOVABLE
|
|
3203
|
+
#define rb_gc_mark_movable rb_gc_mark
|
|
3204
|
+
#else
|
|
3005
3205
|
static void
|
|
3006
|
-
|
|
3206
|
+
d_lite_gc_compact(void *ptr)
|
|
3007
3207
|
{
|
|
3008
3208
|
union DateData *dat = ptr;
|
|
3009
3209
|
if (simple_dat_p(dat))
|
|
3010
|
-
|
|
3210
|
+
dat->s.nth = rb_gc_location(dat->s.nth);
|
|
3011
3211
|
else {
|
|
3012
|
-
|
|
3013
|
-
|
|
3212
|
+
dat->c.nth = rb_gc_location(dat->c.nth);
|
|
3213
|
+
dat->c.sf = rb_gc_location(dat->c.sf);
|
|
3014
3214
|
}
|
|
3015
3215
|
}
|
|
3216
|
+
#endif
|
|
3016
3217
|
|
|
3017
|
-
static
|
|
3018
|
-
|
|
3218
|
+
static void
|
|
3219
|
+
d_lite_gc_mark(void *ptr)
|
|
3019
3220
|
{
|
|
3020
|
-
|
|
3021
|
-
|
|
3221
|
+
union DateData *dat = ptr;
|
|
3222
|
+
if (simple_dat_p(dat))
|
|
3223
|
+
rb_gc_mark_movable(dat->s.nth);
|
|
3224
|
+
else {
|
|
3225
|
+
rb_gc_mark_movable(dat->c.nth);
|
|
3226
|
+
rb_gc_mark_movable(dat->c.sf);
|
|
3227
|
+
}
|
|
3022
3228
|
}
|
|
3023
3229
|
|
|
3024
3230
|
#ifndef HAVE_RB_EXT_RACTOR_SAFE
|
|
3025
3231
|
# define RUBY_TYPED_FROZEN_SHAREABLE 0
|
|
3026
3232
|
#endif
|
|
3027
3233
|
|
|
3234
|
+
#if defined(RUBY_TYPED_EMBEDDABLE) || defined(HAVE_CONST_RUBY_TYPED_EMBEDDABLE)
|
|
3235
|
+
# define HAVE_RUBY_TYPED_EMBEDDABLE 1
|
|
3236
|
+
#else
|
|
3237
|
+
# define RUBY_TYPED_EMBEDDABLE 0
|
|
3238
|
+
#endif
|
|
3239
|
+
|
|
3240
|
+
static size_t
|
|
3241
|
+
d_lite_memsize(const void *ptr)
|
|
3242
|
+
{
|
|
3243
|
+
#ifdef HAVE_RUBY_TYPED_EMBEDDABLE
|
|
3244
|
+
return 0;
|
|
3245
|
+
#else
|
|
3246
|
+
return sizeof(union DateData);
|
|
3247
|
+
#endif
|
|
3248
|
+
}
|
|
3249
|
+
|
|
3028
3250
|
static const rb_data_type_t d_lite_type = {
|
|
3029
3251
|
"Date",
|
|
3030
|
-
{
|
|
3252
|
+
{
|
|
3253
|
+
d_lite_gc_mark,
|
|
3254
|
+
RUBY_TYPED_DEFAULT_FREE,
|
|
3255
|
+
d_lite_memsize,
|
|
3256
|
+
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
|
3257
|
+
d_lite_gc_compact,
|
|
3258
|
+
#endif
|
|
3259
|
+
},
|
|
3031
3260
|
0, 0,
|
|
3032
|
-
RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED|RUBY_TYPED_FROZEN_SHAREABLE,
|
|
3261
|
+
RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED|RUBY_TYPED_EMBEDDABLE|RUBY_TYPED_FROZEN_SHAREABLE,
|
|
3033
3262
|
};
|
|
3034
3263
|
|
|
3035
3264
|
inline static VALUE
|
|
@@ -3040,10 +3269,11 @@ d_simple_new_internal(VALUE klass,
|
|
|
3040
3269
|
unsigned flags)
|
|
3041
3270
|
{
|
|
3042
3271
|
struct SimpleDateData *dat;
|
|
3272
|
+
union DateData *u_dat;
|
|
3043
3273
|
VALUE obj;
|
|
3044
3274
|
|
|
3045
|
-
obj = TypedData_Make_Struct(klass,
|
|
3046
|
-
|
|
3275
|
+
obj = TypedData_Make_Struct(klass, union DateData, &d_lite_type, u_dat);
|
|
3276
|
+
dat = &u_dat->s;
|
|
3047
3277
|
set_to_simple(obj, dat, nth, jd, sg, y, m, d, flags);
|
|
3048
3278
|
|
|
3049
3279
|
assert(have_jd_p(dat) || have_civil_p(dat));
|
|
@@ -3061,10 +3291,11 @@ d_complex_new_internal(VALUE klass,
|
|
|
3061
3291
|
unsigned flags)
|
|
3062
3292
|
{
|
|
3063
3293
|
struct ComplexDateData *dat;
|
|
3294
|
+
union DateData *u_dat;
|
|
3064
3295
|
VALUE obj;
|
|
3065
3296
|
|
|
3066
|
-
obj = TypedData_Make_Struct(klass,
|
|
3067
|
-
|
|
3297
|
+
obj = TypedData_Make_Struct(klass, union DateData, &d_lite_type, u_dat);
|
|
3298
|
+
dat = &u_dat->c;
|
|
3068
3299
|
set_to_complex(obj, dat, nth, jd, df, sf, of, sg,
|
|
3069
3300
|
y, m, d, h, min, s, flags);
|
|
3070
3301
|
|
|
@@ -3350,7 +3581,7 @@ static VALUE d_lite_plus(VALUE, VALUE);
|
|
|
3350
3581
|
*
|
|
3351
3582
|
* Date.jd(Date::ITALY - 1).julian? # => true
|
|
3352
3583
|
*
|
|
3353
|
-
* See argument {start}[rdoc-ref:
|
|
3584
|
+
* See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
3354
3585
|
*
|
|
3355
3586
|
* Related: Date.new.
|
|
3356
3587
|
*/
|
|
@@ -3415,7 +3646,7 @@ date_s_jd(int argc, VALUE *argv, VALUE klass)
|
|
|
3415
3646
|
*
|
|
3416
3647
|
* Raises an exception if +yday+ is zero or out of range.
|
|
3417
3648
|
*
|
|
3418
|
-
* See argument {start}[rdoc-ref:
|
|
3649
|
+
* See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
3419
3650
|
*
|
|
3420
3651
|
* Related: Date.jd, Date.new.
|
|
3421
3652
|
*/
|
|
@@ -3492,7 +3723,7 @@ date_s_civil(int argc, VALUE *argv, VALUE klass)
|
|
|
3492
3723
|
* where +n+ is the number of days in the month;
|
|
3493
3724
|
* when the argument is negative, counts backward from the end of the month.
|
|
3494
3725
|
*
|
|
3495
|
-
* See argument {start}[rdoc-ref:
|
|
3726
|
+
* See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
3496
3727
|
*
|
|
3497
3728
|
* Related: Date.jd.
|
|
3498
3729
|
*/
|
|
@@ -3598,7 +3829,7 @@ date_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
3598
3829
|
* Date.commercial(2020, 1, 1).to_s # => "2019-12-30"
|
|
3599
3830
|
Date.commercial(2020, 1, 7).to_s # => "2020-01-05"
|
|
3600
3831
|
*
|
|
3601
|
-
* See argument {start}[rdoc-ref:
|
|
3832
|
+
* See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
3602
3833
|
*
|
|
3603
3834
|
* Related: Date.jd, Date.new, Date.ordinal.
|
|
3604
3835
|
*/
|
|
@@ -3783,7 +4014,7 @@ static void set_sg(union DateData *, double);
|
|
|
3783
4014
|
*
|
|
3784
4015
|
* Date.today.to_s # => "2022-07-06"
|
|
3785
4016
|
*
|
|
3786
|
-
* See argument {start}[rdoc-ref:
|
|
4017
|
+
* See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
3787
4018
|
*
|
|
3788
4019
|
*/
|
|
3789
4020
|
static VALUE
|
|
@@ -4322,7 +4553,8 @@ d_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
|
|
|
4322
4553
|
}
|
|
4323
4554
|
|
|
4324
4555
|
VALUE date__strptime(const char *str, size_t slen,
|
|
4325
|
-
const char *fmt, size_t flen,
|
|
4556
|
+
const char *fmt, size_t flen,
|
|
4557
|
+
VALUE hash, rb_encoding *enc);
|
|
4326
4558
|
|
|
4327
4559
|
static VALUE
|
|
4328
4560
|
date_s__strptime_internal(int argc, VALUE *argv, VALUE klass,
|
|
@@ -4331,10 +4563,12 @@ date_s__strptime_internal(int argc, VALUE *argv, VALUE klass,
|
|
|
4331
4563
|
VALUE vstr, vfmt, hash;
|
|
4332
4564
|
const char *str, *fmt;
|
|
4333
4565
|
size_t slen, flen;
|
|
4566
|
+
rb_encoding *enc;
|
|
4334
4567
|
|
|
4335
4568
|
rb_scan_args(argc, argv, "11", &vstr, &vfmt);
|
|
4336
4569
|
|
|
4337
4570
|
StringValue(vstr);
|
|
4571
|
+
if (argc > 1) StringValue(vfmt);
|
|
4338
4572
|
if (!rb_enc_str_asciicompat_p(vstr))
|
|
4339
4573
|
rb_raise(rb_eArgError,
|
|
4340
4574
|
"string should have ASCII compatible encoding");
|
|
@@ -4343,34 +4577,18 @@ date_s__strptime_internal(int argc, VALUE *argv, VALUE klass,
|
|
|
4343
4577
|
if (argc < 2) {
|
|
4344
4578
|
fmt = default_fmt;
|
|
4345
4579
|
flen = strlen(default_fmt);
|
|
4580
|
+
enc = rb_enc_get(vstr);
|
|
4346
4581
|
}
|
|
4347
4582
|
else {
|
|
4348
|
-
StringValue(vfmt);
|
|
4349
4583
|
if (!rb_enc_str_asciicompat_p(vfmt))
|
|
4350
4584
|
rb_raise(rb_eArgError,
|
|
4351
4585
|
"format should have ASCII compatible encoding");
|
|
4586
|
+
enc = rb_enc_check(vstr, vfmt);
|
|
4352
4587
|
fmt = RSTRING_PTR(vfmt);
|
|
4353
4588
|
flen = RSTRING_LEN(vfmt);
|
|
4354
4589
|
}
|
|
4355
4590
|
hash = rb_hash_new();
|
|
4356
|
-
|
|
4357
|
-
return Qnil;
|
|
4358
|
-
|
|
4359
|
-
{
|
|
4360
|
-
VALUE zone = ref_hash("zone");
|
|
4361
|
-
VALUE left = ref_hash("leftover");
|
|
4362
|
-
|
|
4363
|
-
if (!NIL_P(zone)) {
|
|
4364
|
-
rb_enc_copy(zone, vstr);
|
|
4365
|
-
set_hash("zone", zone);
|
|
4366
|
-
}
|
|
4367
|
-
if (!NIL_P(left)) {
|
|
4368
|
-
rb_enc_copy(left, vstr);
|
|
4369
|
-
set_hash("leftover", left);
|
|
4370
|
-
}
|
|
4371
|
-
}
|
|
4372
|
-
|
|
4373
|
-
return hash;
|
|
4591
|
+
return date__strptime(str, slen, fmt, flen, hash, enc);
|
|
4374
4592
|
}
|
|
4375
4593
|
|
|
4376
4594
|
/*
|
|
@@ -4383,7 +4601,7 @@ date_s__strptime_internal(int argc, VALUE *argv, VALUE klass,
|
|
|
4383
4601
|
* Date._strptime('2001-02-03', '%Y-%m-%d') # => {:year=>2001, :mon=>2, :mday=>3}
|
|
4384
4602
|
*
|
|
4385
4603
|
* For other formats, see
|
|
4386
|
-
* {Formats for Dates and Times}[
|
|
4604
|
+
* {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc].
|
|
4387
4605
|
* (Unlike Date.strftime, does not support flags and width.)
|
|
4388
4606
|
*
|
|
4389
4607
|
* See also {strptime(3)}[https://man7.org/linux/man-pages/man3/strptime.3.html].
|
|
@@ -4412,10 +4630,10 @@ date_s__strptime(int argc, VALUE *argv, VALUE klass)
|
|
|
4412
4630
|
* Date.strptime('sat3feb01', '%a%d%b%y') # => #<Date: 2001-02-03>
|
|
4413
4631
|
*
|
|
4414
4632
|
* For other formats, see
|
|
4415
|
-
* {Formats for Dates and Times}[
|
|
4633
|
+
* {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc].
|
|
4416
4634
|
* (Unlike Date.strftime, does not support flags and width.)
|
|
4417
4635
|
*
|
|
4418
|
-
* See argument {start}[rdoc-ref:
|
|
4636
|
+
* See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
4419
4637
|
*
|
|
4420
4638
|
* See also {strptime(3)}[https://man7.org/linux/man-pages/man3/strptime.3.html].
|
|
4421
4639
|
*
|
|
@@ -4504,7 +4722,7 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
|
|
|
4504
4722
|
* This method recognizes many forms in +string+,
|
|
4505
4723
|
* but it is not a validator.
|
|
4506
4724
|
* For formats, see
|
|
4507
|
-
* {"Specialized Format Strings" in Formats for Dates and Times}[
|
|
4725
|
+
* {"Specialized Format Strings" in Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc@Specialized+Format+Strings]
|
|
4508
4726
|
*
|
|
4509
4727
|
* If +string+ does not specify a valid date,
|
|
4510
4728
|
* the result is unpredictable;
|
|
@@ -4539,7 +4757,7 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
|
|
|
4539
4757
|
* This method recognizes many forms in +string+,
|
|
4540
4758
|
* but it is not a validator.
|
|
4541
4759
|
* For formats, see
|
|
4542
|
-
* {"Specialized Format Strings" in Formats for Dates and Times}[
|
|
4760
|
+
* {"Specialized Format Strings" in Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc@Specialized+Format+Strings]
|
|
4543
4761
|
* If +string+ does not specify a valid date,
|
|
4544
4762
|
* the result is unpredictable;
|
|
4545
4763
|
* consider using Date._strptime instead.
|
|
@@ -4559,7 +4777,7 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
|
|
|
4559
4777
|
*
|
|
4560
4778
|
* See:
|
|
4561
4779
|
*
|
|
4562
|
-
* - Argument {start}[rdoc-ref:
|
|
4780
|
+
* - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
4563
4781
|
* - Argument {limit}[rdoc-ref:Date@Argument+limit].
|
|
4564
4782
|
*
|
|
4565
4783
|
* Related: Date._parse (returns a hash).
|
|
@@ -4603,7 +4821,7 @@ VALUE date__jisx0301(VALUE);
|
|
|
4603
4821
|
* Date._iso8601(string, limit: 128) -> hash
|
|
4604
4822
|
*
|
|
4605
4823
|
* Returns a hash of values parsed from +string+, which should contain
|
|
4606
|
-
* an {ISO 8601 formatted date}[
|
|
4824
|
+
* an {ISO 8601 formatted date}[rdoc-ref:language/strftime_formatting.rdoc@ISO+8601+Format+Specifications]:
|
|
4607
4825
|
*
|
|
4608
4826
|
* d = Date.new(2001, 2, 3)
|
|
4609
4827
|
* s = d.iso8601 # => "2001-02-03"
|
|
@@ -4630,7 +4848,7 @@ date_s__iso8601(int argc, VALUE *argv, VALUE klass)
|
|
|
4630
4848
|
*
|
|
4631
4849
|
* Returns a new \Date object with values parsed from +string+,
|
|
4632
4850
|
* which should contain
|
|
4633
|
-
* an {ISO 8601 formatted date}[
|
|
4851
|
+
* an {ISO 8601 formatted date}[rdoc-ref:language/strftime_formatting.rdoc@ISO+8601+Format+Specifications]:
|
|
4634
4852
|
*
|
|
4635
4853
|
* d = Date.new(2001, 2, 3)
|
|
4636
4854
|
* s = d.iso8601 # => "2001-02-03"
|
|
@@ -4638,7 +4856,7 @@ date_s__iso8601(int argc, VALUE *argv, VALUE klass)
|
|
|
4638
4856
|
*
|
|
4639
4857
|
* See:
|
|
4640
4858
|
*
|
|
4641
|
-
* - Argument {start}[rdoc-ref:
|
|
4859
|
+
* - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
4642
4860
|
* - Argument {limit}[rdoc-ref:Date@Argument+limit].
|
|
4643
4861
|
*
|
|
4644
4862
|
* Related: Date._iso8601 (returns a hash).
|
|
@@ -4672,7 +4890,7 @@ date_s_iso8601(int argc, VALUE *argv, VALUE klass)
|
|
|
4672
4890
|
* Date._rfc3339(string, limit: 128) -> hash
|
|
4673
4891
|
*
|
|
4674
4892
|
* Returns a hash of values parsed from +string+, which should be a valid
|
|
4675
|
-
* {RFC 3339 format}[
|
|
4893
|
+
* {RFC 3339 format}[rdoc-ref:language/strftime_formatting.rdoc@RFC+3339+Format]:
|
|
4676
4894
|
*
|
|
4677
4895
|
* d = Date.new(2001, 2, 3)
|
|
4678
4896
|
* s = d.rfc3339 # => "2001-02-03T00:00:00+00:00"
|
|
@@ -4700,7 +4918,7 @@ date_s__rfc3339(int argc, VALUE *argv, VALUE klass)
|
|
|
4700
4918
|
*
|
|
4701
4919
|
* Returns a new \Date object with values parsed from +string+,
|
|
4702
4920
|
* which should be a valid
|
|
4703
|
-
* {RFC 3339 format}[
|
|
4921
|
+
* {RFC 3339 format}[rdoc-ref:language/strftime_formatting.rdoc@RFC+3339+Format]:
|
|
4704
4922
|
*
|
|
4705
4923
|
* d = Date.new(2001, 2, 3)
|
|
4706
4924
|
* s = d.rfc3339 # => "2001-02-03T00:00:00+00:00"
|
|
@@ -4708,7 +4926,7 @@ date_s__rfc3339(int argc, VALUE *argv, VALUE klass)
|
|
|
4708
4926
|
*
|
|
4709
4927
|
* See:
|
|
4710
4928
|
*
|
|
4711
|
-
* - Argument {start}[rdoc-ref:
|
|
4929
|
+
* - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
4712
4930
|
* - Argument {limit}[rdoc-ref:Date@Argument+limit].
|
|
4713
4931
|
*
|
|
4714
4932
|
* Related: Date._rfc3339 (returns a hash).
|
|
@@ -4776,7 +4994,7 @@ date_s__xmlschema(int argc, VALUE *argv, VALUE klass)
|
|
|
4776
4994
|
*
|
|
4777
4995
|
* See:
|
|
4778
4996
|
*
|
|
4779
|
-
* - Argument {start}[rdoc-ref:
|
|
4997
|
+
* - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
4780
4998
|
* - Argument {limit}[rdoc-ref:Date@Argument+limit].
|
|
4781
4999
|
*
|
|
4782
5000
|
* Related: Date._xmlschema (returns a hash).
|
|
@@ -4810,7 +5028,7 @@ date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
|
|
|
4810
5028
|
* Date._rfc2822(string, limit: 128) -> hash
|
|
4811
5029
|
*
|
|
4812
5030
|
* Returns a hash of values parsed from +string+, which should be a valid
|
|
4813
|
-
* {RFC 2822 date format}[
|
|
5031
|
+
* {RFC 2822 date format}[rdoc-ref:language/strftime_formatting.rdoc@RFC+2822+Format]:
|
|
4814
5032
|
*
|
|
4815
5033
|
* d = Date.new(2001, 2, 3)
|
|
4816
5034
|
* s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000"
|
|
@@ -4838,7 +5056,7 @@ date_s__rfc2822(int argc, VALUE *argv, VALUE klass)
|
|
|
4838
5056
|
*
|
|
4839
5057
|
* Returns a new \Date object with values parsed from +string+,
|
|
4840
5058
|
* which should be a valid
|
|
4841
|
-
* {RFC 2822 date format}[
|
|
5059
|
+
* {RFC 2822 date format}[rdoc-ref:language/strftime_formatting.rdoc@RFC+2822+Format]:
|
|
4842
5060
|
*
|
|
4843
5061
|
* d = Date.new(2001, 2, 3)
|
|
4844
5062
|
* s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000"
|
|
@@ -4846,7 +5064,7 @@ date_s__rfc2822(int argc, VALUE *argv, VALUE klass)
|
|
|
4846
5064
|
*
|
|
4847
5065
|
* See:
|
|
4848
5066
|
*
|
|
4849
|
-
* - Argument {start}[rdoc-ref:
|
|
5067
|
+
* - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
4850
5068
|
* - Argument {limit}[rdoc-ref:Date@Argument+limit].
|
|
4851
5069
|
*
|
|
4852
5070
|
* Related: Date._rfc2822 (returns a hash).
|
|
@@ -4880,7 +5098,7 @@ date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
|
|
|
4880
5098
|
* Date._httpdate(string, limit: 128) -> hash
|
|
4881
5099
|
*
|
|
4882
5100
|
* Returns a hash of values parsed from +string+, which should be a valid
|
|
4883
|
-
* {HTTP date format}[
|
|
5101
|
+
* {HTTP date format}[rdoc-ref:language/strftime_formatting.rdoc@HTTP+Format]:
|
|
4884
5102
|
*
|
|
4885
5103
|
* d = Date.new(2001, 2, 3)
|
|
4886
5104
|
* s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT"
|
|
@@ -4906,7 +5124,7 @@ date_s__httpdate(int argc, VALUE *argv, VALUE klass)
|
|
|
4906
5124
|
*
|
|
4907
5125
|
* Returns a new \Date object with values parsed from +string+,
|
|
4908
5126
|
* which should be a valid
|
|
4909
|
-
* {HTTP date format}[
|
|
5127
|
+
* {HTTP date format}[rdoc-ref:language/strftime_formatting.rdoc@HTTP+Format]:
|
|
4910
5128
|
*
|
|
4911
5129
|
* d = Date.new(2001, 2, 3)
|
|
4912
5130
|
s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT"
|
|
@@ -4914,7 +5132,7 @@ date_s__httpdate(int argc, VALUE *argv, VALUE klass)
|
|
|
4914
5132
|
*
|
|
4915
5133
|
* See:
|
|
4916
5134
|
*
|
|
4917
|
-
* - Argument {start}[rdoc-ref:
|
|
5135
|
+
* - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
4918
5136
|
* - Argument {limit}[rdoc-ref:Date@Argument+limit].
|
|
4919
5137
|
*
|
|
4920
5138
|
* Related: Date._httpdate (returns a hash).
|
|
@@ -4948,7 +5166,7 @@ date_s_httpdate(int argc, VALUE *argv, VALUE klass)
|
|
|
4948
5166
|
* Date._jisx0301(string, limit: 128) -> hash
|
|
4949
5167
|
*
|
|
4950
5168
|
* Returns a hash of values parsed from +string+, which should be a valid
|
|
4951
|
-
* {JIS X 0301 date format}[
|
|
5169
|
+
* {JIS X 0301 date format}[rdoc-ref:language/strftime_formatting.rdoc@JIS+X+0301+Format]:
|
|
4952
5170
|
*
|
|
4953
5171
|
* d = Date.new(2001, 2, 3)
|
|
4954
5172
|
* s = d.jisx0301 # => "H13.02.03"
|
|
@@ -4974,7 +5192,7 @@ date_s__jisx0301(int argc, VALUE *argv, VALUE klass)
|
|
|
4974
5192
|
* Date.jisx0301(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date
|
|
4975
5193
|
*
|
|
4976
5194
|
* Returns a new \Date object with values parsed from +string+,
|
|
4977
|
-
* which should be a valid {JIS X 0301 format}[
|
|
5195
|
+
* which should be a valid {JIS X 0301 format}[rdoc-ref:language/strftime_formatting.rdoc@JIS+X+0301+Format]:
|
|
4978
5196
|
*
|
|
4979
5197
|
* d = Date.new(2001, 2, 3)
|
|
4980
5198
|
* s = d.jisx0301 # => "H13.02.03"
|
|
@@ -4986,7 +5204,7 @@ date_s__jisx0301(int argc, VALUE *argv, VALUE klass)
|
|
|
4986
5204
|
*
|
|
4987
5205
|
* See:
|
|
4988
5206
|
*
|
|
4989
|
-
* - Argument {start}[rdoc-ref:
|
|
5207
|
+
* - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
4990
5208
|
* - Argument {limit}[rdoc-ref:Date@Argument+limit].
|
|
4991
5209
|
*
|
|
4992
5210
|
* Related: Date._jisx0301 (returns a hash).
|
|
@@ -5744,7 +5962,7 @@ d_lite_leap_p(VALUE self)
|
|
|
5744
5962
|
* Date.new(2001, 2, 3, Date::GREGORIAN).start # => -Infinity
|
|
5745
5963
|
* Date.new(2001, 2, 3, Date::JULIAN).start # => Infinity
|
|
5746
5964
|
*
|
|
5747
|
-
* See argument {start}[rdoc-ref:
|
|
5965
|
+
* See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
5748
5966
|
*
|
|
5749
5967
|
*/
|
|
5750
5968
|
static VALUE
|
|
@@ -5810,7 +6028,7 @@ dup_obj_with_new_start(VALUE obj, double sg)
|
|
|
5810
6028
|
|
|
5811
6029
|
/*
|
|
5812
6030
|
* call-seq:
|
|
5813
|
-
* new_start(start = Date::ITALY
|
|
6031
|
+
* new_start(start = Date::ITALY) -> new_date
|
|
5814
6032
|
*
|
|
5815
6033
|
* Returns a copy of +self+ with the given +start+ value:
|
|
5816
6034
|
*
|
|
@@ -5819,7 +6037,7 @@ dup_obj_with_new_start(VALUE obj, double sg)
|
|
|
5819
6037
|
* d1 = d0.new_start(Date::JULIAN)
|
|
5820
6038
|
* d1.julian? # => true
|
|
5821
6039
|
*
|
|
5822
|
-
* See argument {start}[rdoc-ref:
|
|
6040
|
+
* See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
|
|
5823
6041
|
*
|
|
5824
6042
|
*/
|
|
5825
6043
|
static VALUE
|
|
@@ -6967,7 +7185,7 @@ static VALUE strftimev(const char *, VALUE,
|
|
|
6967
7185
|
* to_s -> string
|
|
6968
7186
|
*
|
|
6969
7187
|
* Returns a string representation of the date in +self+
|
|
6970
|
-
* in {ISO 8601 extended date format}[
|
|
7188
|
+
* in {ISO 8601 extended date format}[rdoc-ref:language/strftime_formatting.rdoc@ISO+8601+Format+Specifications]
|
|
6971
7189
|
* (<tt>'%Y-%m-%d'</tt>):
|
|
6972
7190
|
*
|
|
6973
7191
|
* Date.new(2001, 2, 3).to_s # => "2001-02-03"
|
|
@@ -7248,7 +7466,7 @@ date_strftime_internal(int argc, VALUE *argv, VALUE self,
|
|
|
7248
7466
|
* Date.new(2001, 2, 3).strftime # => "2001-02-03"
|
|
7249
7467
|
*
|
|
7250
7468
|
* For other formats, see
|
|
7251
|
-
* {Formats for Dates and Times}[
|
|
7469
|
+
* {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc].
|
|
7252
7470
|
*
|
|
7253
7471
|
*/
|
|
7254
7472
|
static VALUE
|
|
@@ -7280,12 +7498,12 @@ strftimev(const char *fmt, VALUE self,
|
|
|
7280
7498
|
* asctime -> string
|
|
7281
7499
|
*
|
|
7282
7500
|
* Equivalent to #strftime with argument <tt>'%a %b %e %T %Y'</tt>
|
|
7283
|
-
* (or its {shorthand form}[
|
|
7501
|
+
* (or its {shorthand form}[rdoc-ref:language/strftime_formatting.rdoc@Shorthand+Conversion+Specifiers]
|
|
7284
7502
|
* <tt>'%c'</tt>):
|
|
7285
7503
|
*
|
|
7286
7504
|
* Date.new(2001, 2, 3).asctime # => "Sat Feb 3 00:00:00 2001"
|
|
7287
7505
|
*
|
|
7288
|
-
* See {asctime}[https://
|
|
7506
|
+
* See {asctime}[https://man7.org/linux/man-pages/man3/asctime.3p.html].
|
|
7289
7507
|
*
|
|
7290
7508
|
*/
|
|
7291
7509
|
static VALUE
|
|
@@ -7299,7 +7517,7 @@ d_lite_asctime(VALUE self)
|
|
|
7299
7517
|
* iso8601 -> string
|
|
7300
7518
|
*
|
|
7301
7519
|
* Equivalent to #strftime with argument <tt>'%Y-%m-%d'</tt>
|
|
7302
|
-
* (or its {shorthand form}[
|
|
7520
|
+
* (or its {shorthand form}[rdoc-ref:language/strftime_formatting.rdoc@Shorthand+Conversion+Specifiers]
|
|
7303
7521
|
* <tt>'%F'</tt>);
|
|
7304
7522
|
*
|
|
7305
7523
|
* Date.new(2001, 2, 3).iso8601 # => "2001-02-03"
|
|
@@ -7316,7 +7534,7 @@ d_lite_iso8601(VALUE self)
|
|
|
7316
7534
|
* rfc3339 -> string
|
|
7317
7535
|
*
|
|
7318
7536
|
* Equivalent to #strftime with argument <tt>'%FT%T%:z'</tt>;
|
|
7319
|
-
* see {Formats for Dates and Times}[
|
|
7537
|
+
* see {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]:
|
|
7320
7538
|
*
|
|
7321
7539
|
* Date.new(2001, 2, 3).rfc3339 # => "2001-02-03T00:00:00+00:00"
|
|
7322
7540
|
*
|
|
@@ -7332,7 +7550,7 @@ d_lite_rfc3339(VALUE self)
|
|
|
7332
7550
|
* rfc2822 -> string
|
|
7333
7551
|
*
|
|
7334
7552
|
* Equivalent to #strftime with argument <tt>'%a, %-d %b %Y %T %z'</tt>;
|
|
7335
|
-
* see {Formats for Dates and Times}[
|
|
7553
|
+
* see {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]:
|
|
7336
7554
|
*
|
|
7337
7555
|
* Date.new(2001, 2, 3).rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000"
|
|
7338
7556
|
*
|
|
@@ -7348,7 +7566,7 @@ d_lite_rfc2822(VALUE self)
|
|
|
7348
7566
|
* httpdate -> string
|
|
7349
7567
|
*
|
|
7350
7568
|
* Equivalent to #strftime with argument <tt>'%a, %d %b %Y %T GMT'</tt>;
|
|
7351
|
-
* see {Formats for Dates and Times}[
|
|
7569
|
+
* see {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]:
|
|
7352
7570
|
*
|
|
7353
7571
|
* Date.new(2001, 2, 3).httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT"
|
|
7354
7572
|
*
|
|
@@ -7611,8 +7829,6 @@ d_lite_marshal_load(VALUE self, VALUE a)
|
|
|
7611
7829
|
if (simple_dat_p(dat)) {
|
|
7612
7830
|
if (df || !f_zero_p(sf) || of) {
|
|
7613
7831
|
/* loading a fractional date; promote to complex */
|
|
7614
|
-
dat = ruby_xrealloc(dat, sizeof(struct ComplexDateData));
|
|
7615
|
-
RTYPEDDATA(self)->data = dat;
|
|
7616
7832
|
goto complex_data;
|
|
7617
7833
|
}
|
|
7618
7834
|
set_to_simple(self, &dat->s, nth, jd, sg, 0, 0, 0, HAVE_JD);
|
|
@@ -8717,7 +8933,7 @@ dt_lite_to_s(VALUE self)
|
|
|
8717
8933
|
* DateTime.now.strftime # => "2022-07-01T11:03:19-05:00"
|
|
8718
8934
|
*
|
|
8719
8935
|
* For other formats,
|
|
8720
|
-
* see {Formats for Dates and Times}[
|
|
8936
|
+
* see {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]:
|
|
8721
8937
|
*
|
|
8722
8938
|
*/
|
|
8723
8939
|
static VALUE
|
|
@@ -9496,6 +9712,7 @@ Init_date_core(void)
|
|
|
9496
9712
|
sym_zone = ID2SYM(rb_intern_const("zone"));
|
|
9497
9713
|
|
|
9498
9714
|
half_days_in_day = rb_rational_new2(INT2FIX(1), INT2FIX(2));
|
|
9715
|
+
rb_gc_register_mark_object(half_days_in_day);
|
|
9499
9716
|
|
|
9500
9717
|
#if (LONG_MAX / DAY_IN_SECONDS) > SECOND_IN_NANOSECONDS
|
|
9501
9718
|
day_in_nanoseconds = LONG2NUM((long)DAY_IN_SECONDS *
|
|
@@ -9507,8 +9724,6 @@ Init_date_core(void)
|
|
|
9507
9724
|
day_in_nanoseconds = f_mul(INT2FIX(DAY_IN_SECONDS),
|
|
9508
9725
|
INT2FIX(SECOND_IN_NANOSECONDS));
|
|
9509
9726
|
#endif
|
|
9510
|
-
|
|
9511
|
-
rb_gc_register_mark_object(half_days_in_day);
|
|
9512
9727
|
rb_gc_register_mark_object(day_in_nanoseconds);
|
|
9513
9728
|
|
|
9514
9729
|
positive_inf = +INFINITY;
|
|
@@ -9519,12 +9734,12 @@ Init_date_core(void)
|
|
|
9519
9734
|
* calendar dates.
|
|
9520
9735
|
*
|
|
9521
9736
|
* Consider using
|
|
9522
|
-
* {class Time}[
|
|
9737
|
+
* {class Time}[rdoc-ref:Time]
|
|
9523
9738
|
* instead of class \Date if:
|
|
9524
9739
|
*
|
|
9525
9740
|
* - You need both dates and times; \Date handles only dates.
|
|
9526
9741
|
* - You need only Gregorian dates (and not Julian dates);
|
|
9527
|
-
* see {Julian and Gregorian Calendars}[rdoc-ref:
|
|
9742
|
+
* see {Julian and Gregorian Calendars}[rdoc-ref:language/calendars.rdoc].
|
|
9528
9743
|
*
|
|
9529
9744
|
* A \Date object, once created, is immutable, and cannot be modified.
|
|
9530
9745
|
*
|
|
@@ -9571,7 +9786,7 @@ Init_date_core(void)
|
|
|
9571
9786
|
* Date.strptime('fri31dec99', '%a%d%b%y') # => #<Date: 1999-12-31>
|
|
9572
9787
|
*
|
|
9573
9788
|
* See also the specialized methods in
|
|
9574
|
-
* {"Specialized Format Strings" in Formats for Dates and Times}[
|
|
9789
|
+
* {"Specialized Format Strings" in Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc@Specialized+Format+Strings]
|
|
9575
9790
|
*
|
|
9576
9791
|
* == Argument +limit+
|
|
9577
9792
|
*
|
data/ext/date/date_parse.c
CHANGED
|
@@ -2325,6 +2325,16 @@ sec_fraction(VALUE f)
|
|
|
2325
2325
|
|
|
2326
2326
|
#define SNUM 14
|
|
2327
2327
|
|
|
2328
|
+
#ifndef rb_streql_lit
|
|
2329
|
+
static inline int
|
|
2330
|
+
rb_streql_cstr(VALUE str, const char *lit, size_t len)
|
|
2331
|
+
{
|
|
2332
|
+
if ((size_t)RSTRING_LEN(str) != len) return 0;
|
|
2333
|
+
return memcmp(RSTRING_PTR(str), lit, len) == 0;
|
|
2334
|
+
}
|
|
2335
|
+
#define rb_streql_lit(str, lit) rb_streql_cstr(str, lit, sizeof(lit "") - 1)
|
|
2336
|
+
#endif
|
|
2337
|
+
|
|
2328
2338
|
static int
|
|
2329
2339
|
iso8601_ext_datetime_cb(VALUE m, VALUE hash)
|
|
2330
2340
|
{
|
|
@@ -2339,14 +2349,14 @@ iso8601_ext_datetime_cb(VALUE m, VALUE hash)
|
|
|
2339
2349
|
|
|
2340
2350
|
if (!NIL_P(s[1])) {
|
|
2341
2351
|
if (!NIL_P(s[3])) set_hash("mday", str2num(s[3]));
|
|
2342
|
-
if (
|
|
2352
|
+
if (!rb_streql_lit(s[1], "-")) {
|
|
2343
2353
|
y = str2num(s[1]);
|
|
2344
2354
|
if (RSTRING_LEN(s[1]) < 4)
|
|
2345
2355
|
y = comp_year69(y);
|
|
2346
2356
|
set_hash("year", y);
|
|
2347
2357
|
}
|
|
2348
2358
|
if (NIL_P(s[2])) {
|
|
2349
|
-
if (
|
|
2359
|
+
if (!rb_streql_lit(s[1], "-"))
|
|
2350
2360
|
return 0;
|
|
2351
2361
|
}
|
|
2352
2362
|
else
|
|
@@ -2425,14 +2435,14 @@ iso8601_bas_datetime_cb(VALUE m, VALUE hash)
|
|
|
2425
2435
|
|
|
2426
2436
|
if (!NIL_P(s[3])) {
|
|
2427
2437
|
set_hash("mday", str2num(s[3]));
|
|
2428
|
-
if (
|
|
2438
|
+
if (!rb_streql_lit(s[1], "--")) {
|
|
2429
2439
|
y = str2num(s[1]);
|
|
2430
2440
|
if (RSTRING_LEN(s[1]) < 4)
|
|
2431
2441
|
y = comp_year69(y);
|
|
2432
2442
|
set_hash("year", y);
|
|
2433
2443
|
}
|
|
2434
2444
|
if (*RSTRING_PTR(s[2]) == '-') {
|
|
2435
|
-
if (
|
|
2445
|
+
if (!rb_streql_lit(s[1], "--"))
|
|
2436
2446
|
return 0;
|
|
2437
2447
|
}
|
|
2438
2448
|
else
|
data/ext/date/date_strptime.c
CHANGED
|
@@ -41,7 +41,6 @@ static const int ABBREVIATED_MONTH_NAME_LENGTH = 3;
|
|
|
41
41
|
|
|
42
42
|
#define f_match(r,s) rb_funcall(r, rb_intern("match"), 1, s)
|
|
43
43
|
#define f_aref(o,i) rb_funcall(o, rb_intern("[]"), 1, i)
|
|
44
|
-
#define f_end(o,i) rb_funcall(o, rb_intern("end"), 1, i)
|
|
45
44
|
|
|
46
45
|
#define issign(c) ((c) == '-' || (c) == '+')
|
|
47
46
|
|
|
@@ -144,7 +143,7 @@ valid_range_p(VALUE v, int a, int b)
|
|
|
144
143
|
do { \
|
|
145
144
|
size_t l; \
|
|
146
145
|
l = date__strptime_internal(&str[si], slen - si, \
|
|
147
|
-
fmt, sizeof fmt - 1, hash); \
|
|
146
|
+
fmt, sizeof fmt - 1, hash, enc); \
|
|
148
147
|
if (fail_p()) \
|
|
149
148
|
return 0; \
|
|
150
149
|
si += l; \
|
|
@@ -160,7 +159,8 @@ head_match_p(size_t len, const char *name, const char *str, size_t slen, size_t
|
|
|
160
159
|
|
|
161
160
|
static size_t
|
|
162
161
|
date__strptime_internal(const char *str, size_t slen,
|
|
163
|
-
const char *fmt, size_t flen,
|
|
162
|
+
const char *fmt, size_t flen,
|
|
163
|
+
VALUE hash, rb_encoding *enc)
|
|
164
164
|
{
|
|
165
165
|
size_t si, fi;
|
|
166
166
|
int c;
|
|
@@ -597,15 +597,14 @@ date__strptime_internal(const char *str, size_t slen,
|
|
|
597
597
|
|
|
598
598
|
b = rb_backref_get();
|
|
599
599
|
rb_match_busy(b);
|
|
600
|
-
m = f_match(pat,
|
|
600
|
+
m = f_match(pat, rb_enc_str_new(&str[si], slen - si, enc));
|
|
601
601
|
|
|
602
602
|
if (!NIL_P(m)) {
|
|
603
|
-
VALUE s,
|
|
603
|
+
VALUE s, o;
|
|
604
604
|
|
|
605
605
|
s = rb_reg_nth_match(1, m);
|
|
606
|
-
l = f_end(m, INT2FIX(0));
|
|
607
606
|
o = date_zone_to_diff(s);
|
|
608
|
-
si +=
|
|
607
|
+
si += RSTRING_LEN(s);
|
|
609
608
|
set_hash("zone", s);
|
|
610
609
|
set_hash("offset", o);
|
|
611
610
|
rb_backref_set(b);
|
|
@@ -654,23 +653,24 @@ date__strptime_internal(const char *str, size_t slen,
|
|
|
654
653
|
|
|
655
654
|
VALUE
|
|
656
655
|
date__strptime(const char *str, size_t slen,
|
|
657
|
-
const char *fmt, size_t flen,
|
|
656
|
+
const char *fmt, size_t flen,
|
|
657
|
+
VALUE hash, rb_encoding *enc)
|
|
658
658
|
{
|
|
659
659
|
size_t si;
|
|
660
660
|
VALUE cent, merid;
|
|
661
661
|
|
|
662
|
-
si = date__strptime_internal(str, slen, fmt, flen, hash);
|
|
662
|
+
si = date__strptime_internal(str, slen, fmt, flen, hash, enc);
|
|
663
|
+
|
|
664
|
+
if (fail_p())
|
|
665
|
+
return Qnil;
|
|
663
666
|
|
|
664
667
|
if (slen > si) {
|
|
665
668
|
VALUE s;
|
|
666
669
|
|
|
667
|
-
s =
|
|
670
|
+
s = rb_enc_str_new(&str[si], slen - si, enc);
|
|
668
671
|
set_hash("leftover", s);
|
|
669
672
|
}
|
|
670
673
|
|
|
671
|
-
if (fail_p())
|
|
672
|
-
return Qnil;
|
|
673
|
-
|
|
674
674
|
cent = del_hash("_cent");
|
|
675
675
|
if (!NIL_P(cent)) {
|
|
676
676
|
VALUE year;
|
data/ext/date/extconf.rb
CHANGED
|
@@ -3,6 +3,9 @@ require 'mkmf'
|
|
|
3
3
|
|
|
4
4
|
config_string("strict_warnflags") {|w| $warnflags += " #{w}"}
|
|
5
5
|
|
|
6
|
+
unless try_compile("", "", werror: true)
|
|
7
|
+
append_cflags("-Wno-default-const-init-field-unsafe")
|
|
8
|
+
end
|
|
6
9
|
append_cflags("-Wno-compound-token-split-by-macro") if RUBY_VERSION < "2.7."
|
|
7
10
|
have_func("rb_category_warn")
|
|
8
11
|
with_werror("", {:werror => true}) do |opt, |
|
|
@@ -10,4 +13,7 @@ with_werror("", {:werror => true}) do |opt, |
|
|
|
10
13
|
have_var("altzone", "time.h", opt)
|
|
11
14
|
end
|
|
12
15
|
|
|
16
|
+
have_func("rb_gc_mark_movable", "ruby.h") # RUBY_VERSION >= 2.7
|
|
17
|
+
have_const("RUBY_TYPED_EMBEDDABLE", "ruby.h") # RUBY_VERSION >= 3.3
|
|
18
|
+
|
|
13
19
|
create_makefile('date_core')
|
data/lib/date.rb
CHANGED
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.
|
|
4
|
+
version: 3.6.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:
|
|
11
|
+
date: 2026-10-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: The official date library for Ruby.
|
|
14
14
|
email:
|