date 3.3.0 → 3.3.3
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 +152 -1
- data/ext/date/date_strptime.c +51 -54
- data/lib/date.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ccf42407789dcdf94598ab68332e1860f4f2b5f5820d7b2b2bd8ae283088160
|
4
|
+
data.tar.gz: 988c7bded5cb20a4b68283216eeaaddf874a15765705919fe372bdeaf58d1c2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f99b7157afc55d925ffe6ea0f786ce4dc377a30786bb8045b71019db65cd056c83edbd4a979925060ed0daaae2f0cc71f19c04d0b89df53b6a39c70ad6005457
|
7
|
+
data.tar.gz: d4d955554151f00b3e0db05cf684d5e7c47655654fd3174aa3e1c67b14a9fa8696092219eac5e540ae9d9abe8c05b06e13bb4ff74c754c33b7e075e9b5498597
|
data/ext/date/date_core.c
CHANGED
@@ -27,6 +27,10 @@ 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
|
+
// used by deconstruct_keys
|
31
|
+
static VALUE sym_year, sym_month, sym_day, sym_yday, sym_wday;
|
32
|
+
static VALUE sym_hour, sym_min, sym_sec, sym_sec_fraction, sym_zone;
|
33
|
+
|
30
34
|
#define f_boolcast(x) ((x) ? Qtrue : Qfalse)
|
31
35
|
|
32
36
|
#define f_abs(x) rb_funcall(x, rb_intern("abs"), 0)
|
@@ -60,7 +64,8 @@ static VALUE datetime_initialize(int argc, VALUE *argv, VALUE self);
|
|
60
64
|
|
61
65
|
#define RETURN_FALSE_UNLESS_NUMERIC(obj) if(!RTEST(rb_obj_is_kind_of((obj), rb_cNumeric))) return Qfalse
|
62
66
|
inline static void
|
63
|
-
check_numeric(VALUE obj, const char* field)
|
67
|
+
check_numeric(VALUE obj, const char* field)
|
68
|
+
{
|
64
69
|
if(!RTEST(rb_obj_is_kind_of(obj, rb_cNumeric))) {
|
65
70
|
rb_raise(rb_eTypeError, "invalid %s (not numeric)", field);
|
66
71
|
}
|
@@ -7432,6 +7437,96 @@ d_lite_jisx0301(VALUE self)
|
|
7432
7437
|
return strftimev(fmt, self, set_tmx);
|
7433
7438
|
}
|
7434
7439
|
|
7440
|
+
static VALUE
|
7441
|
+
deconstruct_keys(VALUE self, VALUE keys, int is_datetime)
|
7442
|
+
{
|
7443
|
+
VALUE h = rb_hash_new();
|
7444
|
+
long i;
|
7445
|
+
|
7446
|
+
get_d1(self);
|
7447
|
+
|
7448
|
+
if (NIL_P(keys)) {
|
7449
|
+
rb_hash_aset(h, sym_year, m_real_year(dat));
|
7450
|
+
rb_hash_aset(h, sym_month, INT2FIX(m_mon(dat)));
|
7451
|
+
rb_hash_aset(h, sym_day, INT2FIX(m_mday(dat)));
|
7452
|
+
rb_hash_aset(h, sym_yday, INT2FIX(m_yday(dat)));
|
7453
|
+
rb_hash_aset(h, sym_wday, INT2FIX(m_wday(dat)));
|
7454
|
+
if (is_datetime) {
|
7455
|
+
rb_hash_aset(h, sym_hour, INT2FIX(m_hour(dat)));
|
7456
|
+
rb_hash_aset(h, sym_min, INT2FIX(m_min(dat)));
|
7457
|
+
rb_hash_aset(h, sym_sec, INT2FIX(m_sec(dat)));
|
7458
|
+
rb_hash_aset(h, sym_sec_fraction, m_sf_in_sec(dat));
|
7459
|
+
rb_hash_aset(h, sym_zone, m_zone(dat));
|
7460
|
+
}
|
7461
|
+
|
7462
|
+
return h;
|
7463
|
+
}
|
7464
|
+
if (!RB_TYPE_P(keys, T_ARRAY)) {
|
7465
|
+
rb_raise(rb_eTypeError,
|
7466
|
+
"wrong argument type %"PRIsVALUE" (expected Array or nil)",
|
7467
|
+
rb_obj_class(keys));
|
7468
|
+
|
7469
|
+
}
|
7470
|
+
|
7471
|
+
for (i=0; i<RARRAY_LEN(keys); i++) {
|
7472
|
+
VALUE key = RARRAY_AREF(keys, i);
|
7473
|
+
|
7474
|
+
if (sym_year == key) rb_hash_aset(h, key, m_real_year(dat));
|
7475
|
+
if (sym_month == key) rb_hash_aset(h, key, INT2FIX(m_mon(dat)));
|
7476
|
+
if (sym_day == key) rb_hash_aset(h, key, INT2FIX(m_mday(dat)));
|
7477
|
+
if (sym_yday == key) rb_hash_aset(h, key, INT2FIX(m_yday(dat)));
|
7478
|
+
if (sym_wday == key) rb_hash_aset(h, key, INT2FIX(m_wday(dat)));
|
7479
|
+
if (is_datetime) {
|
7480
|
+
if (sym_hour == key) rb_hash_aset(h, key, INT2FIX(m_hour(dat)));
|
7481
|
+
if (sym_min == key) rb_hash_aset(h, key, INT2FIX(m_min(dat)));
|
7482
|
+
if (sym_sec == key) rb_hash_aset(h, key, INT2FIX(m_sec(dat)));
|
7483
|
+
if (sym_sec_fraction == key) rb_hash_aset(h, key, m_sf_in_sec(dat));
|
7484
|
+
if (sym_zone == key) rb_hash_aset(h, key, m_zone(dat));
|
7485
|
+
}
|
7486
|
+
}
|
7487
|
+
return h;
|
7488
|
+
}
|
7489
|
+
|
7490
|
+
/*
|
7491
|
+
* call-seq:
|
7492
|
+
* deconstruct_keys(array_of_names_or_nil) -> hash
|
7493
|
+
*
|
7494
|
+
* Returns a hash of the name/value pairs, to use in pattern matching.
|
7495
|
+
* Possible keys are: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
|
7496
|
+
* <tt>:wday</tt>, <tt>:yday</tt>.
|
7497
|
+
*
|
7498
|
+
* Possible usages:
|
7499
|
+
*
|
7500
|
+
* d = Date.new(2022, 10, 5)
|
7501
|
+
*
|
7502
|
+
* if d in wday: 3, day: ..7 # uses deconstruct_keys underneath
|
7503
|
+
* puts "first Wednesday of the month"
|
7504
|
+
* end
|
7505
|
+
* #=> prints "first Wednesday of the month"
|
7506
|
+
*
|
7507
|
+
* case d
|
7508
|
+
* in year: ...2022
|
7509
|
+
* puts "too old"
|
7510
|
+
* in month: ..9
|
7511
|
+
* puts "quarter 1-3"
|
7512
|
+
* in wday: 1..5, month:
|
7513
|
+
* puts "working day in month #{month}"
|
7514
|
+
* end
|
7515
|
+
* #=> prints "working day in month 10"
|
7516
|
+
*
|
7517
|
+
* Note that deconstruction by pattern can also be combined with class check:
|
7518
|
+
*
|
7519
|
+
* if d in Date(wday: 3, day: ..7)
|
7520
|
+
* puts "first Wednesday of the month"
|
7521
|
+
* end
|
7522
|
+
*
|
7523
|
+
*/
|
7524
|
+
static VALUE
|
7525
|
+
d_lite_deconstruct_keys(VALUE self, VALUE keys)
|
7526
|
+
{
|
7527
|
+
return deconstruct_keys(self, keys, /* is_datetime=false */ 0);
|
7528
|
+
}
|
7529
|
+
|
7435
7530
|
#ifndef NDEBUG
|
7436
7531
|
/* :nodoc: */
|
7437
7532
|
static VALUE
|
@@ -8740,6 +8835,47 @@ dt_lite_jisx0301(int argc, VALUE *argv, VALUE self)
|
|
8740
8835
|
iso8601_timediv(self, n));
|
8741
8836
|
}
|
8742
8837
|
|
8838
|
+
/*
|
8839
|
+
* call-seq:
|
8840
|
+
* deconstruct_keys(array_of_names_or_nil) -> hash
|
8841
|
+
*
|
8842
|
+
* Returns a hash of the name/value pairs, to use in pattern matching.
|
8843
|
+
* Possible keys are: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
|
8844
|
+
* <tt>:wday</tt>, <tt>:yday</tt>, <tt>:hour</tt>, <tt>:min</tt>,
|
8845
|
+
* <tt>:sec</tt>, <tt>:sec_fraction</tt>, <tt>:zone</tt>.
|
8846
|
+
*
|
8847
|
+
* Possible usages:
|
8848
|
+
*
|
8849
|
+
* dt = DateTime.new(2022, 10, 5, 13, 30)
|
8850
|
+
*
|
8851
|
+
* if d in wday: 1..5, hour: 10..18 # uses deconstruct_keys underneath
|
8852
|
+
* puts "Working time"
|
8853
|
+
* end
|
8854
|
+
* #=> prints "Working time"
|
8855
|
+
*
|
8856
|
+
* case dt
|
8857
|
+
* in year: ...2022
|
8858
|
+
* puts "too old"
|
8859
|
+
* in month: ..9
|
8860
|
+
* puts "quarter 1-3"
|
8861
|
+
* in wday: 1..5, month:
|
8862
|
+
* puts "working day in month #{month}"
|
8863
|
+
* end
|
8864
|
+
* #=> prints "working day in month 10"
|
8865
|
+
*
|
8866
|
+
* Note that deconstruction by pattern can also be combined with class check:
|
8867
|
+
*
|
8868
|
+
* if d in DateTime(wday: 1..5, hour: 10..18, day: ..7)
|
8869
|
+
* puts "Working time, first week of the month"
|
8870
|
+
* end
|
8871
|
+
*
|
8872
|
+
*/
|
8873
|
+
static VALUE
|
8874
|
+
dt_lite_deconstruct_keys(VALUE self, VALUE keys)
|
8875
|
+
{
|
8876
|
+
return deconstruct_keys(self, keys, /* is_datetime=true */ 1);
|
8877
|
+
}
|
8878
|
+
|
8743
8879
|
/* conversions */
|
8744
8880
|
|
8745
8881
|
#define f_subsec(x) rb_funcall(x, rb_intern("subsec"), 0)
|
@@ -9370,6 +9506,17 @@ Init_date_core(void)
|
|
9370
9506
|
id_ge_p = rb_intern_const(">=");
|
9371
9507
|
id_eqeq_p = rb_intern_const("==");
|
9372
9508
|
|
9509
|
+
sym_year = ID2SYM(rb_intern_const("year"));
|
9510
|
+
sym_month = ID2SYM(rb_intern_const("month"));
|
9511
|
+
sym_yday = ID2SYM(rb_intern_const("yday"));
|
9512
|
+
sym_wday = ID2SYM(rb_intern_const("wday"));
|
9513
|
+
sym_day = ID2SYM(rb_intern_const("day"));
|
9514
|
+
sym_hour = ID2SYM(rb_intern_const("hour"));
|
9515
|
+
sym_min = ID2SYM(rb_intern_const("min"));
|
9516
|
+
sym_sec = ID2SYM(rb_intern_const("sec"));
|
9517
|
+
sym_sec_fraction = ID2SYM(rb_intern_const("sec_fraction"));
|
9518
|
+
sym_zone = ID2SYM(rb_intern_const("zone"));
|
9519
|
+
|
9373
9520
|
half_days_in_day = rb_rational_new2(INT2FIX(1), INT2FIX(2));
|
9374
9521
|
|
9375
9522
|
#if (LONG_MAX / DAY_IN_SECONDS) > SECOND_IN_NANOSECONDS
|
@@ -9691,6 +9838,8 @@ Init_date_core(void)
|
|
9691
9838
|
rb_define_method(cDate, "httpdate", d_lite_httpdate, 0);
|
9692
9839
|
rb_define_method(cDate, "jisx0301", d_lite_jisx0301, 0);
|
9693
9840
|
|
9841
|
+
rb_define_method(cDate, "deconstruct_keys", d_lite_deconstruct_keys, 1);
|
9842
|
+
|
9694
9843
|
#ifndef NDEBUG
|
9695
9844
|
rb_define_method(cDate, "marshal_dump_old", d_lite_marshal_dump_old, 0);
|
9696
9845
|
#endif
|
@@ -9901,6 +10050,8 @@ Init_date_core(void)
|
|
9901
10050
|
rb_define_method(cDateTime, "rfc3339", dt_lite_rfc3339, -1);
|
9902
10051
|
rb_define_method(cDateTime, "jisx0301", dt_lite_jisx0301, -1);
|
9903
10052
|
|
10053
|
+
rb_define_method(cDateTime, "deconstruct_keys", dt_lite_deconstruct_keys, 1);
|
10054
|
+
|
9904
10055
|
/* conversions */
|
9905
10056
|
|
9906
10057
|
rb_define_method(rb_cTime, "to_time", time_to_time, 0);
|
data/ext/date/date_strptime.c
CHANGED
@@ -10,28 +10,15 @@
|
|
10
10
|
static const char *day_names[] = {
|
11
11
|
"Sunday", "Monday", "Tuesday", "Wednesday",
|
12
12
|
"Thursday", "Friday", "Saturday",
|
13
|
-
"Sun", "Mon", "Tue", "Wed",
|
14
|
-
"Thu", "Fri", "Sat"
|
15
13
|
};
|
14
|
+
static const int ABBREVIATED_DAY_NAME_LENGTH = 3;
|
16
15
|
|
17
16
|
static const char *month_names[] = {
|
18
17
|
"January", "February", "March", "April",
|
19
18
|
"May", "June", "July", "August", "September",
|
20
19
|
"October", "November", "December",
|
21
|
-
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
22
|
-
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
23
|
-
};
|
24
|
-
|
25
|
-
static const char *merid_names[] = {
|
26
|
-
"am", "pm",
|
27
|
-
"a.m.", "p.m."
|
28
|
-
};
|
29
|
-
|
30
|
-
static const char *extz_pats[] = {
|
31
|
-
":z",
|
32
|
-
"::z",
|
33
|
-
":::z"
|
34
20
|
};
|
21
|
+
static const int ABBREVIATED_MONTH_NAME_LENGTH = 3;
|
35
22
|
|
36
23
|
#define sizeof_array(o) (sizeof o / sizeof o[0])
|
37
24
|
|
@@ -75,7 +62,7 @@ num_pattern_p(const char *s)
|
|
75
62
|
#define NUM_PATTERN_P() num_pattern_p(&fmt[fi + 1])
|
76
63
|
|
77
64
|
static long
|
78
|
-
read_digits(const char *s, VALUE *n, size_t width)
|
65
|
+
read_digits(const char *s, size_t slen, VALUE *n, size_t width)
|
79
66
|
{
|
80
67
|
size_t l;
|
81
68
|
|
@@ -83,7 +70,7 @@ read_digits(const char *s, VALUE *n, size_t width)
|
|
83
70
|
return 0;
|
84
71
|
|
85
72
|
l = 0;
|
86
|
-
while (ISDIGIT(s[l])) {
|
73
|
+
while (l < slen && ISDIGIT(s[l])) {
|
87
74
|
if (++l == width) break;
|
88
75
|
}
|
89
76
|
|
@@ -131,7 +118,7 @@ do { \
|
|
131
118
|
#define READ_DIGITS(n,w) \
|
132
119
|
do { \
|
133
120
|
size_t l; \
|
134
|
-
l = read_digits(&str[si], &n, w); \
|
121
|
+
l = read_digits(&str[si], slen - si, &n, w); \
|
135
122
|
if (l == 0) \
|
136
123
|
fail(); \
|
137
124
|
si += l; \
|
@@ -161,6 +148,12 @@ do { \
|
|
161
148
|
|
162
149
|
VALUE date_zone_to_diff(VALUE);
|
163
150
|
|
151
|
+
static inline int
|
152
|
+
head_match_p(size_t len, const char *name, const char *str, size_t slen, size_t si)
|
153
|
+
{
|
154
|
+
return slen - si >= len && strncasecmp(name, &str[si], len) == 0;
|
155
|
+
}
|
156
|
+
|
164
157
|
static size_t
|
165
158
|
date__strptime_internal(const char *str, size_t slen,
|
166
159
|
const char *fmt, size_t flen, VALUE hash)
|
@@ -168,9 +161,18 @@ date__strptime_internal(const char *str, size_t slen,
|
|
168
161
|
size_t si, fi;
|
169
162
|
int c;
|
170
163
|
|
164
|
+
#define HEAD_MATCH_P(len, name) head_match_p(len, name, str, slen, si)
|
171
165
|
si = fi = 0;
|
172
166
|
|
173
167
|
while (fi < flen) {
|
168
|
+
if (isspace((unsigned char)fmt[fi])) {
|
169
|
+
while (si < slen && isspace((unsigned char)str[si]))
|
170
|
+
si++;
|
171
|
+
while (++fi < flen && isspace((unsigned char)fmt[fi]));
|
172
|
+
continue;
|
173
|
+
}
|
174
|
+
|
175
|
+
if (si >= slen) fail();
|
174
176
|
|
175
177
|
switch (fmt[fi]) {
|
176
178
|
case '%':
|
@@ -194,12 +196,11 @@ date__strptime_internal(const char *str, size_t slen,
|
|
194
196
|
{
|
195
197
|
int i;
|
196
198
|
|
197
|
-
for (i =
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
}
|
199
|
+
for (i = 1; i < 3 && fi + i < flen && fmt[fi+i] == ':'; ++i);
|
200
|
+
if (fmt[fi+i] == 'z') {
|
201
|
+
fi += i - 1;
|
202
|
+
goto again;
|
203
|
+
}
|
203
204
|
fail();
|
204
205
|
}
|
205
206
|
|
@@ -209,10 +210,12 @@ date__strptime_internal(const char *str, size_t slen,
|
|
209
210
|
int i;
|
210
211
|
|
211
212
|
for (i = 0; i < (int)sizeof_array(day_names); i++) {
|
212
|
-
|
213
|
-
|
213
|
+
const char *day_name = day_names[i];
|
214
|
+
size_t l = strlen(day_name);
|
215
|
+
if (HEAD_MATCH_P(l, day_name) ||
|
216
|
+
HEAD_MATCH_P(l = ABBREVIATED_DAY_NAME_LENGTH, day_name)) {
|
214
217
|
si += l;
|
215
|
-
set_hash("wday", INT2FIX(i
|
218
|
+
set_hash("wday", INT2FIX(i));
|
216
219
|
goto matched;
|
217
220
|
}
|
218
221
|
}
|
@@ -225,10 +228,12 @@ date__strptime_internal(const char *str, size_t slen,
|
|
225
228
|
int i;
|
226
229
|
|
227
230
|
for (i = 0; i < (int)sizeof_array(month_names); i++) {
|
228
|
-
|
229
|
-
|
231
|
+
const char *month_name = month_names[i];
|
232
|
+
size_t l = strlen(month_name);
|
233
|
+
if (HEAD_MATCH_P(l, month_name) ||
|
234
|
+
HEAD_MATCH_P(l = ABBREVIATED_MONTH_NAME_LENGTH, month_name)) {
|
230
235
|
si += l;
|
231
|
-
set_hash("mon", INT2FIX(
|
236
|
+
set_hash("mon", INT2FIX(i + 1));
|
232
237
|
goto matched;
|
233
238
|
}
|
234
239
|
}
|
@@ -402,18 +407,19 @@ date__strptime_internal(const char *str, size_t slen,
|
|
402
407
|
|
403
408
|
case 'P':
|
404
409
|
case 'p':
|
410
|
+
if (slen - si < 2) fail();
|
405
411
|
{
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
if (
|
411
|
-
|
412
|
-
set_hash("_merid", INT2FIX((i % 2) == 0 ? 0 : 12));
|
413
|
-
goto matched;
|
414
|
-
}
|
412
|
+
char c = str[si];
|
413
|
+
const int hour = (c == 'P' || c == 'p') ? 12 : 0;
|
414
|
+
if (!hour && !(c == 'A' || c == 'a')) fail();
|
415
|
+
if ((c = str[si+1]) == '.') {
|
416
|
+
if (slen - si < 4 || str[si+3] != '.') fail();
|
417
|
+
c = str[si += 2];
|
415
418
|
}
|
416
|
-
fail();
|
419
|
+
if (!(c == 'M' || c == 'm')) fail();
|
420
|
+
si += 2;
|
421
|
+
set_hash("_merid", INT2FIX(hour));
|
422
|
+
goto matched;
|
417
423
|
}
|
418
424
|
|
419
425
|
case 'Q':
|
@@ -587,7 +593,7 @@ date__strptime_internal(const char *str, size_t slen,
|
|
587
593
|
|
588
594
|
b = rb_backref_get();
|
589
595
|
rb_match_busy(b);
|
590
|
-
m = f_match(pat,
|
596
|
+
m = f_match(pat, rb_usascii_str_new(&str[si], slen - si));
|
591
597
|
|
592
598
|
if (!NIL_P(m)) {
|
593
599
|
VALUE s, l, o;
|
@@ -619,22 +625,13 @@ date__strptime_internal(const char *str, size_t slen,
|
|
619
625
|
if (str[si] != '%')
|
620
626
|
fail();
|
621
627
|
si++;
|
622
|
-
if (fi < flen)
|
623
|
-
if (str[si] != fmt[fi])
|
628
|
+
if (fi < flen) {
|
629
|
+
if (si >= slen || str[si] != fmt[fi])
|
624
630
|
fail();
|
625
|
-
|
631
|
+
si++;
|
632
|
+
}
|
626
633
|
goto matched;
|
627
634
|
}
|
628
|
-
case ' ':
|
629
|
-
case '\t':
|
630
|
-
case '\n':
|
631
|
-
case '\v':
|
632
|
-
case '\f':
|
633
|
-
case '\r':
|
634
|
-
while (isspace((unsigned char)str[si]))
|
635
|
-
si++;
|
636
|
-
fi++;
|
637
|
-
break;
|
638
635
|
default:
|
639
636
|
ordinal:
|
640
637
|
if (str[si] != fmt[fi])
|
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.3.
|
4
|
+
version: 3.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tadayoshi Funaba
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-12-
|
11
|
+
date: 2022-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A subclass of Object includes Comparable module for handling dates.
|
14
14
|
email:
|
@@ -42,7 +42,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
42
|
requirements:
|
43
43
|
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 2.
|
45
|
+
version: 2.6.0
|
46
46
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
47
|
requirements:
|
48
48
|
- - ">="
|