date 1.0.0 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of date might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0fa112c995a20e5310b0d736088be7c3abc5b3a6de817b4d511f65c957d6949e
4
- data.tar.gz: ed868848f6cfa0f172296a511d1f1fe82e833ac469d4ba342ff8bd8f208ffc1a
3
+ metadata.gz: 023fa4cf6c7f68a0f3dc03031ad864c1fe3f748234c20e1bffc1ee2cc9b41ae8
4
+ data.tar.gz: 7851c6cccbc8275113236208e093689f62882abf40ff5c7911ca146597d8457a
5
5
  SHA512:
6
- metadata.gz: cf7d8b67c199e8d4619893d5a4933663d64996a10d5baaf7381c6c9fe673cfed15d7ad04ff4df039f0704344568d5af2a469679cc670b208f3634125c456ba11
7
- data.tar.gz: 9ce68c93915cf79ecddf6ed8a705b15fdc0a3555491e60dcc5ea7c8db7fb894adc5d8fc01e1c3247cb68012e9ff4d10f9d8621ddadb486a032ea5418d3a15248
6
+ metadata.gz: 763d8778816f56ec3f5c2dd8cc81f5ba1c07c9adc4216156faf10170276bd15c07dda24313e4925e4003e7aeb399a8115fe68129d3b3d10833d65443e9de760d
7
+ data.tar.gz: c5bb10ba72106dcdb7363fb988e38cb542c27a09dfc19b878966184750845da6e80f7033feb57e72dd9cf1ec23dd4cf0788d765e1f596fe7961dbcaec7905711
@@ -11,6 +11,7 @@
11
11
  #include <sys/time.h>
12
12
  #endif
13
13
 
14
+ #undef NDEBUG
14
15
  #define NDEBUG
15
16
  #include <assert.h>
16
17
 
@@ -22,6 +23,7 @@
22
23
 
23
24
  static ID id_cmp, id_le_p, id_ge_p, id_eqeq_p;
24
25
  static VALUE cDate, cDateTime;
26
+ static VALUE eDateError;
25
27
  static VALUE half_days_in_day, day_in_nanoseconds;
26
28
  static double positive_inf, negative_inf;
27
29
 
@@ -51,18 +53,31 @@ static double positive_inf, negative_inf;
51
53
  #define f_add3(x,y,z) f_add(f_add(x, y), z)
52
54
  #define f_sub3(x,y,z) f_sub(f_sub(x, y), z)
53
55
 
54
- inline static VALUE
56
+ #define f_frozen_ary(...) rb_obj_freeze(rb_ary_new3(__VA_ARGS__))
57
+
58
+ static VALUE date_initialize(int argc, VALUE *argv, VALUE self);
59
+ static VALUE datetime_initialize(int argc, VALUE *argv, VALUE self);
60
+
61
+ #define RETURN_FALSE_UNLESS_NUMERIC(obj) if(!RTEST(rb_obj_is_kind_of((obj), rb_cNumeric))) return Qfalse
62
+ inline static void
63
+ check_numeric(VALUE obj, const char* field) {
64
+ if(!RTEST(rb_obj_is_kind_of(obj, rb_cNumeric))) {
65
+ rb_raise(rb_eTypeError, "invalid %s (not numeric)", field);
66
+ }
67
+ }
68
+
69
+ inline static int
55
70
  f_cmp(VALUE x, VALUE y)
56
71
  {
57
72
  if (FIXNUM_P(x) && FIXNUM_P(y)) {
58
73
  long c = FIX2LONG(x) - FIX2LONG(y);
59
74
  if (c > 0)
60
- c = 1;
75
+ return 1;
61
76
  else if (c < 0)
62
- c = -1;
63
- return INT2FIX(c);
77
+ return -1;
78
+ return 0;
64
79
  }
65
- return rb_funcall(x, id_cmp, 1, y);
80
+ return rb_cmpint(rb_funcallv(x, id_cmp, 1, &y), x, y);
66
81
  }
67
82
 
68
83
  inline static VALUE
@@ -94,7 +109,7 @@ f_ge_p(VALUE x, VALUE y)
94
109
  {
95
110
  if (FIXNUM_P(x) && FIXNUM_P(y))
96
111
  return f_boolcast(FIX2LONG(x) >= FIX2LONG(y));
97
- return rb_funcall(x, rb_intern(">="), 1, y);
112
+ return rb_funcall(x, id_ge_p, 1, y);
98
113
  }
99
114
 
100
115
  inline static VALUE
@@ -102,7 +117,7 @@ f_eqeq_p(VALUE x, VALUE y)
102
117
  {
103
118
  if (FIXNUM_P(x) && FIXNUM_P(y))
104
119
  return f_boolcast(FIX2LONG(x) == FIX2LONG(y));
105
- return rb_funcall(x, rb_intern("=="), 1, y);
120
+ return rb_funcall(x, id_eqeq_p, 1, y);
106
121
  }
107
122
 
108
123
  inline static VALUE
@@ -236,11 +251,8 @@ f_negative_p(VALUE x)
236
251
  struct SimpleDateData
237
252
  {
238
253
  unsigned flags;
239
- VALUE nth; /* not always canonicalized */
240
254
  int jd; /* as utc */
241
- /* df is zero */
242
- /* sf is zero */
243
- /* of is zero */
255
+ VALUE nth; /* not always canonicalized */
244
256
  date_sg_t sg; /* 2298874..2426355 or -/+oo -- at most 22 bits */
245
257
  /* decoded as utc=local */
246
258
  int year; /* truncated */
@@ -259,11 +271,8 @@ struct SimpleDateData
259
271
  struct ComplexDateData
260
272
  {
261
273
  unsigned flags;
262
- VALUE nth; /* not always canonicalized */
263
274
  int jd; /* as utc */
264
- int df; /* as utc, in secs */
265
- VALUE sf; /* in nano secs */
266
- int of; /* in secs */
275
+ VALUE nth; /* not always canonicalized */
267
276
  date_sg_t sg; /* 2298874..2426355 or -/+oo -- at most 22 bits */
268
277
  /* decoded as local */
269
278
  int year; /* truncated */
@@ -277,6 +286,9 @@ struct ComplexDateData
277
286
  /* packed civil */
278
287
  unsigned pc;
279
288
  #endif
289
+ int df; /* as utc, in secs */
290
+ int of; /* in secs */
291
+ VALUE sf; /* in nano secs */
280
292
  };
281
293
 
282
294
  union DateData {
@@ -315,31 +327,31 @@ canon(VALUE x)
315
327
 
316
328
  #ifndef USE_PACK
317
329
  #define set_to_simple(obj, x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \
318
- {\
330
+ do {\
319
331
  RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth)); \
320
332
  (x)->jd = _jd;\
321
333
  (x)->sg = (date_sg_t)(_sg);\
322
334
  (x)->year = _year;\
323
335
  (x)->mon = _mon;\
324
336
  (x)->mday = _mday;\
325
- (x)->flags = _flags;\
326
- }
337
+ (x)->flags = (_flags) & ~COMPLEX_DAT;\
338
+ } while (0)
327
339
  #else
328
340
  #define set_to_simple(obj, x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \
329
- {\
341
+ do {\
330
342
  RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth)); \
331
343
  (x)->jd = _jd;\
332
344
  (x)->sg = (date_sg_t)(_sg);\
333
345
  (x)->year = _year;\
334
346
  (x)->pc = PACK2(_mon, _mday);\
335
- (x)->flags = _flags;\
336
- }
347
+ (x)->flags = (_flags) & ~COMPLEX_DAT;\
348
+ } while (0)
337
349
  #endif
338
350
 
339
351
  #ifndef USE_PACK
340
352
  #define set_to_complex(obj, x, _nth, _jd ,_df, _sf, _of, _sg,\
341
353
  _year, _mon, _mday, _hour, _min, _sec, _flags) \
342
- {\
354
+ do {\
343
355
  RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth));\
344
356
  (x)->jd = _jd;\
345
357
  (x)->df = _df;\
@@ -352,12 +364,12 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
352
364
  (x)->hour = _hour;\
353
365
  (x)->min = _min;\
354
366
  (x)->sec = _sec;\
355
- (x)->flags = _flags;\
356
- }
367
+ (x)->flags = (_flags) | COMPLEX_DAT;\
368
+ } while (0)
357
369
  #else
358
370
  #define set_to_complex(obj, x, _nth, _jd ,_df, _sf, _of, _sg,\
359
371
  _year, _mon, _mday, _hour, _min, _sec, _flags) \
360
- {\
372
+ do {\
361
373
  RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth));\
362
374
  (x)->jd = _jd;\
363
375
  (x)->df = _df;\
@@ -366,13 +378,13 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
366
378
  (x)->sg = (date_sg_t)(_sg);\
367
379
  (x)->year = _year;\
368
380
  (x)->pc = PACK5(_mon, _mday, _hour, _min, _sec);\
369
- (x)->flags = _flags;\
370
- }
381
+ (x)->flags = (_flags) | COMPLEX_DAT;\
382
+ } while (0)
371
383
  #endif
372
384
 
373
385
  #ifndef USE_PACK
374
386
  #define copy_simple_to_complex(obj, x, y) \
375
- {\
387
+ do {\
376
388
  RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\
377
389
  (x)->jd = (y)->jd;\
378
390
  (x)->df = 0;\
@@ -386,10 +398,10 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
386
398
  (x)->min = 0;\
387
399
  (x)->sec = 0;\
388
400
  (x)->flags = (y)->flags;\
389
- }
401
+ } while (0)
390
402
  #else
391
403
  #define copy_simple_to_complex(obj, x, y) \
392
- {\
404
+ do {\
393
405
  RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\
394
406
  (x)->jd = (y)->jd;\
395
407
  (x)->df = 0;\
@@ -399,12 +411,12 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
399
411
  (x)->year = (y)->year;\
400
412
  (x)->pc = PACK5(EX_MON((y)->pc), EX_MDAY((y)->pc), 0, 0, 0);\
401
413
  (x)->flags = (y)->flags;\
402
- }
414
+ } while (0)
403
415
  #endif
404
416
 
405
417
  #ifndef USE_PACK
406
418
  #define copy_complex_to_simple(obj, x, y) \
407
- {\
419
+ do {\
408
420
  RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\
409
421
  (x)->jd = (y)->jd;\
410
422
  (x)->sg = (date_sg_t)((y)->sg);\
@@ -412,17 +424,17 @@ _year, _mon, _mday, _hour, _min, _sec, _flags) \
412
424
  (x)->mon = (y)->mon;\
413
425
  (x)->mday = (y)->mday;\
414
426
  (x)->flags = (y)->flags;\
415
- }
427
+ } while (0)
416
428
  #else
417
429
  #define copy_complex_to_simple(obj, x, y) \
418
- {\
430
+ do {\
419
431
  RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\
420
432
  (x)->jd = (y)->jd;\
421
433
  (x)->sg = (date_sg_t)((y)->sg);\
422
434
  (x)->year = (y)->year;\
423
435
  (x)->pc = PACK2(EX_MON((y)->pc), EX_MDAY((y)->pc));\
424
436
  (x)->flags = (y)->flags;\
425
- }
437
+ } while (0)
426
438
  #endif
427
439
 
428
440
  /* base */
@@ -1109,7 +1121,7 @@ m_virtual_sg(union DateData *x)
1109
1121
  }
1110
1122
 
1111
1123
  #define canonicalize_jd(_nth, _jd) \
1112
- {\
1124
+ do {\
1113
1125
  if (_jd < 0) {\
1114
1126
  _nth = f_sub(_nth, INT2FIX(1));\
1115
1127
  _jd += CM_PERIOD;\
@@ -1118,7 +1130,7 @@ m_virtual_sg(union DateData *x)
1118
1130
  _nth = f_add(_nth, INT2FIX(1));\
1119
1131
  _jd -= CM_PERIOD;\
1120
1132
  }\
1121
- }
1133
+ } while (0)
1122
1134
 
