date 3.3.0 → 3.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ">="
|