1123
1135
  inline static void
1124
1136
  canonicalize_s_jd(VALUE obj, union DateData *x)
@@ -1928,13 +1940,13 @@ m_sec(union DateData *x)
1928
1940
  }
1929
1941
 
1930
1942
  #define decode_offset(of,s,h,m)\
1931
- {\
1943
+ do {\
1932
1944
  int a;\
1933
1945
  s = (of < 0) ? '-' : '+';\
1934
1946
  a = (of < 0) ? -of : of;\
1935
1947
  h = a / HOUR_IN_SECONDS;\
1936
1948
  m = a % HOUR_IN_SECONDS / MINUTE_IN_SECONDS;\
1937
- }
1949
+ } while (0)
1938
1950
 
1939
1951
  static VALUE
1940
1952
  of2str(int of)
@@ -2333,6 +2345,9 @@ VALUE date_zone_to_diff(VALUE);
2333
2345
  static int
2334
2346
  offset_to_sec(VALUE vof, int *rof)
2335
2347
  {
2348
+ int try_rational = 1;
2349
+
2350
+ again:
2336
2351
  switch (TYPE(vof)) {
2337
2352
  case T_FIXNUM:
2338
2353
  {
@@ -2359,10 +2374,11 @@ offset_to_sec(VALUE vof, int *rof)
2359
2374
  default:
2360
2375
  expect_numeric(vof);
2361
2376
  vof = f_to_r(vof);
2362
- #ifdef CANONICALIZATION_FOR_MATHN
2363
- if (!k_rational_p(vof))
2364
- return offset_to_sec(vof, rof);
2365
- #endif
2377
+ if (!k_rational_p(vof)) {
2378
+ if (!try_rational) Check_Type(vof, T_RATIONAL);
2379
+ try_rational = 0;
2380
+ goto again;
2381
+ }
2366
2382
  /* fall through */
2367
2383
  case T_RATIONAL:
2368
2384
  {
@@ -2371,17 +2387,10 @@ offset_to_sec(VALUE vof, int *rof)
2371
2387
 
2372
2388
  vs = day_to_sec(vof);
2373
2389
 
2374
- #ifdef CANONICALIZATION_FOR_MATHN
2375
2390
  if (!k_rational_p(vs)) {
2376
- if (!FIXNUM_P(vs))
2377
- return 0;
2378
- n = FIX2LONG(vs);
2379
- if (n < -DAY_IN_SECONDS || n > DAY_IN_SECONDS)
2380
- return 0;
2381
- *rof = (int)n;
2382
- return 1;
2391
+ vn = vs;
2392
+ goto rounded;
2383
2393
  }
2384
- #endif
2385
2394
  vn = rb_rational_num(vs);
2386
2395
  vd = rb_rational_den(vs);
2387
2396
 
@@ -2391,6 +2400,7 @@ offset_to_sec(VALUE vof, int *rof)
2391
2400
  vn = f_round(vs);
2392
2401
  if (!f_eqeq_p(vn, vs))
2393
2402
  rb_warning("fraction of offset is ignored");
2403
+ rounded:
2394
2404
  if (!FIXNUM_P(vn))
2395
2405
  return 0;
2396
2406
  n = FIX2LONG(vn);
@@ -2420,12 +2430,12 @@ offset_to_sec(VALUE vof, int *rof)
2420
2430
  /* date */
2421
2431
 
2422
2432
  #define valid_sg(sg) \
2423
- {\
2433
+ do {\
2424
2434
  if (!c_valid_start_p(sg)) {\
2425
2435
  sg = 0;\
2426
2436
  rb_warning("invalid start is ignored");\
2427
2437
  }\
2428
- }
2438
+ } while (0)
2429
2439
 
2430
2440
  static VALUE
2431
2441
  valid_jd_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
@@ -2472,6 +2482,7 @@ date_s_valid_jd_p(int argc, VALUE *argv, VALUE klass)
2472
2482
 
2473
2483
  rb_scan_args(argc, argv, "11", &vjd, &vsg);
2474
2484
 
2485
+ RETURN_FALSE_UNLESS_NUMERIC(vjd);
2475
2486
  argv2[0] = vjd;
2476
2487
  if (argc < 2)
2477
2488
  argv2[1] = INT2FIX(DEFAULT_SG);
@@ -2547,9 +2558,12 @@ date_s__valid_civil_p(int argc, VALUE *argv, VALUE klass)
2547
2558
  * Date.valid_date?(year, month, mday[, start=Date::ITALY]) -> bool
2548
2559
  *
2549
2560
  * Returns true if the given calendar date is valid, and false if not.
2561
+ * Valid in this context is whether the arguments passed to this
2562
+ * method would be accepted by ::new.
2550
2563
  *
2551
2564
  * Date.valid_date?(2001,2,3) #=> true
2552
2565
  * Date.valid_date?(2001,2,29) #=> false
2566
+ * Date.valid_date?(2001,2,-1) #=> true
2553
2567
  *
2554
2568
  * See also ::jd and ::civil.
2555
2569
  */
@@ -2561,6 +2575,9 @@ date_s_valid_civil_p(int argc, VALUE *argv, VALUE klass)
2561
2575
 
2562
2576
  rb_scan_args(argc, argv, "31", &vy, &vm, &vd, &vsg);
2563
2577
 
2578
+ RETURN_FALSE_UNLESS_NUMERIC(vy);
2579
+ RETURN_FALSE_UNLESS_NUMERIC(vm);
2580
+ RETURN_FALSE_UNLESS_NUMERIC(vd);
2564
2581
  argv2[0] = vy;
2565
2582
  argv2[1] = vm;
2566
2583
  argv2[2] = vd;
@@ -2642,6 +2659,8 @@ date_s_valid_ordinal_p(int argc, VALUE *argv, VALUE klass)
2642
2659
 
2643
2660
  rb_scan_args(argc, argv, "21", &vy, &vd, &vsg);
2644
2661
 
2662
+ RETURN_FALSE_UNLESS_NUMERIC(vy);
2663
+ RETURN_FALSE_UNLESS_NUMERIC(vd);
2645
2664
  argv2[0] = vy;
2646
2665
  argv2[1] = vd;
2647
2666
  if (argc < 3)
@@ -2724,6 +2743,9 @@ date_s_valid_commercial_p(int argc, VALUE *argv, VALUE klass)
2724
2743
 
2725
2744
  rb_scan_args(argc, argv, "31", &vy, &vw, &vd, &vsg);
2726
2745
 
2746
+ RETURN_FALSE_UNLESS_NUMERIC(vy);
2747
+ RETURN_FALSE_UNLESS_NUMERIC(vw);
2748
+ RETURN_FALSE_UNLESS_NUMERIC(vd);
2727
2749
  argv2[0] = vy;
2728
2750
  argv2[1] = vw;
2729
2751
  argv2[2] = vd;
@@ -2905,6 +2927,7 @@ date_s_julian_leap_p(VALUE klass, VALUE y)
2905
2927
  VALUE nth;
2906
2928
  int ry;
2907
2929
 
2930
+ check_numeric(y, "year");
2908
2931
  decode_year(y, +1, &nth, &ry);
2909
2932
  return f_boolcast(c_julian_leap_p(ry));
2910
2933
  }
@@ -2926,6 +2949,7 @@ date_s_gregorian_leap_p(VALUE klass, VALUE y)
2926
2949
  VALUE nth;
2927
2950
  int ry;
2928
2951
 
2952
+ check_numeric(y, "year");
2929
2953
  decode_year(y, -1, &nth, &ry);
2930
2954
  return f_boolcast(c_gregorian_leap_p(ry));
2931
2955
  }
@@ -2949,11 +2973,15 @@ d_lite_memsize(const void *ptr)
2949
2973
  return complex_dat_p(dat) ? sizeof(struct ComplexDateData) : sizeof(struct SimpleDateData);
2950
2974
  }
2951
2975
 
2976
+ #ifndef HAVE_RB_EXT_RACTOR_SAFE
2977
+ # define RUBY_TYPED_FROZEN_SHAREABLE 0
2978
+ #endif
2979
+
2952
2980
  static const rb_data_type_t d_lite_type = {
2953
2981
  "Date",
2954
2982
  {d_lite_gc_mark, RUBY_TYPED_DEFAULT_FREE, d_lite_memsize,},
2955
2983
  0, 0,
2956
- RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED,
2984
+ RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED|RUBY_TYPED_FROZEN_SHAREABLE,
2957
2985
  };
2958
2986
 
2959
2987
  inline static VALUE
@@ -2968,7 +2996,7 @@ d_simple_new_internal(VALUE klass,
2968
2996
 
2969
2997
  obj = TypedData_Make_Struct(klass, struct SimpleDateData,
2970
2998
  &d_lite_type, dat);
2971
- set_to_simple(obj, dat, nth, jd, sg, y, m, d, flags & ~COMPLEX_DAT);
2999
+ set_to_simple(obj, dat, nth, jd, sg, y, m, d, flags);
2972
3000
 
2973
3001
  assert(have_jd_p(dat) || have_civil_p(dat));
2974
3002
 
@@ -2990,7 +3018,7 @@ d_complex_new_internal(VALUE klass,
2990
3018
  obj = TypedData_Make_Struct(klass, struct ComplexDateData,
2991
3019
  &d_lite_type, dat);
2992
3020
  set_to_complex(obj, dat, nth, jd, df, sf, of, sg,
2993
- y, m, d, h, min, s, flags | COMPLEX_DAT);
3021
+ y, m, d, h, min, s, flags);
2994
3022
 
2995
3023
  assert(have_jd_p(dat) || have_civil_p(dat));
2996
3024
  assert(have_df_p(dat) || have_time_p(dat));
@@ -3049,7 +3077,7 @@ old_to_new(VALUE ajd, VALUE of, VALUE sg,
3049
3077
  *rsg = NUM2DBL(sg);
3050
3078
 
3051
3079
  if (*rdf < 0 || *rdf >= DAY_IN_SECONDS)
3052
- rb_raise(rb_eArgError, "invalid day fraction");
3080
+ rb_raise(eDateError, "invalid day fraction");
3053
3081
 
3054
3082
  if (f_lt_p(*rsf, INT2FIX(0)) ||
3055
3083
  f_ge_p(*rsf, INT2FIX(SECOND_IN_NANOSECONDS)))
@@ -3207,47 +3235,47 @@ s_trunc(VALUE s, VALUE *fr)
3207
3235
  }
3208
3236
 
3209
3237
  #define num2num_with_frac(s,n) \
3210
- {\
3238
+ do {\
3211
3239
  s = s##_trunc(v##s, &fr);\
3212
3240
  if (f_nonzero_p(fr)) {\
3213
3241
  if (argc > n)\
3214
- rb_raise(rb_eArgError, "invalid fraction");\
3242
+ rb_raise(eDateError, "invalid fraction");\
3215
3243
  fr2 = fr;\
3216
3244
  }\
3217
- }
3245
+ } while (0)
3218
3246
 
3219
3247
  #define num2int_with_frac(s,n) \
3220
- {\
3248
+ do {\
3221
3249
  s = NUM2INT(s##_trunc(v##s, &fr));\
3222
3250
  if (f_nonzero_p(fr)) {\
3223
3251
  if (argc > n)\
3224
- rb_raise(rb_eArgError, "invalid fraction");\
3252
+ rb_raise(eDateError, "invalid fraction");\
3225
3253
  fr2 = fr;\
3226
3254
  }\
3227
- }
3255
+ } while (0)
3228
3256
 
3229
3257
  #define canon24oc() \
3230
- {\
3258
+ do {\
3231
3259
  if (rh == 24) {\
3232
3260
  rh = 0;\
3233
3261
  fr2 = f_add(fr2, INT2FIX(1));\
3234
3262
  }\
3235
- }
3263
+ } while (0)
3236
3264
 
3237
3265
  #define add_frac() \
3238
- {\
3266
+ do {\
3239
3267
  if (f_nonzero_p(fr2))\
3240
3268
  ret = d_lite_plus(ret, fr2);\
3241
- }
3269
+ } while (0)
3242
3270
 
3243
3271
  #define val2sg(vsg,dsg) \
3244
- {\
3272
+ do {\
3245
3273
  dsg = NUM2DBL(vsg);\
3246
3274
  if (!c_valid_start_p(dsg)) {\
3247
3275
  dsg = DEFAULT_SG;\
3248
3276
  rb_warning("invalid start is ignored");\
3249
3277
  }\
3250
- }
3278
+ } while (0)
3251
3279
 
3252
3280
  static VALUE d_lite_plus(VALUE, VALUE);
3253
3281
 
@@ -3280,6 +3308,7 @@ date_s_jd(int argc, VALUE *argv, VALUE klass)
3280
3308
  case 2:
3281
3309
  val2sg(vsg, sg);
3282
3310
  case 1:
3311
+ check_numeric(vjd, "jd");
3283
3312
  num2num_with_frac(jd, positive_inf);
3284
3313
  }
3285
3314
 
@@ -3332,8 +3361,10 @@ date_s_ordinal(int argc, VALUE *argv, VALUE klass)
3332
3361
  case 3:
3333
3362
  val2sg(vsg, sg);
3334
3363
  case 2:
3364
+ check_numeric(vd, "yday");
3335
3365
  num2int_with_frac(d, positive_inf);
3336
3366
  case 1:
3367
+ check_numeric(vy, "year");
3337
3368
  y = vy;
3338
3369
  }
3339
3370
 
@@ -3345,7 +3376,7 @@ date_s_ordinal(int argc, VALUE *argv, VALUE klass)
3345
3376
  &nth, &ry,
3346
3377
  &rd, &rjd,
3347
3378
  &ns))
3348
- rb_raise(rb_eArgError, "invalid date");
3379
+ rb_raise(eDateError, "invalid date");
3349
3380
 
3350
3381
  ret = d_simple_new_internal(klass,
3351
3382
  nth, rjd,
@@ -3384,10 +3415,21 @@ date_s_ordinal(int argc, VALUE *argv, VALUE klass)
3384
3415
  */
3385
3416
  static VALUE
3386
3417
  date_s_civil(int argc, VALUE *argv, VALUE klass)
3418
+ {
3419
+ return date_initialize(argc, argv, d_lite_s_alloc_simple(klass));
3420
+ }
3421
+
3422
+ static VALUE
3423
+ date_initialize(int argc, VALUE *argv, VALUE self)
3387
3424
  {
3388
3425
  VALUE vy, vm, vd, vsg, y, fr, fr2, ret;
3389
3426
  int m, d;
3390
3427
  double sg;
3428
+ struct SimpleDateData *dat = rb_check_typeddata(self, &d_lite_type);
3429
+
3430
+ if (!simple_dat_p(dat)) {
3431
+ rb_raise(rb_eTypeError, "Date expected");
3432
+ }
3391
3433
 
3392
3434
  rb_scan_args(argc, argv, "04", &vy, &vm, &vd, &vsg);
3393
3435
 
@@ -3401,10 +3443,13 @@ date_s_civil(int argc, VALUE *argv, VALUE klass)
3401
3443
  case 4:
3402
3444
  val2sg(vsg, sg);
3403
3445
  case 3:
3446
+ check_numeric(vd, "day");
3404
3447
  num2int_with_frac(d, positive_inf);
3405
3448
  case 2:
3449
+ check_numeric(vm, "month");
3406
3450
  m = NUM2INT(vm);
3407
3451
  case 1:
3452
+ check_numeric(vy, "year");
3408
3453
  y = vy;
3409
3454
  }
3410
3455
 
@@ -3415,13 +3460,9 @@ date_s_civil(int argc, VALUE *argv, VALUE klass)
3415
3460
  if (!valid_gregorian_p(y, m, d,
3416
3461
  &nth, &ry,
3417
3462
  &rm, &rd))
3418
- rb_raise(rb_eArgError, "invalid date");
3463
+ rb_raise(eDateError, "invalid date");
3419
3464
 
3420
- ret = d_simple_new_internal(klass,
3421
- nth, 0,
3422
- sg,
3423
- ry, rm, rd,
3424
- HAVE_CIVIL);
3465
+ set_to_simple(self, dat, nth, 0, sg, ry, rm, rd, HAVE_CIVIL);
3425
3466
  }
3426
3467
  else {
3427
3468
  VALUE nth;
@@ -3431,14 +3472,11 @@ date_s_civil(int argc, VALUE *argv, VALUE klass)
3431
3472
  &nth, &ry,
3432
3473
  &rm, &rd, &rjd,
3433
3474
  &ns))
3434
- rb_raise(rb_eArgError, "invalid date");
3475
+ rb_raise(eDateError, "invalid date");
3435
3476
 
3436
- ret = d_simple_new_internal(klass,
3437
- nth, rjd,
3438
- sg,
3439
- ry, rm, rd,
3440
- HAVE_JD | HAVE_CIVIL);
3477
+ set_to_simple(self, dat, nth, rjd, sg, ry, rm, rd, HAVE_JD | HAVE_CIVIL);
3441
3478
  }
3479
+ ret = self;
3442
3480
  add_frac();
3443
3481
  return ret;
3444
3482
  }
@@ -3478,10 +3516,13 @@ date_s_commercial(int argc, VALUE *argv, VALUE klass)
3478
3516
  case 4:
3479
3517
  val2sg(vsg, sg);
3480
3518
  case 3:
3519
+ check_numeric(vd, "cwday");
3481
3520
  num2int_with_frac(d, positive_inf);
3482
3521
  case 2:
3522
+ check_numeric(vw, "cweek");
3483
3523
  w = NUM2INT(vw);
3484
3524
  case 1:
3525
+ check_numeric(vy, "year");
3485
3526
  y = vy;
3486
3527
  }
3487
3528
 
@@ -3493,7 +3534,7 @@ date_s_commercial(int argc, VALUE *argv, VALUE klass)
3493
3534
  &nth, &ry,
3494
3535
  &rw, &rd, &rjd,
3495
3536
  &ns))
3496
- rb_raise(rb_eArgError, "invalid date");
3537
+ rb_raise(eDateError, "invalid date");
3497
3538
 
3498
3539
  ret = d_simple_new_internal(klass,
3499
3540
  nth, rjd,
@@ -3543,7 +3584,7 @@ date_s_weeknum(int argc, VALUE *argv, VALUE klass)
3543
3584
  &nth, &ry,
3544
3585
  &rw, &rd, &rjd,
3545
3586
  &ns))
3546
- rb_raise(rb_eArgError, "invalid date");
3587
+ rb_raise(eDateError, "invalid date");
3547
3588
 
3548
3589
  ret = d_simple_new_internal(klass,
3549
3590
  nth, rjd,
@@ -3592,7 +3633,7 @@ date_s_nth_kday(int argc, VALUE *argv, VALUE klass)
3592
3633
  &nth, &ry,
3593
3634
  &rm, &rn, &rk, &rjd,
3594
3635
  &ns))
3595
- rb_raise(rb_eArgError, "invalid date");
3636
+ rb_raise(eDateError, "invalid date");
3596
3637
 
3597
3638
  ret = d_simple_new_internal(klass,
3598
3639
  nth, rjd,
@@ -3679,16 +3720,18 @@ date_s_today(int argc, VALUE *argv, VALUE klass)
3679
3720
  #define ref_hash0(k) rb_hash_aref(hash, k)
3680
3721
  #define del_hash0(k) rb_hash_delete(hash, k)
3681
3722
 
3682
- #define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k)), v)
3683
- #define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k)))
3684
- #define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k)))
3723
+ #define sym(x) ID2SYM(rb_intern(x""))
3724
+
3725
+ #define set_hash(k,v) set_hash0(sym(k), v)
3726
+ #define ref_hash(k) ref_hash0(sym(k))
3727
+ #define del_hash(k) del_hash0(sym(k))
3685
3728
 
3686
3729
  static VALUE
3687
3730
  rt_rewrite_frags(VALUE hash)
3688
3731
  {
3689
3732
  VALUE seconds;
3690
3733
 
3691
- seconds = ref_hash("seconds");
3734
+ seconds = del_hash("seconds");
3692
3735
  if (!NIL_P(seconds)) {
3693
3736
  VALUE offset, d, h, min, s, fr;
3694
3737
 
@@ -3713,13 +3756,10 @@ rt_rewrite_frags(VALUE hash)
3713
3756
  set_hash("min", min);
3714
3757
  set_hash("sec", s);
3715
3758
  set_hash("sec_fraction", fr);
3716
- del_hash("seconds");
3717
3759
  }
3718
3760
  return hash;
3719
3761
  }
3720
3762
 
3721
- #define sym(x) ID2SYM(rb_intern(x))
3722
-
3723
3763
  static VALUE d_lite_year(VALUE);
3724
3764
  static VALUE d_lite_wday(VALUE);
3725
3765
  static VALUE d_lite_jd(VALUE);
@@ -3733,89 +3773,89 @@ rt_complete_frags(VALUE klass, VALUE hash)
3733
3773
  VALUE k, a, d;
3734
3774
 
3735
3775
  if (NIL_P(tab)) {
3736
- tab = rb_ary_new3(11,
3737
- rb_ary_new3(2,
3776
+ tab = f_frozen_ary(11,
3777
+ f_frozen_ary(2,
3738
3778
  sym("time"),
3739
- rb_ary_new3(3,
3779
+ f_frozen_ary(3,
3740
3780
  sym("hour"),
3741
3781
  sym("min"),
3742
3782
  sym("sec"))),
3743
- rb_ary_new3(2,
3783
+ f_frozen_ary(2,
3744
3784
  Qnil,
3745
- rb_ary_new3(1,
3785
+ f_frozen_ary(1,
3746
3786
  sym("jd"))),
3747
- rb_ary_new3(2,
3787
+ f_frozen_ary(2,
3748
3788
  sym("ordinal"),
3749
- rb_ary_new3(5,
3789
+ f_frozen_ary(5,
3750
3790
  sym("year"),
3751
3791
  sym("yday"),
3752
3792
  sym("hour"),
3753
3793
  sym("min"),
3754
3794
  sym("sec"))),
3755
- rb_ary_new3(2,
3795
+ f_frozen_ary(2,
3756
3796
  sym("civil"),
3757
- rb_ary_new3(6,
3797
+ f_frozen_ary(6,
3758
3798
  sym("year"),
3759
3799
  sym("mon"),
3760
3800
  sym("mday"),
3761
3801
  sym("hour"),
3762
3802
  sym("min"),
3763
3803
  sym("sec"))),
3764
- rb_ary_new3(2,
3804
+ f_frozen_ary(2,
3765
3805
  sym("commercial"),
3766
- rb_ary_new3(6,
3806
+ f_frozen_ary(6,
3767
3807
  sym("cwyear"),
3768
3808
  sym("cweek"),
3769
3809
  sym("cwday"),
3770
3810
  sym("hour"),
3771
3811
  sym("min"),
3772
3812
  sym("sec"))),
3773
- rb_ary_new3(2,
3813
+ f_frozen_ary(2,
3774
3814
  sym("wday"),
3775
- rb_ary_new3(4,
3815
+ f_frozen_ary(4,
3776
3816
  sym("wday"),
3777
3817
  sym("hour"),
3778
3818
  sym("min"),
3779
3819
  sym("sec"))),
3780
- rb_ary_new3(2,
3820
+ f_frozen_ary(2,
3781
3821
  sym("wnum0"),
3782
- rb_ary_new3(6,
3822
+ f_frozen_ary(6,
3783
3823
  sym("year"),
3784
3824
  sym("wnum0"),
3785
3825
  sym("wday"),
3786
3826
  sym("hour"),
3787
3827
  sym("min"),
3788
3828
  sym("sec"))),
3789
- rb_ary_new3(2,
3829
+ f_frozen_ary(2,
3790
3830
  sym("wnum1"),
3791
- rb_ary_new3(6,
3831
+ f_frozen_ary(6,
3792
3832
  sym("year"),
3793
3833
  sym("wnum1"),
3794
3834
  sym("wday"),
3795
3835
  sym("hour"),
3796
3836
  sym("min"),
3797
3837
  sym("sec"))),
3798
- rb_ary_new3(2,
3838
+ f_frozen_ary(2,
3799
3839
  Qnil,
3800
- rb_ary_new3(6,
3840
+ f_frozen_ary(6,
3801
3841
  sym("cwyear"),
3802
3842
  sym("cweek"),
3803
3843
  sym("wday"),
3804
3844
  sym("hour"),
3805
3845
  sym("min"),
3806
3846
  sym("sec"))),
3807
- rb_ary_new3(2,
3847
+ f_frozen_ary(2,
3808
3848
  Qnil,
3809
- rb_ary_new3(6,
3849
+ f_frozen_ary(6,
3810
3850
  sym("year"),
3811
3851
  sym("wnum0"),
3812
3852
  sym("cwday"),
3813
3853
  sym("hour"),
3814
3854
  sym("min"),
3815
3855
  sym("sec"))),
3816
- rb_ary_new3(2,
3856
+ f_frozen_ary(2,
3817
3857
  Qnil,
3818
- rb_ary_new3(6,
3858
+ f_frozen_ary(6,
3819
3859
  sym("year"),
3820
3860
  sym("wnum1"),
3821
3861
  sym("cwday"),
@@ -4140,7 +4180,7 @@ d_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
4140
4180
  }
4141
4181
 
4142
4182
  if (NIL_P(hash))
4143
- rb_raise(rb_eArgError, "invalid date");
4183
+ rb_raise(eDateError, "invalid date");
4144
4184
 
4145
4185
  if (NIL_P(ref_hash("jd")) &&
4146
4186
  NIL_P(ref_hash("yday")) &&
@@ -4157,7 +4197,7 @@ d_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
4157
4197
  }
4158
4198
 
4159
4199
  if (NIL_P(jd))
4160
- rb_raise(rb_eArgError, "invalid date");
4200
+ rb_raise(eDateError, "invalid date");
4161
4201
  {
4162
4202
  VALUE nth;
4163
4203
  int rjd;
@@ -4212,12 +4252,10 @@ date_s__strptime_internal(int argc, VALUE *argv, VALUE klass,
4212
4252
 
4213
4253
  if (!NIL_P(zone)) {
4214
4254
  rb_enc_copy(zone, vstr);
4215
- OBJ_INFECT(zone, vstr);
4216
4255
  set_hash("zone", zone);
4217
4256
  }
4218
4257
  if (!NIL_P(left)) {
4219
4258
  rb_enc_copy(left, vstr);
4220
- OBJ_INFECT(left, vstr);
4221
4259
  set_hash("leftover", left);
4222
4260
  }
4223
4261
  }
@@ -4305,16 +4343,6 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
4305
4343
 
4306
4344
  hash = date__parse(vstr, vcomp);
4307
4345
 
4308
- {
4309
- VALUE zone = ref_hash("zone");
4310
-
4311
- if (!NIL_P(zone)) {
4312
- rb_enc_copy(zone, vstr);
4313
- OBJ_INFECT(zone, vstr);
4314
- set_hash("zone", zone);
4315
- }
4316
- }
4317
-
4318
4346
  return hash;
4319
4347
  }
4320
4348
 
@@ -4323,8 +4351,12 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
4323
4351
  * Date._parse(string[, comp=true]) -> hash
4324
4352
  *
4325
4353
  * Parses the given representation of date and time, and returns a
4326
- * hash of parsed elements. This method does not function as a
4327
- * validator.
4354
+ * hash of parsed elements.
4355
+ *
4356
+ * This method **does not** function as a validator. If the input
4357
+ * string does not match valid formats strictly, you may get a cryptic
4358
+ * result. Should consider to use `Date._strptime` or
4359
+ * `DateTime._strptime` instead of this method as possible.
4328
4360
  *
4329
4361
  * If the optional second argument is true and the detected year is in
4330
4362
  * the range "00" to "99", considers the year a 2-digit form and makes
@@ -4343,7 +4375,12 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
4343
4375
  * Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]]) -> date
4344
4376
  *
4345
4377
  * Parses the given representation of date and time, and creates a
4346
- * date object. This method does not function as a validator.
4378
+ * date object.
4379
+ *
4380
+ * This method **does not** function as a validator. If the input
4381
+ * string does not match valid formats strictly, you may get a cryptic
4382
+ * result. Should consider to use `Date.strptime` instead of this
4383
+ * method as possible.
4347
4384
  *
4348
4385
  * If the optional second argument is true and the detected year is in
4349
4386
  * the range "00" to "99", considers the year a 2-digit form and makes
@@ -4617,6 +4654,10 @@ date_s__jisx0301(VALUE klass, VALUE str)
4617
4654
  * some typical JIS X 0301 formats.
4618
4655
  *
4619
4656
  * Date.jisx0301('H13.02.03') #=> #<Date: 2001-02-03 ...>
4657
+ *
4658
+ * For no-era year, legacy format, Heisei is assumed.
4659
+ *
4660
+ * Date.jisx0301('13.02.03') #=> #<Date: 2001-02-03 ...>
4620
4661
  */
4621
4662
  static VALUE
4622
4663
  date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
@@ -4691,14 +4732,14 @@ dup_obj_as_complex(VALUE self)
4691
4732
  }
4692
4733
 
4693
4734
  #define val2off(vof,iof) \
4694
- {\
4735
+ do {\
4695
4736
  if (!offset_to_sec(vof, &iof)) {\
4696
4737
  iof = 0;\
4697
4738
  rb_warning("invalid offset is ignored");\
4698
4739
  }\
4699
- }
4740
+ } while (0)
4700
4741
 
4701
- #ifndef NDEBUG
4742
+ #if 0
4702
4743
  static VALUE
4703
4744
  d_lite_initialize(int argc, VALUE *argv, VALUE self)
4704
4745
  {
@@ -4707,7 +4748,6 @@ d_lite_initialize(int argc, VALUE *argv, VALUE self)
4707
4748
  double sg;
4708
4749
 
4709
4750
  rb_check_frozen(self);
4710
- rb_check_trusted(self);
4711
4751
 
4712
4752
  rb_scan_args(argc, argv, "05", &vjd, &vdf, &vsf, &vof, &vsg);
4713
4753
 
@@ -4726,11 +4766,11 @@ d_lite_initialize(int argc, VALUE *argv, VALUE self)
4726
4766
  sf = vsf;
4727
4767
  if (f_lt_p(sf, INT2FIX(0)) ||
4728
4768
  f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS)))
4729
- rb_raise(rb_eArgError, "invalid second fraction");
4769
+ rb_raise(eDateError, "invalid second fraction");
4730
4770
  case 2:
4731
4771
  df = NUM2INT(vdf);
4732
4772
  if (df < 0 || df >= DAY_IN_SECONDS)
4733
- rb_raise(rb_eArgError, "invalid day fraction");
4773
+ rb_raise(eDateError, "invalid day fraction");
4734
4774
  case 1:
4735
4775
  jd = vjd;
4736
4776
  }
@@ -4751,7 +4791,7 @@ d_lite_initialize(int argc, VALUE *argv, VALUE self)
4751
4791
  "cannot load complex into simple");
4752
4792
 
4753
4793
  set_to_complex(self, &dat->c, nth, rjd, df, sf, of, sg,
4754
- 0, 0, 0, 0, 0, 0, HAVE_JD | HAVE_DF | COMPLEX_DAT);
4794
+ 0, 0, 0, 0, 0, 0, HAVE_JD | HAVE_DF);
4755
4795
  }
4756
4796
  }
4757
4797
  return self;
@@ -4763,15 +4803,34 @@ static VALUE
4763
4803
  d_lite_initialize_copy(VALUE copy, VALUE date)
4764
4804
  {
4765
4805
  rb_check_frozen(copy);
4766
- rb_check_trusted(copy);
4767
4806
 
4768
4807
  if (copy == date)
4769
4808
  return copy;
4770
4809
  {
4771
4810
  get_d2(copy, date);
4772
4811
  if (simple_dat_p(bdat)) {
4773
- adat->s = bdat->s;
4774
- adat->s.flags &= ~COMPLEX_DAT;
4812
+ if (simple_dat_p(adat)) {
4813
+ adat->s = bdat->s;
4814
+ }
4815
+ else {
4816
+ adat->c.flags = bdat->s.flags | COMPLEX_DAT;
4817
+ adat->c.nth = bdat->s.nth;
4818
+ adat->c.jd = bdat->s.jd;
4819
+ adat->c.df = 0;
4820
+ adat->c.sf = INT2FIX(0);
4821
+ adat->c.of = 0;
4822
+ adat->c.sg = bdat->s.sg;
4823
+ adat->c.year = bdat->s.year;
4824
+ #ifndef USE_PACK
4825
+ adat->c.mon = bdat->s.mon;
4826
+ adat->c.mday = bdat->s.mday;
4827
+ adat->c.hour = bdat->s.hour;
4828
+ adat->c.min = bdat->s.min;
4829
+ adat->c.sec = bdat->s.sec;
4830
+ #else
4831
+ adat->c.pc = bdat->s.pc;
4832
+ #endif
4833
+ }
4775
4834
  }
4776
4835
  else {
4777
4836
  if (!complex_dat_p(adat))
@@ -4779,7 +4838,6 @@ d_lite_initialize_copy(VALUE copy, VALUE date)
4779
4838
  "cannot load complex into simple");
4780
4839
 
4781
4840
  adat->c = bdat->c;
4782
- adat->c.flags |= COMPLEX_DAT;
4783
4841
  }
4784
4842
  }
4785
4843
  return copy;
@@ -5513,8 +5571,10 @@ d_lite_new_offset(int argc, VALUE *argv, VALUE self)
5513
5571
  static VALUE
5514
5572
  d_lite_plus(VALUE self, VALUE other)
5515
5573
  {
5574
+ int try_rational = 1;
5516
5575
  get_d1(self);
5517
5576
 
5577
+ again:
5518
5578
  switch (TYPE(other)) {
5519
5579
  case T_FIXNUM:
5520
5580
  {
@@ -5724,18 +5784,21 @@ d_lite_plus(VALUE self, VALUE other)
5724
5784
  default:
5725
5785
  expect_numeric(other);
5726
5786
  other = f_to_r(other);
5727
- #ifdef CANONICALIZATION_FOR_MATHN
5728
- if (!k_rational_p(other))
5729
- return d_lite_plus(self, other);
5730
- #endif
5787
+ if (!k_rational_p(other)) {
5788
+ if (!try_rational) Check_Type(other, T_RATIONAL);
5789
+ try_rational = 0;
5790
+ goto again;
5791
+ }
5731
5792
  /* fall through */
5732
5793
  case T_RATIONAL:
5733
5794
  {
5734
5795
  VALUE nth, sf, t;
5735
5796
  int jd, df, s;
5736
5797
 
5737
- if (wholenum_p(other))
5738
- return d_lite_plus(self, rb_rational_num(other));
5798
+ if (wholenum_p(other)) {
5799
+ other = rb_rational_num(other);
5800
+ goto again;
5801
+ }
5739
5802
 
5740
5803
  if (f_positive_p(other))
5741
5804
  s = +1;
@@ -6017,7 +6080,7 @@ d_lite_rshift(VALUE self, VALUE other)
6017
6080
  &rm, &rd, &rjd, &ns))
6018
6081
  break;
6019
6082
  if (--d < 1)
6020
- rb_raise(rb_eArgError, "invalid date");
6083
+ rb_raise(eDateError, "invalid date");
6021
6084
  }
6022
6085
  encode_jd(nth, rjd, &rjd2);
6023
6086
  return d_lite_plus(self, f_sub(rjd2, m_real_local_jd(dat)));
@@ -6154,6 +6217,7 @@ static VALUE
6154
6217
  d_lite_step(int argc, VALUE *argv, VALUE self)
6155
6218
  {
6156
6219
  VALUE limit, step, date;
6220
+ int c;
6157
6221
 
6158
6222
  rb_scan_args(argc, argv, "11", &limit, &step);
6159
6223
 
@@ -6168,25 +6232,22 @@ d_lite_step(int argc, VALUE *argv, VALUE self)
6168
6232
  RETURN_ENUMERATOR(self, argc, argv);
6169
6233
 
6170
6234
  date = self;
6171
- switch (FIX2INT(f_cmp(step, INT2FIX(0)))) {
6172
- case -1:
6235
+ c = f_cmp(step, INT2FIX(0));
6236
+ if (c < 0) {
6173
6237
  while (FIX2INT(d_lite_cmp(date, limit)) >= 0) {
6174
6238
  rb_yield(date);
6175
6239
  date = d_lite_plus(date, step);
6176
6240
  }
6177
- break;
6178
- case 0:
6241
+ }
6242
+ else if (c == 0) {
6179
6243
  while (1)
6180
6244
  rb_yield(date);
6181
- break;
6182
- case 1:
6245
+ }
6246
+ else /* if (c > 0) */ {
6183
6247
  while (FIX2INT(d_lite_cmp(date, limit)) <= 0) {
6184
6248
  rb_yield(date);
6185
6249
  date = d_lite_plus(date, step);
6186
6250
  }
6187
- break;
6188
- default:
6189
- abort();
6190
6251
  }
6191
6252
  return self;
6192
6253
  }
@@ -6241,10 +6302,10 @@ cmp_gen(VALUE self, VALUE other)
6241
6302
  get_d1(self);
6242
6303
 
6243
6304
  if (k_numeric_p(other))
6244
- return f_cmp(m_ajd(dat), other);
6305
+ return INT2FIX(f_cmp(m_ajd(dat), other));
6245
6306
  else if (k_date_p(other))
6246
- return f_cmp(m_ajd(dat), f_ajd(other));
6247
- return rb_num_coerce_cmp(self, other, rb_intern("<=>"));
6307
+ return INT2FIX(f_cmp(m_ajd(dat), f_ajd(other)));
6308
+ return rb_num_coerce_cmp(self, other, id_cmp);
6248
6309
  }
6249
6310
 
6250
6311
  static VALUE
@@ -6373,7 +6434,7 @@ equal_gen(VALUE self, VALUE other)
6373
6434
  return f_eqeq_p(m_real_local_jd(dat), other);
6374
6435
  else if (k_date_p(other))
6375
6436
  return f_eqeq_p(m_real_local_jd(dat), f_jd(other));
6376
- return rb_num_coerce_cmp(self, other, rb_intern("=="));
6437
+ return rb_num_coerce_cmp(self, other, id_eqeq_p);
6377
6438
  }
6378
6439
 
6379
6440
  /*
@@ -6471,7 +6532,7 @@ d_lite_to_s(VALUE self)
6471
6532
  static VALUE
6472
6533
  mk_inspect_raw(union DateData *x, VALUE klass)
6473
6534
  {
6474
- char flags[5];
6535
+ char flags[6];
6475
6536
 
6476
6537
  flags[0] = (x->flags & COMPLEX_DAT) ? 'C' : 'S';
6477
6538
  flags[1] = (x->flags & HAVE_JD) ? 'j' : '-';
@@ -6543,9 +6604,9 @@ mk_inspect(union DateData *x, VALUE klass, VALUE to_s)
6543
6604
  * Returns the value as a string for inspection.
6544
6605
  *
6545
6606
  * Date.new(2001,2,3).inspect
6546
- * #=> "#<Date: 2001-02-03 ((2451944j,0s,0n),+0s,2299161j)>"
6607
+ * #=> "#<Date: 2001-02-03>"
6547
6608
  * DateTime.new(2001,2,3,4,5,6,'-7').inspect
6548
- * #=> "#<DateTime: 2001-02-03T04:05:06-07:00 ((2451944j,39906s,0n),-25200s,2299161j)>"
6609
+ * #=> "#<DateTime: 2001-02-03T04:05:06-07:00>"
6549
6610
  */
6550
6611
  static VALUE
6551
6612
  d_lite_inspect(VALUE self)
@@ -6637,7 +6698,9 @@ tmx_m_of(union DateData *x)
6637
6698
  static char *
6638
6699
  tmx_m_zone(union DateData *x)
6639
6700
  {
6640
- return RSTRING_PTR(m_zone(x));
6701
+ VALUE zone = m_zone(x);
6702
+ /* TODO: fix potential dangling pointer */
6703
+ return RSTRING_PTR(zone);
6641
6704
  }
6642
6705
 
6643
6706
  static const struct tmx_funcs tmx_funcs = {
@@ -6712,7 +6775,6 @@ date_strftime_internal(int argc, VALUE *argv, VALUE self,
6712
6775
  if (p > fmt) rb_str_cat(str, fmt, p - fmt);
6713
6776
  }
6714
6777
  rb_enc_copy(str, vfmt);
6715
- OBJ_INFECT(str, vfmt);
6716
6778
  return str;
6717
6779
  }
6718
6780
  else
@@ -6721,7 +6783,6 @@ date_strftime_internal(int argc, VALUE *argv, VALUE self,
6721
6783
  str = rb_str_new(buf, len);
6722
6784
  if (buf != buffer) xfree(buf);
6723
6785
  rb_enc_copy(str, vfmt);
6724
- OBJ_INFECT(str, vfmt);
6725
6786
  return str;
6726
6787
  }
6727
6788
 
@@ -6787,7 +6848,7 @@ date_strftime_internal(int argc, VALUE *argv, VALUE self,
6787
6848
  *
6788
6849
  * %M - Minute of the hour (00..59)
6789
6850
  *
6790
- * %S - Second of the minute (00..59)
6851
+ * %S - Second of the minute (00..60)
6791
6852
  *
6792
6853
  * %L - Millisecond of the second (000..999)
6793
6854
  * %N - Fractional seconds digits, default is 9 digits (nanosecond)
@@ -7020,10 +7081,14 @@ jisx0301_date_format(char *fmt, size_t size, VALUE jd, VALUE y)
7020
7081
  c = 'S';
7021
7082
  s = 1925;
7022
7083
  }
7023
- else {
7084
+ else if (d < 2458605) {
7024
7085
  c = 'H';
7025
7086
  s = 1988;
7026
7087
  }
7088
+ else {
7089
+ c = 'R';
7090
+ s = 2018;
7091
+ }
7027
7092
  snprintf(fmt, size, "%c%02ld" ".%%m.%%d", c, FIX2INT(y) - s);
7028
7093
  return fmt;
7029
7094
  }
@@ -7101,10 +7166,13 @@ d_lite_marshal_dump(VALUE self)
7101
7166
  static VALUE
7102
7167
  d_lite_marshal_load(VALUE self, VALUE a)
7103
7168
  {
7169
+ VALUE nth, sf;
7170
+ int jd, df, of;
7171
+ double sg;
7172
+
7104
7173
  get_d1(self);
7105
7174
 
7106
7175
  rb_check_frozen(self);
7107
- rb_check_trusted(self);
7108
7176
 
7109
7177
  if (!RB_TYPE_P(a, T_ARRAY))
7110
7178
  rb_raise(rb_eTypeError, "expected an array");
@@ -7113,63 +7181,33 @@ d_lite_marshal_load(VALUE self, VALUE a)
7113
7181
  case 2: /* 1.6.x */
7114
7182
  case 3: /* 1.8.x, 1.9.2 */
7115
7183
  {
7116
- VALUE ajd, of, sg, nth, sf;
7117
- int jd, df, rof;
7118
- double rsg;
7119
-
7184
+ VALUE ajd, vof, vsg;
7120
7185
 
7121
7186
  if (RARRAY_LEN(a) == 2) {
7122
7187
  ajd = f_sub(RARRAY_AREF(a, 0), half_days_in_day);
7123
- of = INT2FIX(0);
7124
- sg = RARRAY_AREF(a, 1);
7125
- if (!k_numeric_p(sg))
7126
- sg = DBL2NUM(RTEST(sg) ? GREGORIAN : JULIAN);
7188
+ vof = INT2FIX(0);
7189
+ vsg = RARRAY_AREF(a, 1);
7190
+ if (!k_numeric_p(vsg))
7191
+ vsg = DBL2NUM(RTEST(vsg) ? GREGORIAN : JULIAN);
7127
7192
  }
7128
7193
  else {
7129
7194
  ajd = RARRAY_AREF(a, 0);
7130
- of = RARRAY_AREF(a, 1);
7131
- sg = RARRAY_AREF(a, 2);
7195
+ vof = RARRAY_AREF(a, 1);
7196
+ vsg = RARRAY_AREF(a, 2);
7132
7197
  }
7133
7198
 
7134
- old_to_new(ajd, of, sg,
7135
- &nth, &jd, &df, &sf, &rof, &rsg);
7136
-
7137
- if (!df && f_zero_p(sf) && !rof) {
7138
- set_to_simple(self, &dat->s, nth, jd, rsg, 0, 0, 0, HAVE_JD);
7139
- } else {
7140
- if (!complex_dat_p(dat))
7141
- rb_raise(rb_eArgError,
7142
- "cannot load complex into simple");
7143
-
7144
- set_to_complex(self, &dat->c, nth, jd, df, sf, rof, rsg,
7145
- 0, 0, 0, 0, 0, 0,
7146
- HAVE_JD | HAVE_DF | COMPLEX_DAT);
7147
- }
7199
+ old_to_new(ajd, vof, vsg,
7200
+ &nth, &jd, &df, &sf, &of, &sg);
7148
7201
  }
7149
7202
  break;
7150
7203
  case 6:
7151
7204
  {
7152
- VALUE nth, sf;
7153
- int jd, df, of;
7154
- double sg;
7155
-
7156
7205
  nth = RARRAY_AREF(a, 0);
7157
7206
  jd = NUM2INT(RARRAY_AREF(a, 1));
7158
7207
  df = NUM2INT(RARRAY_AREF(a, 2));
7159
7208
  sf = RARRAY_AREF(a, 3);
7160
7209
  of = NUM2INT(RARRAY_AREF(a, 4));
7161
7210
  sg = NUM2DBL(RARRAY_AREF(a, 5));
7162
- if (!df && f_zero_p(sf) && !of) {
7163
- set_to_simple(self, &dat->s, nth, jd, sg, 0, 0, 0, HAVE_JD);
7164
- } else {
7165
- if (!complex_dat_p(dat))
7166
- rb_raise(rb_eArgError,
7167
- "cannot load complex into simple");
7168
-
7169
- set_to_complex(self, &dat->c, nth, jd, df, sf, of, sg,
7170
- 0, 0, 0, 0, 0, 0,
7171
- HAVE_JD | HAVE_DF | COMPLEX_DAT);
7172
- }
7173
7211
  }
7174
7212
  break;
7175
7213
  default:
@@ -7177,6 +7215,21 @@ d_lite_marshal_load(VALUE self, VALUE a)
7177
7215
  break;
7178
7216
  }
7179
7217
 
7218
+ if (simple_dat_p(dat)) {
7219
+ if (df || !f_zero_p(sf) || of) {
7220
+ /* loading a fractional date; promote to complex */
7221
+ dat = ruby_xrealloc(dat, sizeof(struct ComplexDateData));
7222
+ RTYPEDDATA(self)->data = dat;
7223
+ goto complex_data;
7224
+ }
7225
+ set_to_simple(self, &dat->s, nth, jd, sg, 0, 0, 0, HAVE_JD);
7226
+ } else {
7227
+ complex_data:
7228
+ set_to_complex(self, &dat->c, nth, jd, df, sf, of, sg,
7229
+ 0, 0, 0, 0, 0, 0,
7230
+ HAVE_JD | HAVE_DF);
7231
+ }
7232
+
7180
7233
  if (FL_TEST(a, FL_EXIVAR)) {
7181
7234
  rb_copy_generic_ivar(self, a);
7182
7235
  FL_SET(self, FL_EXIVAR);
@@ -7232,12 +7285,16 @@ datetime_s_jd(int argc, VALUE *argv, VALUE klass)
7232
7285
  case 5:
7233
7286
  val2off(vof, rof);
7234
7287
  case 4:
7288
+ check_numeric(vs, "second");
7235
7289
  num2int_with_frac(s, positive_inf);
7236
7290
  case 3:
7291
+ check_numeric(vmin, "minute");
7237
7292
  num2int_with_frac(min, 3);
7238
7293
  case 2:
7294
+ check_numeric(vh, "hour");
7239
7295
  num2int_with_frac(h, 2);
7240
7296
  case 1:
7297
+ check_numeric(vjd, "jd");
7241
7298
  num2num_with_frac(jd, 1);
7242
7299
  }
7243
7300
 
@@ -7246,7 +7303,7 @@ datetime_s_jd(int argc, VALUE *argv, VALUE klass)
7246
7303
  int rh, rmin, rs, rjd, rjd2;
7247
7304
 
7248
7305
  if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
7249
- rb_raise(rb_eArgError, "invalid date");
7306
+ rb_raise(eDateError, "invalid date");
7250
7307
  canon24oc();
7251
7308
 
7252
7309
  decode_jd(jd, &nth, &rjd);
@@ -7301,14 +7358,19 @@ datetime_s_ordinal(int argc, VALUE *argv, VALUE klass)
7301
7358
  case 6:
7302
7359
  val2off(vof, rof);
7303
7360
  case 5:
7361
+ check_numeric(vs, "second");
7304
7362
  num2int_with_frac(s, positive_inf);
7305
7363
  case 4:
7364
+ check_numeric(vmin, "minute");
7306
7365
  num2int_with_frac(min, 4);
7307
7366
  case 3:
7367
+ check_numeric(vh, "hour");
7308
7368
  num2int_with_frac(h, 3);
7309
7369
  case 2:
7370
+ check_numeric(vd, "yday");
7310
7371
  num2int_with_frac(d, 2);
7311
7372
  case 1:
7373
+ check_numeric(vy, "year");
7312
7374
  y = vy;
7313
7375
  }
7314
7376
 
@@ -7320,9 +7382,9 @@ datetime_s_ordinal(int argc, VALUE *argv, VALUE klass)
7320
7382
  &nth, &ry,
7321
7383
  &rd, &rjd,
7322
7384
  &ns))
7323
- rb_raise(rb_eArgError, "invalid date");
7385
+ rb_raise(eDateError, "invalid date");
7324
7386
  if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
7325
- rb_raise(rb_eArgError, "invalid date");
7387
+ rb_raise(eDateError, "invalid date");
7326
7388
  canon24oc();
7327
7389
 
7328
7390
  rjd2 = jd_local_to_utc(rjd,
@@ -7356,10 +7418,21 @@ datetime_s_ordinal(int argc, VALUE *argv, VALUE klass)
7356
7418
  */
7357
7419
  static VALUE
7358
7420
  datetime_s_civil(int argc, VALUE *argv, VALUE klass)
7421
+ {
7422
+ return datetime_initialize(argc, argv, d_lite_s_alloc_complex(klass));
7423
+ }
7424
+
7425
+ static VALUE
7426
+ datetime_initialize(int argc, VALUE *argv, VALUE self)
7359
7427
  {
7360
7428
  VALUE vy, vm, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
7361
7429
  int m, d, h, min, s, rof;
7362
7430
  double sg;
7431
+ struct ComplexDateData *dat = rb_check_typeddata(self, &d_lite_type);
7432
+
7433
+ if (!complex_dat_p(dat)) {
7434
+ rb_raise(rb_eTypeError, "DateTime expected");
7435
+ }
7363
7436
 
7364
7437
  rb_scan_args(argc, argv, "08", &vy, &vm, &vd, &vh, &vmin, &vs, &vof, &vsg);
7365
7438
 
@@ -7378,16 +7451,22 @@ datetime_s_civil(int argc, VALUE *argv, VALUE klass)
7378
7451
  case 7:
7379
7452
  val2off(vof, rof);
7380
7453
  case 6:
7454
+ check_numeric(vs, "second");
7381
7455
  num2int_with_frac(s, positive_inf);
7382
7456
  case 5:
7457
+ check_numeric(vmin, "minute");
7383
7458
  num2int_with_frac(min, 5);
7384
7459
  case 4:
7460
+ check_numeric(vh, "hour");
7385
7461
  num2int_with_frac(h, 4);
7386
7462
  case 3:
7463
+ check_numeric(vd, "day");
7387
7464
  num2int_with_frac(d, 3);
7388
7465
  case 2:
7466
+ check_numeric(vm, "month");
7389
7467
  m = NUM2INT(vm);
7390
7468
  case 1:
7469
+ check_numeric(vy, "year");
7391
7470
  y = vy;
7392
7471
  }
7393
7472
 
@@ -7398,18 +7477,18 @@ datetime_s_civil(int argc, VALUE *argv, VALUE klass)
7398
7477
  if (!valid_gregorian_p(y, m, d,
7399
7478
  &nth, &ry,
7400
7479
  &rm, &rd))
7401
- rb_raise(rb_eArgError, "invalid date");
7480
+ rb_raise(eDateError, "invalid date");
7402
7481
  if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
7403
- rb_raise(rb_eArgError, "invalid date");
7482
+ rb_raise(eDateError, "invalid date");
7404
7483
  canon24oc();
7405
7484
 
7406
- ret = d_complex_new_internal(klass,
7407
- nth, 0,
7408
- 0, INT2FIX(0),
7409
- rof, sg,
7410
- ry, rm, rd,
7411
- rh, rmin, rs,
7412
- HAVE_CIVIL | HAVE_TIME);
7485
+ set_to_complex(self, dat,
7486
+ nth, 0,
7487
+ 0, INT2FIX(0),
7488
+ rof, sg,
7489
+ ry, rm, rd,
7490
+ rh, rmin, rs,
7491
+ HAVE_CIVIL | HAVE_TIME);
7413
7492
  }
7414
7493
  else {
7415
7494
  VALUE nth;
@@ -7419,23 +7498,24 @@ datetime_s_civil(int argc, VALUE *argv, VALUE klass)
7419
7498
  &nth, &ry,
7420
7499
  &rm, &rd, &rjd,
7421
7500
  &ns))
7422
- rb_raise(rb_eArgError, "invalid date");
7501
+ rb_raise(eDateError, "invalid date");
7423
7502
  if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
7424
- rb_raise(rb_eArgError, "invalid date");
7503
+ rb_raise(eDateError, "invalid date");
7425
7504
  canon24oc();
7426
7505
 
7427
7506
  rjd2 = jd_local_to_utc(rjd,
7428
7507
  time_to_df(rh, rmin, rs),
7429
7508
  rof);
7430
7509
 
7431
- ret = d_complex_new_internal(klass,
7432
- nth, rjd2,
7433
- 0, INT2FIX(0),
7434
- rof, sg,
7435
- ry, rm, rd,
7436
- rh, rmin, rs,
7437
- HAVE_JD | HAVE_CIVIL | HAVE_TIME);
7510
+ set_to_complex(self, dat,
7511
+ nth, rjd2,
7512
+ 0, INT2FIX(0),
7513
+ rof, sg,
7514
+ ry, rm, rd,
7515
+ rh, rmin, rs,
7516
+ HAVE_JD | HAVE_CIVIL | HAVE_TIME);
7438
7517
  }
7518
+ ret = self;
7439
7519
  add_frac();
7440
7520
  return ret;
7441
7521
  }
@@ -7475,16 +7555,22 @@ datetime_s_commercial(int argc, VALUE *argv, VALUE klass)
7475
7555
  case 7:
7476
7556
  val2off(vof, rof);
7477
7557
  case 6:
7558
+ check_numeric(vs, "second");
7478
7559
  num2int_with_frac(s, positive_inf);
7479
7560
  case 5:
7561
+ check_numeric(vmin, "minute");
7480
7562
  num2int_with_frac(min, 5);
7481
7563
  case 4:
7564
+ check_numeric(vh, "hour");
7482
7565
  num2int_with_frac(h, 4);
7483
7566
  case 3:
7567
+ check_numeric(vd, "cwday");
7484
7568
  num2int_with_frac(d, 3);
7485
7569
  case 2:
7570
+ check_numeric(vw, "cweek");
7486
7571
  w = NUM2INT(vw);
7487
7572
  case 1:
7573
+ check_numeric(vy, "year");
7488
7574
  y = vy;
7489
7575
  }
7490
7576
 
@@ -7496,9 +7582,9 @@ datetime_s_commercial(int argc, VALUE *argv, VALUE klass)
7496
7582
  &nth, &ry,
7497
7583
  &rw, &rd, &rjd,
7498
7584
  &ns))
7499
- rb_raise(rb_eArgError, "invalid date");
7585
+ rb_raise(eDateError, "invalid date");
7500
7586
  if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
7501
- rb_raise(rb_eArgError, "invalid date");
7587
+ rb_raise(eDateError, "invalid date");
7502
7588
  canon24oc();
7503
7589
 
7504
7590
  rjd2 = jd_local_to_utc(rjd,
@@ -7567,9 +7653,9 @@ datetime_s_weeknum(int argc, VALUE *argv, VALUE klass)
7567
7653
  &nth, &ry,
7568
7654
  &rw, &rd, &rjd,
7569
7655
  &ns))
7570
- rb_raise(rb_eArgError, "invalid date");
7656
+ rb_raise(eDateError, "invalid date");
7571
7657
  if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
7572
- rb_raise(rb_eArgError, "invalid date");
7658
+ rb_raise(eDateError, "invalid date");
7573
7659
  canon24oc();
7574
7660
 
7575
7661
  rjd2 = jd_local_to_utc(rjd,
@@ -7636,9 +7722,9 @@ datetime_s_nth_kday(int argc, VALUE *argv, VALUE klass)
7636
7722
  &nth, &ry,
7637
7723
  &rm, &rn, &rk, &rjd,
7638
7724
  &ns))
7639
- rb_raise(rb_eArgError, "invalid date");
7725
+ rb_raise(eDateError, "invalid date");
7640
7726
  if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
7641
- rb_raise(rb_eArgError, "invalid date");
7727
+ rb_raise(eDateError, "invalid date");
7642
7728
  canon24oc();
7643
7729
 
7644
7730
  rjd2 = jd_local_to_utc(rjd,
@@ -7781,7 +7867,7 @@ dt_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
7781
7867
  }
7782
7868
 
7783
7869
  if (NIL_P(hash))
7784
- rb_raise(rb_eArgError, "invalid date");
7870
+ rb_raise(eDateError, "invalid date");
7785
7871
 
7786
7872
  if (NIL_P(ref_hash("jd")) &&
7787
7873
  NIL_P(ref_hash("yday")) &&
@@ -7808,7 +7894,7 @@ dt_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
7808
7894
  }
7809
7895
 
7810
7896
  if (NIL_P(jd))
7811
- rb_raise(rb_eArgError, "invalid date");
7897
+ rb_raise(eDateError, "invalid date");
7812
7898
 
7813
7899
  {
7814
7900
  int rh, rmin, rs;
@@ -7817,7 +7903,7 @@ dt_new_by_frags(VALUE klass, VALUE hash, VALUE sg)
7817
7903
  NUM2INT(ref_hash("min")),
7818
7904
  NUM2INT(ref_hash("sec")),
7819
7905
  &rh, &rmin, &rs))
7820
- rb_raise(rb_eArgError, "invalid date");
7906
+ rb_raise(eDateError, "invalid date");
7821
7907
 
7822
7908
  df = time_to_df(rh, rmin, rs);
7823
7909
  }
@@ -7930,7 +8016,12 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
7930
8016
  * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]]) -> datetime
7931
8017
  *
7932
8018
  * Parses the given representation of date and time, and creates a
7933
- * DateTime object. This method does not function as a validator.
8019
+ * DateTime object.
8020
+ *
8021
+ * This method **does not** function as a validator. If the input
8022
+ * string does not match valid formats strictly, you may get a cryptic
8023
+ * result. Should consider to use `DateTime.strptime` instead of this
8024
+ * method as possible.
7934
8025
  *
7935
8026
  * If the optional second argument is true and the detected year is in
7936
8027
  * the range "00" to "99", makes it full.
@@ -8132,6 +8223,11 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
8132
8223
  *
8133
8224
  * DateTime.jisx0301('H13.02.03T04:05:06+07:00')
8134
8225
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8226
+ *
8227
+ * For no-era year, legacy format, Heisei is assumed.
8228
+ *
8229
+ * DateTime.jisx0301('13.02.03T04:05:06+07:00')
8230
+ * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8135
8231
  */
8136
8232
  static VALUE
8137
8233
  datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
@@ -8232,7 +8328,7 @@ dt_lite_to_s(VALUE self)
8232
8328
  *
8233
8329
  * %M - Minute of the hour (00..59)
8234
8330
  *
8235
- * %S - Second of the minute (00..59)
8331
+ * %S - Second of the minute (00..60)
8236
8332
  *
8237
8333
  * %L - Millisecond of the second (000..999)
8238
8334
  * %N - Fractional seconds digits, default is 9 digits (nanosecond)
@@ -8526,17 +8622,24 @@ time_to_datetime(VALUE self)
8526
8622
  * call-seq:
8527
8623
  * d.to_time -> time
8528
8624
  *
8529
- * Returns a Time object which denotes self.
8625
+ * Returns a Time object which denotes self. If self is a julian date,
8626
+ * convert it to a gregorian date before converting it to Time.
8530
8627
  */
8531
8628
  static VALUE
8532
8629
  date_to_time(VALUE self)
8533
8630
  {
8534
- get_d1(self);
8631
+ get_d1a(self);
8632
+
8633
+ if (m_julian_p(adat)) {
8634
+ VALUE tmp = d_lite_gregorian(self);
8635
+ get_d1b(tmp);
8636
+ adat = bdat;
8637
+ }
8535
8638
 
8536
8639
  return f_local3(rb_cTime,
8537
- m_real_year(dat),
8538
- INT2FIX(m_mon(dat)),
8539
- INT2FIX(m_mday(dat)));
8640
+ m_real_year(adat),
8641
+ INT2FIX(m_mon(adat)),
8642
+ INT2FIX(m_mday(adat)));
8540
8643
  }
8541
8644
 
8542
8645
  /*
@@ -8645,7 +8748,7 @@ datetime_to_date(VALUE self)
8645
8748
  VALUE new = d_lite_s_alloc_simple(cDate);
8646
8749
  {
8647
8750
  get_d1b(new);
8648
- copy_complex_to_simple(new, &bdat->s, &adat->c)
8751
+ copy_complex_to_simple(new, &bdat->s, &adat->c);
8649
8752
  bdat->s.jd = m_local_jd(adat);
8650
8753
  bdat->s.flags &= ~(HAVE_DF | HAVE_TIME | COMPLEX_DAT);
8651
8754
  return new;
@@ -9010,18 +9113,22 @@ mk_ary_of_str(long len, const char *a[])
9010
9113
  return o;
9011
9114
  }
9012
9115
 
9116
+ static VALUE
9117
+ d_lite_zero(VALUE x)
9118
+ {
9119
+ return INT2FIX(0);
9120
+ }
9121
+
9013
9122
  void
9014
9123
  Init_date_core(void)
9015
9124
  {
9016
- #undef rb_intern
9017
- #define rb_intern(str) rb_intern_const(str)
9018
-
9019
- assert(fprintf(stderr, "assert() is now active\n"));
9020
-
9021
- id_cmp = rb_intern("<=>");
9022
- id_le_p = rb_intern("<=");
9023
- id_ge_p = rb_intern(">=");
9024
- id_eqeq_p = rb_intern("==");
9125
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
9126
+ RB_EXT_RACTOR_SAFE(true);
9127
+ #endif
9128
+ id_cmp = rb_intern_const("<=>");
9129
+ id_le_p = rb_intern_const("<=");
9130
+ id_ge_p = rb_intern_const(">=");
9131
+ id_eqeq_p = rb_intern_const("==");
9025
9132
 
9026
9133
  half_days_in_day = rb_rational_new2(INT2FIX(1), INT2FIX(2));
9027
9134
 
@@ -9189,6 +9296,7 @@ Init_date_core(void)
9189
9296
  *
9190
9297
  */
9191
9298
  cDate = rb_define_class("Date", rb_cObject);
9299
+ eDateError = rb_define_class_under(cDate, "Error", rb_eArgError);
9192
9300
 
9193
9301
  rb_include_module(cDate, rb_mComparable);
9194
9302
 
@@ -9233,23 +9341,22 @@ Init_date_core(void)
9233
9341
  */
9234
9342
  rb_define_const(cDate, "GREGORIAN", DBL2NUM(GREGORIAN));
9235
9343
 
9236
- rb_define_alloc_func(cDate, d_lite_s_alloc);
9344
+ rb_define_alloc_func(cDate, d_lite_s_alloc_simple);
9237
9345
 
9238
9346
  #ifndef NDEBUG
9239
- #define de_define_private_method rb_define_private_method
9240
- de_define_private_method(CLASS_OF(cDate), "_valid_jd?",
9347
+ rb_define_private_method(CLASS_OF(cDate), "_valid_jd?",
9241
9348
  date_s__valid_jd_p, -1);
9242
- de_define_private_method(CLASS_OF(cDate), "_valid_ordinal?",
9349
+ rb_define_private_method(CLASS_OF(cDate), "_valid_ordinal?",
9243
9350
  date_s__valid_ordinal_p, -1);
9244
- de_define_private_method(CLASS_OF(cDate), "_valid_civil?",
9351
+ rb_define_private_method(CLASS_OF(cDate), "_valid_civil?",
9245
9352
  date_s__valid_civil_p, -1);
9246
- de_define_private_method(CLASS_OF(cDate), "_valid_date?",
9353
+ rb_define_private_method(CLASS_OF(cDate), "_valid_date?",
9247
9354
  date_s__valid_civil_p, -1);
9248
- de_define_private_method(CLASS_OF(cDate), "_valid_commercial?",
9355
+ rb_define_private_method(CLASS_OF(cDate), "_valid_commercial?",
9249
9356
  date_s__valid_commercial_p, -1);
9250
- de_define_private_method(CLASS_OF(cDate), "_valid_weeknum?",
9357
+ rb_define_private_method(CLASS_OF(cDate), "_valid_weeknum?",
9251
9358
  date_s__valid_weeknum_p, -1);
9252
- de_define_private_method(CLASS_OF(cDate), "_valid_nth_kday?",
9359
+ rb_define_private_method(CLASS_OF(cDate), "_valid_nth_kday?",
9253
9360
  date_s__valid_nth_kday_p, -1);
9254
9361
  #endif
9255
9362
 
@@ -9262,11 +9369,11 @@ Init_date_core(void)
9262
9369
  date_s_valid_commercial_p, -1);
9263
9370
 
9264
9371
  #ifndef NDEBUG
9265
- de_define_private_method(CLASS_OF(cDate), "valid_weeknum?",
9372
+ rb_define_private_method(CLASS_OF(cDate), "valid_weeknum?",
9266
9373
  date_s_valid_weeknum_p, -1);
9267
- de_define_private_method(CLASS_OF(cDate), "valid_nth_kday?",
9374
+ rb_define_private_method(CLASS_OF(cDate), "valid_nth_kday?",
9268
9375
  date_s_valid_nth_kday_p, -1);
9269
- de_define_private_method(CLASS_OF(cDate), "zone_to_diff",
9376
+ rb_define_private_method(CLASS_OF(cDate), "zone_to_diff",
9270
9377
  date_s_zone_to_diff, 1);
9271
9378
  #endif
9272
9379
 
@@ -9277,21 +9384,18 @@ Init_date_core(void)
9277
9384
  date_s_gregorian_leap_p, 1);
9278
9385
 
9279
9386
  #ifndef NDEBUG
9280
- #define de_define_singleton_method rb_define_singleton_method
9281
- #define de_define_alias rb_define_alias
9282
- de_define_singleton_method(cDate, "new!", date_s_new_bang, -1);
9283
- de_define_alias(rb_singleton_class(cDate), "new_l!", "new");
9387
+ rb_define_singleton_method(cDate, "new!", date_s_new_bang, -1);
9388
+ rb_define_alias(rb_singleton_class(cDate), "new_l!", "new");
9284
9389
  #endif
9285
9390
 
9286
9391
  rb_define_singleton_method(cDate, "jd", date_s_jd, -1);
9287
9392
  rb_define_singleton_method(cDate, "ordinal", date_s_ordinal, -1);
9288
9393
  rb_define_singleton_method(cDate, "civil", date_s_civil, -1);
9289
- rb_define_singleton_method(cDate, "new", date_s_civil, -1);
9290
9394
  rb_define_singleton_method(cDate, "commercial", date_s_commercial, -1);
9291
9395
 
9292
9396
  #ifndef NDEBUG
9293
- de_define_singleton_method(cDate, "weeknum", date_s_weeknum, -1);
9294
- de_define_singleton_method(cDate, "nth_kday", date_s_nth_kday, -1);
9397
+ rb_define_singleton_method(cDate, "weeknum", date_s_weeknum, -1);
9398
+ rb_define_singleton_method(cDate, "nth_kday", date_s_nth_kday, -1);
9295
9399
  #endif
9296
9400
 
9297
9401
  rb_define_singleton_method(cDate, "today", date_s_today, -1);
@@ -9314,14 +9418,11 @@ Init_date_core(void)
9314
9418
  rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, 1);
9315
9419
  rb_define_singleton_method(cDate, "jisx0301", date_s_jisx0301, -1);
9316
9420
 
9317
- #ifndef NDEBUG
9318
- #define de_define_method rb_define_method
9319
- de_define_method(cDate, "initialize", d_lite_initialize, -1);
9320
- #endif
9421
+ rb_define_method(cDate, "initialize", date_initialize, -1);
9321
9422
  rb_define_method(cDate, "initialize_copy", d_lite_initialize_copy, 1);
9322
9423
 
9323
9424
  #ifndef NDEBUG
9324
- de_define_method(cDate, "fill", d_lite_fill, 0);
9425
+ rb_define_method(cDate, "fill", d_lite_fill, 0);
9325
9426
  #endif
9326
9427
 
9327
9428
  rb_define_method(cDate, "ajd", d_lite_ajd, 0);
@@ -9343,8 +9444,8 @@ Init_date_core(void)
9343
9444
  rb_define_method(cDate, "cwday", d_lite_cwday, 0);
9344
9445
 
9345
9446
  #ifndef NDEBUG
9346
- de_define_private_method(cDate, "wnum0", d_lite_wnum0, 0);
9347
- de_define_private_method(cDate, "wnum1", d_lite_wnum1, 0);
9447
+ rb_define_private_method(cDate, "wnum0", d_lite_wnum0, 0);
9448
+ rb_define_private_method(cDate, "wnum1", d_lite_wnum1, 0);
9348
9449
  #endif
9349
9450
 
9350
9451
  rb_define_method(cDate, "wday", d_lite_wday, 0);
@@ -9358,18 +9459,14 @@ Init_date_core(void)
9358
9459
  rb_define_method(cDate, "saturday?", d_lite_saturday_p, 0);
9359
9460
 
9360
9461
  #ifndef NDEBUG
9361
- de_define_method(cDate, "nth_kday?", d_lite_nth_kday_p, 2);
9462
+ rb_define_method(cDate, "nth_kday?", d_lite_nth_kday_p, 2);
9362
9463
  #endif
9363
9464
 
9364
- rb_define_private_method(cDate, "hour", d_lite_hour, 0);
9365
- rb_define_private_method(cDate, "min", d_lite_min, 0);
9366
- rb_define_private_method(cDate, "minute", d_lite_min, 0);
9367
- rb_define_private_method(cDate, "sec", d_lite_sec, 0);
9368
- rb_define_private_method(cDate, "second", d_lite_sec, 0);
9369
- rb_define_private_method(cDate, "sec_fraction", d_lite_sec_fraction, 0);
9370
- rb_define_private_method(cDate, "second_fraction", d_lite_sec_fraction, 0);
9371
- rb_define_private_method(cDate, "offset", d_lite_offset, 0);
9372
- rb_define_private_method(cDate, "zone", d_lite_zone, 0);
9465
+ rb_define_private_method(cDate, "hour", d_lite_zero, 0);
9466
+ rb_define_private_method(cDate, "min", d_lite_zero, 0);
9467
+ rb_define_private_method(cDate, "minute", d_lite_zero, 0);
9468
+ rb_define_private_method(cDate, "sec", d_lite_zero, 0);
9469
+ rb_define_private_method(cDate, "second", d_lite_zero, 0);
9373
9470
 
9374
9471
  rb_define_method(cDate, "julian?", d_lite_julian_p, 0);
9375
9472
  rb_define_method(cDate, "gregorian?", d_lite_gregorian_p, 0);
@@ -9382,8 +9479,6 @@ Init_date_core(void)
9382
9479
  rb_define_method(cDate, "julian", d_lite_julian, 0);
9383
9480
  rb_define_method(cDate, "gregorian", d_lite_gregorian, 0);
9384
9481
 
9385
- rb_define_private_method(cDate, "new_offset", d_lite_new_offset, -1);
9386
-
9387
9482
  rb_define_method(cDate, "+", d_lite_plus, 1);
9388
9483
  rb_define_method(cDate, "-", d_lite_minus, 1);
9389
9484
 
@@ -9411,7 +9506,7 @@ Init_date_core(void)
9411
9506
 
9412
9507
  rb_define_method(cDate, "to_s", d_lite_to_s, 0);
9413
9508
  #ifndef NDEBUG
9414
- de_define_method(cDate, "inspect_raw", d_lite_inspect_raw, 0);
9509
+ rb_define_method(cDate, "inspect_raw", d_lite_inspect_raw, 0);
9415
9510
  #endif
9416
9511
  rb_define_method(cDate, "inspect", d_lite_inspect, 0);
9417
9512
 
@@ -9428,7 +9523,7 @@ Init_date_core(void)
9428
9523
  rb_define_method(cDate, "jisx0301", d_lite_jisx0301, 0);
9429
9524
 
9430
9525
  #ifndef NDEBUG
9431
- de_define_method(cDate, "marshal_dump_old", d_lite_marshal_dump_old, 0);
9526
+ rb_define_method(cDate, "marshal_dump_old", d_lite_marshal_dump_old, 0);
9432
9527
  #endif
9433
9528
  rb_define_method(cDate, "marshal_dump", d_lite_marshal_dump, 0);
9434
9529
  rb_define_method(cDate, "marshal_load", d_lite_marshal_load, 1);
@@ -9440,6 +9535,8 @@ Init_date_core(void)
9440
9535
  * A subclass of Date that easily handles date, hour, minute, second,
9441
9536
  * and offset.
9442
9537
  *
9538
+ * DateTime class is considered deprecated. Use Time class.
9539
+ *
9443
9540
  * DateTime does not consider any leap seconds, does not track
9444
9541
  * any summer time rules.
9445
9542
  *
@@ -9500,18 +9597,18 @@ Init_date_core(void)
9500
9597
  * === When should you use DateTime and when should you use Time?
9501
9598
  *
9502
9599
  * It's a common misconception that
9503
- * {William Shakespeare}[http://en.wikipedia.org/wiki/William_Shakespeare]
9600
+ * {William Shakespeare}[https://en.wikipedia.org/wiki/William_Shakespeare]
9504
9601
  * and
9505
- * {Miguel de Cervantes}[http://en.wikipedia.org/wiki/Miguel_de_Cervantes]
9602
+ * {Miguel de Cervantes}[https://en.wikipedia.org/wiki/Miguel_de_Cervantes]
9506
9603
  * died on the same day in history -
9507
9604
  * so much so that UNESCO named April 23 as
9508
- * {World Book Day because of this fact}[http://en.wikipedia.org/wiki/World_Book_Day].
9605
+ * {World Book Day because of this fact}[https://en.wikipedia.org/wiki/World_Book_Day].
9509
9606
  * However, because England hadn't yet adopted the
9510
- * {Gregorian Calendar Reform}[http://en.wikipedia.org/wiki/Gregorian_calendar#Gregorian_reform]
9511
- * (and wouldn't until {1752}[http://en.wikipedia.org/wiki/Calendar_(New_Style)_Act_1750])
9607
+ * {Gregorian Calendar Reform}[https://en.wikipedia.org/wiki/Gregorian_calendar#Gregorian_reform]
9608
+ * (and wouldn't until {1752}[https://en.wikipedia.org/wiki/Calendar_(New_Style)_Act_1750])
9512
9609
  * their deaths are actually 10 days apart.
9513
9610
  * Since Ruby's Time class implements a
9514
- * {proleptic Gregorian calendar}[http://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar]
9611
+ * {proleptic Gregorian calendar}[https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar]
9515
9612
  * and has no concept of calendar reform there's no way
9516
9613
  * to express this with Time objects. This is where DateTime steps in:
9517
9614
  *
@@ -9555,7 +9652,7 @@ Init_date_core(void)
9555
9652
  * #=> Fri, 04 May 1753 00:00:00 +0000
9556
9653
  *
9557
9654
  * As you can see, if we're accurately tracking the number of
9558
- * {solar years}[http://en.wikipedia.org/wiki/Tropical_year]
9655
+ * {solar years}[https://en.wikipedia.org/wiki/Tropical_year]
9559
9656
  * since Shakespeare's birthday then the correct anniversary date
9560
9657
  * would be the 4th May and not the 23rd April.
9561
9658
  *
@@ -9567,14 +9664,15 @@ Init_date_core(void)
9567
9664
  * making the same mistakes as UNESCO. If you also have to deal
9568
9665
  * with timezones then best of luck - just bear in mind that
9569
9666
  * you'll probably be dealing with
9570
- * {local solar times}[http://en.wikipedia.org/wiki/Solar_time],
9667
+ * {local solar times}[https://en.wikipedia.org/wiki/Solar_time],
9571
9668
  * since it wasn't until the 19th century that the introduction
9572
9669
  * of the railways necessitated the need for
9573
- * {Standard Time}[http://en.wikipedia.org/wiki/Standard_time#Great_Britain]
9670
+ * {Standard Time}[https://en.wikipedia.org/wiki/Standard_time#Great_Britain]
9574
9671
  * and eventually timezones.
9575
9672
  */
9576
9673
 
9577
9674
  cDateTime = rb_define_class("DateTime", cDate);
9675
+ rb_define_alloc_func(cDateTime, d_lite_s_alloc_complex);
9578
9676
 
9579
9677
  rb_define_singleton_method(cDateTime, "jd", datetime_s_jd, -1);
9580
9678
  rb_define_singleton_method(cDateTime, "ordinal", datetime_s_ordinal, -1);
@@ -9584,9 +9682,9 @@ Init_date_core(void)
9584
9682
  datetime_s_commercial, -1);
9585
9683
 
9586
9684
  #ifndef NDEBUG
9587
- de_define_singleton_method(cDateTime, "weeknum",
9685
+ rb_define_singleton_method(cDateTime, "weeknum",
9588
9686
  datetime_s_weeknum, -1);
9589
- de_define_singleton_method(cDateTime, "nth_kday",
9687
+ rb_define_singleton_method(cDateTime, "nth_kday",
9590
9688
  datetime_s_nth_kday, -1);
9591
9689
  #endif
9592
9690
 
@@ -9614,19 +9712,16 @@ Init_date_core(void)
9614
9712
  rb_define_singleton_method(cDateTime, "jisx0301",
9615
9713
  datetime_s_jisx0301, -1);
9616
9714
 
9617
- #define f_public(m,s) rb_funcall(m, rb_intern("public"), 1,\
9618
- ID2SYM(rb_intern(s)))
9619
-
9620
- f_public(cDateTime, "hour");
9621
- f_public(cDateTime, "min");
9622
- f_public(cDateTime, "minute");
9623
- f_public(cDateTime, "sec");
9624
- f_public(cDateTime, "second");
9625
- f_public(cDateTime, "sec_fraction");
9626
- f_public(cDateTime, "second_fraction");
9627
- f_public(cDateTime, "offset");
9628
- f_public(cDateTime, "zone");
9629
- f_public(cDateTime, "new_offset");
9715
+ rb_define_method(cDateTime, "hour", d_lite_hour, 0);
9716
+ rb_define_method(cDateTime, "min", d_lite_min, 0);
9717
+ rb_define_method(cDateTime, "minute", d_lite_min, 0);
9718
+ rb_define_method(cDateTime, "sec", d_lite_sec, 0);
9719
+ rb_define_method(cDateTime, "second", d_lite_sec, 0);
9720
+ rb_define_method(cDateTime, "sec_fraction", d_lite_sec_fraction, 0);
9721
+ rb_define_method(cDateTime, "second_fraction", d_lite_sec_fraction, 0);
9722
+ rb_define_method(cDateTime, "offset", d_lite_offset, 0);
9723
+ rb_define_method(cDateTime, "zone", d_lite_zone, 0);
9724
+ rb_define_method(cDateTime, "new_offset", d_lite_new_offset, -1);
9630
9725
 
9631
9726
  rb_define_method(cDateTime, "to_s", dt_lite_to_s, 0);
9632
9727
 
@@ -9654,15 +9749,15 @@ Init_date_core(void)
9654
9749
  #ifndef NDEBUG
9655
9750
  /* tests */
9656
9751
 
9657
- de_define_singleton_method(cDate, "test_civil", date_s_test_civil, 0);
9658
- de_define_singleton_method(cDate, "test_ordinal", date_s_test_ordinal, 0);
9659
- de_define_singleton_method(cDate, "test_commercial",
9752
+ rb_define_singleton_method(cDate, "test_civil", date_s_test_civil, 0);
9753
+ rb_define_singleton_method(cDate, "test_ordinal", date_s_test_ordinal, 0);
9754
+ rb_define_singleton_method(cDate, "test_commercial",
9660
9755
  date_s_test_commercial, 0);
9661
- de_define_singleton_method(cDate, "test_weeknum", date_s_test_weeknum, 0);
9662
- de_define_singleton_method(cDate, "test_nth_kday", date_s_test_nth_kday, 0);
9663
- de_define_singleton_method(cDate, "test_unit_conv",
9756
+ rb_define_singleton_method(cDate, "test_weeknum", date_s_test_weeknum, 0);
9757
+ rb_define_singleton_method(cDate, "test_nth_kday", date_s_test_nth_kday, 0);
9758
+ rb_define_singleton_method(cDate, "test_unit_conv",
9664
9759
  date_s_test_unit_conv, 0);
9665
- de_define_singleton_method(cDate, "test_all", date_s_test_all, 0);
9760
+ rb_define_singleton_method(cDate, "test_all", date_s_test_all, 0);
9666
9761
  #endif
9667
9762
  }
9668
9763