date 3.2.1 → 3.5.1

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.
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)
@@ -53,14 +57,15 @@ static double positive_inf, negative_inf;
53
57
  #define f_add3(x,y,z) f_add(f_add(x, y), z)
54
58
  #define f_sub3(x,y,z) f_sub(f_sub(x, y), z)
55
59
 
56
- #define f_frozen_ary(...) rb_obj_freeze(rb_ary_new3(__VA_ARGS__))
60
+ #define f_frozen_ary(...) rb_ary_freeze(rb_ary_new3(__VA_ARGS__))
57
61
 
58
62
  static VALUE date_initialize(int argc, VALUE *argv, VALUE self);
59
63
  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
  }
@@ -243,6 +248,11 @@ f_negative_p(VALUE x)
243
248
  #define date_sg_t double
244
249
  #endif
245
250
 
251
+ #define JULIAN_EPOCH_DATE "-4712-01-01"
252
+ #define JULIAN_EPOCH_DATETIME JULIAN_EPOCH_DATE "T00:00:00+00:00"
253
+ #define JULIAN_EPOCH_DATETIME_RFC3339 "Mon, 1 Jan -4712 00:00:00 +0000"
254
+ #define JULIAN_EPOCH_DATETIME_HTTPDATE "Mon, 01 Jan -4712 00:00:00 GMT"
255
+
246
256
  /* A set of nth, jd, df and sf denote ajd + 1/2. Each ajd begin at
247
257
  * noon of GMT (assume equal to UTC). However, this begins at
248
258
  * midnight.
@@ -465,6 +475,7 @@ c_find_ldoy(int y, double sg, int *rjd, int *ns)
465
475
  }
466
476
 
467
477
  #ifndef NDEBUG
478
+ /* :nodoc: */
468
479
  static int
469
480
  c_find_fdom(int y, int m, double sg, int *rjd, int *ns)
470
481
  {
@@ -621,6 +632,7 @@ c_jd_to_weeknum(int jd, int f, double sg, int *ry, int *rw, int *rd)
621
632
  }
622
633
 
623
634
  #ifndef NDEBUG
635
+ /* :nodoc: */
624
636
  static void
625
637
  c_nth_kday_to_jd(int y, int m, int n, int k, double sg, int *rjd, int *ns)
626
638
  {
@@ -646,6 +658,7 @@ c_jd_to_wday(int jd)
646
658
  }
647
659
 
648
660
  #ifndef NDEBUG
661
+ /* :nodoc: */
649
662
  static void
650
663
  c_jd_to_nth_kday(int jd, double sg, int *ry, int *rm, int *rn, int *rk)
651
664
  {
@@ -758,6 +771,8 @@ c_valid_civil_p(int y, int m, int d, double sg,
758
771
 
759
772
  if (m < 0)
760
773
  m += 13;
774
+ if (m < 1 || m > 12)
775
+ return 0;
761
776
  if (d < 0) {
762
777
  if (!c_find_ldom(y, m, sg, rjd, ns))
763
778
  return 0;
@@ -822,6 +837,7 @@ c_valid_weeknum_p(int y, int w, int d, int f, double sg,
822
837
  }
823
838
 
824
839
  #ifndef NDEBUG
840
+ /* :nodoc: */
825
841
  static int
826
842
  c_valid_nth_kday_p(int y, int m, int n, int k, double sg,
827
843
  int *rm, int *rn, int *rk, int *rjd, int *ns)
@@ -963,6 +979,7 @@ ns_to_day(VALUE n)
963
979
  }
964
980
 
965
981
  #ifndef NDEBUG
982
+ /* :nodoc: */
966
983
  static VALUE
967
984
  ms_to_sec(VALUE m)
968
985
  {
@@ -981,6 +998,7 @@ ns_to_sec(VALUE n)
981
998
  }
982
999
 
983
1000
  #ifndef NDEBUG
1001
+ /* :nodoc: */
984
1002
  inline static VALUE
985
1003
  ins_to_day(int n)
986
1004
  {
@@ -1016,6 +1034,7 @@ day_to_sec(VALUE d)
1016
1034
  }
1017
1035
 
1018
1036
  #ifndef NDEBUG
1037
+ /* :nodoc: */
1019
1038
  static VALUE
1020
1039
  day_to_ns(VALUE d)
1021
1040
  {
@@ -1040,6 +1059,7 @@ sec_to_ns(VALUE s)
1040
1059
  }
1041
1060
 
1042
1061
  #ifndef NDEBUG
1062
+ /* :nodoc: */
1043
1063
  static VALUE
1044
1064
  isec_to_ns(int s)
1045
1065
  {
@@ -1066,6 +1086,7 @@ div_df(VALUE d, VALUE *f)
1066
1086
  }
1067
1087
 
1068
1088
  #ifndef NDEBUG
1089
+ /* :nodoc: */
1069
1090
  static VALUE
1070
1091
  div_sf(VALUE s, VALUE *f)
1071
1092
  {
@@ -1500,6 +1521,7 @@ m_df(union DateData *x)
1500
1521
  }
1501
1522
 
1502
1523
  #ifndef NDEBUG
1524
+ /* :nodoc: */
1503
1525
  static VALUE
1504
1526
  m_df_in_day(union DateData *x)
1505
1527
  {
@@ -1577,7 +1599,7 @@ m_ajd(union DateData *x)
1577
1599
 
1578
1600
  if (simple_dat_p(x)) {
1579
1601
  r = m_real_jd(x);
1580
- if (FIXNUM_P(r) && FIX2LONG(r) <= (FIXNUM_MAX / 2)) {
1602
+ if (FIXNUM_P(r) && FIX2LONG(r) <= (FIXNUM_MAX / 2) && FIX2LONG(r) >= (FIXNUM_MIN + 1) / 2) {
1581
1603
  long ir = FIX2LONG(r);
1582
1604
  ir = ir * 2 - 1;
1583
1605
  return rb_rational_new2(LONG2FIX(ir), INT2FIX(2));
@@ -1997,6 +2019,7 @@ expect_numeric(VALUE x)
1997
2019
  }
1998
2020
 
1999
2021
  #ifndef NDEBUG
2022
+ /* :nodoc: */
2000
2023
  static void
2001
2024
  civil_to_jd(VALUE y, int m, int d, double sg,
2002
2025
  VALUE *nth, int *ry,
@@ -2309,6 +2332,7 @@ valid_weeknum_p(VALUE y, int w, int d, int f, double sg,
2309
2332
  }
2310
2333
 
2311
2334
  #ifndef NDEBUG
2335
+ /* :nodoc: */
2312
2336
  static int
2313
2337
  valid_nth_kday_p(VALUE y, int m, int n, int k, double sg,
2314
2338
  VALUE *nth, int *ry,
@@ -2446,6 +2470,7 @@ valid_jd_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2446
2470
  }
2447
2471
 
2448
2472
  #ifndef NDEBUG
2473
+ /* :nodoc: */
2449
2474
  static VALUE
2450
2475
  date_s__valid_jd_p(int argc, VALUE *argv, VALUE klass)
2451
2476
  {
@@ -2466,13 +2491,16 @@ date_s__valid_jd_p(int argc, VALUE *argv, VALUE klass)
2466
2491
 
2467
2492
  /*
2468
2493
  * call-seq:
2469
- * Date.valid_jd?(jd[, start=Date::ITALY]) -> bool
2494
+ * Date.valid_jd?(jd, start = Date::ITALY) -> true
2470
2495
  *
2471
- * Just returns true. It's nonsense, but is for symmetry.
2496
+ * Implemented for compatibility;
2497
+ * returns +true+ unless +jd+ is invalid (i.e., not a Numeric).
2472
2498
  *
2473
- * Date.valid_jd?(2451944) #=> true
2499
+ * Date.valid_jd?(2451944) # => true
2474
2500
  *
2475
- * See also ::jd.
2501
+ * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
2502
+ *
2503
+ * Related: Date.jd.
2476
2504
  */
2477
2505
  static VALUE
2478
2506
  date_s_valid_jd_p(int argc, VALUE *argv, VALUE klass)
@@ -2532,6 +2560,7 @@ valid_civil_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2532
2560
  }
2533
2561
 
2534
2562
  #ifndef NDEBUG
2563
+ /* :nodoc: */
2535
2564
  static VALUE
2536
2565
  date_s__valid_civil_p(int argc, VALUE *argv, VALUE klass)
2537
2566
  {
@@ -2554,18 +2583,18 @@ date_s__valid_civil_p(int argc, VALUE *argv, VALUE klass)
2554
2583
 
2555
2584
  /*
2556
2585
  * call-seq:
2557
- * Date.valid_civil?(year, month, mday[, start=Date::ITALY]) -> bool
2558
- * Date.valid_date?(year, month, mday[, start=Date::ITALY]) -> bool
2586
+ * Date.valid_civil?(year, month, mday, start = Date::ITALY) -> true or false
2587
+ *
2588
+ * Returns +true+ if the arguments define a valid ordinal date,
2589
+ * +false+ otherwise:
2559
2590
  *
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.
2591
+ * Date.valid_date?(2001, 2, 3) # => true
2592
+ * Date.valid_date?(2001, 2, 29) # => false
2593
+ * Date.valid_date?(2001, 2, -1) # => true
2563
2594
  *
2564
- * Date.valid_date?(2001,2,3) #=> true
2565
- * Date.valid_date?(2001,2,29) #=> false
2566
- * Date.valid_date?(2001,2,-1) #=> true
2595
+ * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
2567
2596
  *
2568
- * See also ::jd and ::civil.
2597
+ * Related: Date.jd, Date.new.
2569
2598
  */
2570
2599
  static VALUE
2571
2600
  date_s_valid_civil_p(int argc, VALUE *argv, VALUE klass)
@@ -2621,6 +2650,7 @@ valid_ordinal_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2621
2650
  }
2622
2651
 
2623
2652
  #ifndef NDEBUG
2653
+ /* :nodoc: */
2624
2654
  static VALUE
2625
2655
  date_s__valid_ordinal_p(int argc, VALUE *argv, VALUE klass)
2626
2656
  {
@@ -2642,14 +2672,17 @@ date_s__valid_ordinal_p(int argc, VALUE *argv, VALUE klass)
2642
2672
 
2643
2673
  /*
2644
2674
  * call-seq:
2645
- * Date.valid_ordinal?(year, yday[, start=Date::ITALY]) -> bool
2675
+ * Date.valid_ordinal?(year, yday, start = Date::ITALY) -> true or false
2676
+ *
2677
+ * Returns +true+ if the arguments define a valid ordinal date,
2678
+ * +false+ otherwise:
2646
2679
  *
2647
- * Returns true if the given ordinal date is valid, and false if not.
2680
+ * Date.valid_ordinal?(2001, 34) # => true
2681
+ * Date.valid_ordinal?(2001, 366) # => false
2648
2682
  *
2649
- * Date.valid_ordinal?(2001,34) #=> true
2650
- * Date.valid_ordinal?(2001,366) #=> false
2683
+ * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
2651
2684
  *
2652
- * See also ::jd and ::ordinal.
2685
+ * Related: Date.jd, Date.ordinal.
2653
2686
  */
2654
2687
  static VALUE
2655
2688
  date_s_valid_ordinal_p(int argc, VALUE *argv, VALUE klass)
@@ -2704,6 +2737,7 @@ valid_commercial_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2704
2737
  }
2705
2738
 
2706
2739
  #ifndef NDEBUG
2740
+ /* :nodoc: */
2707
2741
  static VALUE
2708
2742
  date_s__valid_commercial_p(int argc, VALUE *argv, VALUE klass)
2709
2743
  {
@@ -2726,14 +2760,19 @@ date_s__valid_commercial_p(int argc, VALUE *argv, VALUE klass)
2726
2760
 
2727
2761
  /*
2728
2762
  * call-seq:
2729
- * Date.valid_commercial?(cwyear, cweek, cwday[, start=Date::ITALY]) -> bool
2763
+ * Date.valid_commercial?(cwyear, cweek, cwday, start = Date::ITALY) -> true or false
2764
+ *
2765
+ * Returns +true+ if the arguments define a valid commercial date,
2766
+ * +false+ otherwise:
2767
+ *
2768
+ * Date.valid_commercial?(2001, 5, 6) # => true
2769
+ * Date.valid_commercial?(2001, 5, 8) # => false
2730
2770
  *
2731
- * Returns true if the given week date is valid, and false if not.
2771
+ * See Date.commercial.
2732
2772
  *
2733
- * Date.valid_commercial?(2001,5,6) #=> true
2734
- * Date.valid_commercial?(2001,5,8) #=> false
2773
+ * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
2735
2774
  *
2736
- * See also ::jd and ::commercial.
2775
+ * Related: Date.jd, Date.commercial.
2737
2776
  */
2738
2777
  static VALUE
2739
2778
  date_s_valid_commercial_p(int argc, VALUE *argv, VALUE klass)
@@ -2760,6 +2799,7 @@ date_s_valid_commercial_p(int argc, VALUE *argv, VALUE klass)
2760
2799
  }
2761
2800
 
2762
2801
  #ifndef NDEBUG
2802
+ /* :nodoc: */
2763
2803
  static VALUE
2764
2804
  valid_weeknum_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2765
2805
  {
@@ -2791,6 +2831,7 @@ valid_weeknum_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2791
2831
  }
2792
2832
  }
2793
2833
 
2834
+ /* :nodoc: */
2794
2835
  static VALUE
2795
2836
  date_s__valid_weeknum_p(int argc, VALUE *argv, VALUE klass)
2796
2837
  {
@@ -2811,6 +2852,7 @@ date_s__valid_weeknum_p(int argc, VALUE *argv, VALUE klass)
2811
2852
  return valid_weeknum_sub(5, argv2, klass, 1);
2812
2853
  }
2813
2854
 
2855
+ /* :nodoc: */
2814
2856
  static VALUE
2815
2857
  date_s_valid_weeknum_p(int argc, VALUE *argv, VALUE klass)
2816
2858
  {
@@ -2862,6 +2904,7 @@ valid_nth_kday_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2862
2904
  }
2863
2905
  }
2864
2906
 
2907
+ /* :nodoc: */
2865
2908
  static VALUE
2866
2909
  date_s__valid_nth_kday_p(int argc, VALUE *argv, VALUE klass)
2867
2910
  {
@@ -2882,6 +2925,7 @@ date_s__valid_nth_kday_p(int argc, VALUE *argv, VALUE klass)
2882
2925
  return valid_nth_kday_sub(5, argv2, klass, 1);
2883
2926
  }
2884
2927
 
2928
+ /* :nodoc: */
2885
2929
  static VALUE
2886
2930
  date_s_valid_nth_kday_p(int argc, VALUE *argv, VALUE klass)
2887
2931
  {
@@ -2904,6 +2948,7 @@ date_s_valid_nth_kday_p(int argc, VALUE *argv, VALUE klass)
2904
2948
  return Qtrue;
2905
2949
  }
2906
2950
 
2951
+ /* :nodoc: */
2907
2952
  static VALUE
2908
2953
  date_s_zone_to_diff(VALUE klass, VALUE str)
2909
2954
  {
@@ -2913,13 +2958,15 @@ date_s_zone_to_diff(VALUE klass, VALUE str)
2913
2958
 
2914
2959
  /*
2915
2960
  * call-seq:
2916
- * Date.julian_leap?(year) -> bool
2961
+ * Date.julian_leap?(year) -> true or false
2917
2962
  *
2918
- * Returns true if the given year is a leap year of the proleptic
2919
- * Julian calendar.
2963
+ * Returns +true+ if the given year is a leap year
2964
+ * in the {proleptic Julian calendar}[https://en.wikipedia.org/wiki/Proleptic_Julian_calendar], +false+ otherwise:
2920
2965
  *
2921
- * Date.julian_leap?(1900) #=> true
2922
- * Date.julian_leap?(1901) #=> false
2966
+ * Date.julian_leap?(1900) # => true
2967
+ * Date.julian_leap?(1901) # => false
2968
+ *
2969
+ * Related: Date.gregorian_leap?.
2923
2970
  */
2924
2971
  static VALUE
2925
2972
  date_s_julian_leap_p(VALUE klass, VALUE y)
@@ -2934,14 +2981,15 @@ date_s_julian_leap_p(VALUE klass, VALUE y)
2934
2981
 
2935
2982
  /*
2936
2983
  * call-seq:
2937
- * Date.gregorian_leap?(year) -> bool
2938
- * Date.leap?(year) -> bool
2984
+ * Date.gregorian_leap?(year) -> true or false
2985
+ *
2986
+ * Returns +true+ if the given year is a leap year
2987
+ * in the {proleptic Gregorian calendar}[https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar], +false+ otherwise:
2939
2988
  *
2940
- * Returns true if the given year is a leap year of the proleptic
2941
- * Gregorian calendar.
2989
+ * Date.gregorian_leap?(2000) # => true
2990
+ * Date.gregorian_leap?(2001) # => false
2942
2991
  *
2943
- * Date.gregorian_leap?(1900) #=> false
2944
- * Date.gregorian_leap?(2000) #=> true
2992
+ * Related: Date.julian_leap?.
2945
2993
  */
2946
2994
  static VALUE
2947
2995
  date_s_gregorian_leap_p(VALUE klass, VALUE y)
@@ -3094,6 +3142,7 @@ old_to_new(VALUE ajd, VALUE of, VALUE sg,
3094
3142
  }
3095
3143
 
3096
3144
  #ifndef NDEBUG
3145
+ /* :nodoc: */
3097
3146
  static VALUE
3098
3147
  date_s_new_bang(int argc, VALUE *argv, VALUE klass)
3099
3148
  {
@@ -3281,16 +3330,29 @@ static VALUE d_lite_plus(VALUE, VALUE);
3281
3330
 
3282
3331
  /*
3283
3332
  * call-seq:
3284
- * Date.jd([jd=0[, start=Date::ITALY]]) -> date
3333
+ * Date.jd(jd = 0, start = Date::ITALY) -> date
3334
+ *
3335
+ * Returns a new \Date object formed from the arguments:
3336
+ *
3337
+ * Date.jd(2451944).to_s # => "2001-02-03"
3338
+ * Date.jd(2451945).to_s # => "2001-02-04"
3339
+ * Date.jd(0).to_s # => "-4712-01-01"
3340
+ *
3341
+ * The returned date is:
3342
+ *
3343
+ * - Gregorian, if the argument is greater than or equal to +start+:
3344
+ *
3345
+ * Date::ITALY # => 2299161
3346
+ * Date.jd(Date::ITALY).gregorian? # => true
3347
+ * Date.jd(Date::ITALY + 1).gregorian? # => true
3285
3348
  *
3286
- * Creates a date object denoting the given chronological Julian day
3287
- * number.
3349
+ * - Julian, otherwise
3288
3350
  *
3289
- * Date.jd(2451944) #=> #<Date: 2001-02-03 ...>
3290
- * Date.jd(2451945) #=> #<Date: 2001-02-04 ...>
3291
- * Date.jd(0) #=> #<Date: -4712-01-01 ...>
3351
+ * Date.jd(Date::ITALY - 1).julian? # => true
3292
3352
  *
3293
- * See also ::new.
3353
+ * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
3354
+ *
3355
+ * Related: Date.new.
3294
3356
  */
3295
3357
  static VALUE
3296
3358
  date_s_jd(int argc, VALUE *argv, VALUE klass)
@@ -3329,19 +3391,33 @@ date_s_jd(int argc, VALUE *argv, VALUE klass)
3329
3391
 
3330
3392
  /*
3331
3393
  * call-seq:
3332
- * Date.ordinal([year=-4712[, yday=1[, start=Date::ITALY]]]) -> date
3394
+ * Date.ordinal(year = -4712, yday = 1, start = Date::ITALY) -> date
3395
+ *
3396
+ * Returns a new \Date object formed fom the arguments.
3397
+ *
3398
+ * With no arguments, returns the date for January 1, -4712:
3399
+ *
3400
+ * Date.ordinal.to_s # => "-4712-01-01"
3401
+ *
3402
+ * With argument +year+, returns the date for January 1 of that year:
3333
3403
  *
3334
- * Creates a date object denoting the given ordinal date.
3404
+ * Date.ordinal(2001).to_s # => "2001-01-01"
3405
+ * Date.ordinal(-2001).to_s # => "-2001-01-01"
3335
3406
  *
3336
- * The day of year should be a negative or a positive number (as a
3337
- * relative day from the end of year when negative). It should not be
3338
- * zero.
3407
+ * With positive argument +yday+ == +n+,
3408
+ * returns the date for the +nth+ day of the given year:
3339
3409
  *
3340
- * Date.ordinal(2001) #=> #<Date: 2001-01-01 ...>
3341
- * Date.ordinal(2001,34) #=> #<Date: 2001-02-03 ...>
3342
- * Date.ordinal(2001,-1) #=> #<Date: 2001-12-31 ...>
3410
+ * Date.ordinal(2001, 14).to_s # => "2001-01-14"
3343
3411
  *
3344
- * See also ::jd and ::new.
3412
+ * With negative argument +yday+, counts backward from the end of the year:
3413
+ *
3414
+ * Date.ordinal(2001, -14).to_s # => "2001-12-18"
3415
+ *
3416
+ * Raises an exception if +yday+ is zero or out of range.
3417
+ *
3418
+ * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
3419
+ *
3420
+ * Related: Date.jd, Date.new.
3345
3421
  */
3346
3422
  static VALUE
3347
3423
  date_s_ordinal(int argc, VALUE *argv, VALUE klass)
@@ -3389,29 +3465,7 @@ date_s_ordinal(int argc, VALUE *argv, VALUE klass)
3389
3465
  }
3390
3466
 
3391
3467
  /*
3392
- * call-seq:
3393
- * Date.civil([year=-4712[, month=1[, mday=1[, start=Date::ITALY]]]]) -> date
3394
- * Date.new([year=-4712[, month=1[, mday=1[, start=Date::ITALY]]]]) -> date
3395
- *
3396
- * Creates a date object denoting the given calendar date.
3397
- *
3398
- * In this class, BCE years are counted astronomically. Thus, the
3399
- * year before the year 1 is the year zero, and the year preceding the
3400
- * year zero is the year -1. The month and the day of month should be
3401
- * a negative or a positive number (as a relative month/day from the
3402
- * end of year/month when negative). They should not be zero.
3403
- *
3404
- * The last argument should be a Julian day number which denotes the
3405
- * day of calendar reform. Date::ITALY (2299161=1582-10-15),
3406
- * Date::ENGLAND (2361222=1752-09-14), Date::GREGORIAN (the proleptic
3407
- * Gregorian calendar) and Date::JULIAN (the proleptic Julian
3408
- * calendar) can be specified as a day of calendar reform.
3409
- *
3410
- * Date.new(2001) #=> #<Date: 2001-01-01 ...>
3411
- * Date.new(2001,2,3) #=> #<Date: 2001-02-03 ...>
3412
- * Date.new(2001,2,-1) #=> #<Date: 2001-02-28 ...>
3413
- *
3414
- * See also ::jd.
3468
+ * Same as Date.new.
3415
3469
  */
3416
3470
  static VALUE
3417
3471
  date_s_civil(int argc, VALUE *argv, VALUE klass)
@@ -3419,6 +3473,29 @@ date_s_civil(int argc, VALUE *argv, VALUE klass)
3419
3473
  return date_initialize(argc, argv, d_lite_s_alloc_simple(klass));
3420
3474
  }
3421
3475
 
3476
+ /*
3477
+ * call-seq:
3478
+ * Date.new(year = -4712, month = 1, mday = 1, start = Date::ITALY) -> date
3479
+ *
3480
+ * Returns a new \Date object constructed from the given arguments:
3481
+ *
3482
+ * Date.new(2022).to_s # => "2022-01-01"
3483
+ * Date.new(2022, 2).to_s # => "2022-02-01"
3484
+ * Date.new(2022, 2, 4).to_s # => "2022-02-04"
3485
+ *
3486
+ * Argument +month+ should be in range (1..12) or range (-12..-1);
3487
+ * when the argument is negative, counts backward from the end of the year:
3488
+ *
3489
+ * Date.new(2022, -11, 4).to_s # => "2022-02-04"
3490
+ *
3491
+ * Argument +mday+ should be in range (1..n) or range (-n..-1)
3492
+ * where +n+ is the number of days in the month;
3493
+ * when the argument is negative, counts backward from the end of the month.
3494
+ *
3495
+ * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
3496
+ *
3497
+ * Related: Date.jd.
3498
+ */
3422
3499
  static VALUE
3423
3500
  date_initialize(int argc, VALUE *argv, VALUE self)
3424
3501
  {
@@ -3483,19 +3560,47 @@ date_initialize(int argc, VALUE *argv, VALUE self)
3483
3560
 
3484
3561
  /*
3485
3562
  * call-seq:
3486
- * Date.commercial([cwyear=-4712[, cweek=1[, cwday=1[, start=Date::ITALY]]]]) -> date
3563
+ * Date.commercial(cwyear = -4712, cweek = 1, cwday = 1, start = Date::ITALY) -> date
3564
+ *
3565
+ * Returns a new \Date object constructed from the arguments.
3566
+ *
3567
+ * Argument +cwyear+ gives the year, and should be an integer.
3568
+ *
3569
+ * Argument +cweek+ gives the index of the week within the year,
3570
+ * and should be in range (1..53) or (-53..-1);
3571
+ * in some years, 53 or -53 will be out-of-range;
3572
+ * if negative, counts backward from the end of the year:
3487
3573
  *
3488
- * Creates a date object denoting the given week date.
3574
+ * Date.commercial(2022, 1, 1).to_s # => "2022-01-03"
3575
+ * Date.commercial(2022, 52, 1).to_s # => "2022-12-26"
3489
3576
  *
3490
- * The week and the day of week should be a negative or a positive
3491
- * number (as a relative week/day from the end of year/week when
3492
- * negative). They should not be zero.
3577
+ * Argument +cwday+ gives the indes of the weekday within the week,
3578
+ * and should be in range (1..7) or (-7..-1);
3579
+ * 1 or -7 is Monday;
3580
+ * if negative, counts backward from the end of the week:
3493
3581
  *
3494
- * Date.commercial(2001) #=> #<Date: 2001-01-01 ...>
3495
- * Date.commercial(2002) #=> #<Date: 2001-12-31 ...>
3496
- * Date.commercial(2001,5,6) #=> #<Date: 2001-02-03 ...>
3582
+ * Date.commercial(2022, 1, 1).to_s # => "2022-01-03"
3583
+ * Date.commercial(2022, 1, -7).to_s # => "2022-01-03"
3497
3584
  *
3498
- * See also ::jd and ::new.
3585
+ * When +cweek+ is 1:
3586
+ *
3587
+ * - If January 1 is a Friday, Saturday, or Sunday,
3588
+ * the first week begins in the week after:
3589
+ *
3590
+ * Date::ABBR_DAYNAMES[Date.new(2023, 1, 1).wday] # => "Sun"
3591
+ * Date.commercial(2023, 1, 1).to_s # => "2023-01-02"
3592
+ Date.commercial(2023, 1, 7).to_s # => "2023-01-08"
3593
+ *
3594
+ * - Otherwise, the first week is the week of January 1,
3595
+ * which may mean some of the days fall on the year before:
3596
+ *
3597
+ * Date::ABBR_DAYNAMES[Date.new(2020, 1, 1).wday] # => "Wed"
3598
+ * Date.commercial(2020, 1, 1).to_s # => "2019-12-30"
3599
+ Date.commercial(2020, 1, 7).to_s # => "2020-01-05"
3600
+ *
3601
+ * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
3602
+ *
3603
+ * Related: Date.jd, Date.new, Date.ordinal.
3499
3604
  */
3500
3605
  static VALUE
3501
3606
  date_s_commercial(int argc, VALUE *argv, VALUE klass)
@@ -3547,6 +3652,7 @@ date_s_commercial(int argc, VALUE *argv, VALUE klass)
3547
3652
  }
3548
3653
 
3549
3654
  #ifndef NDEBUG
3655
+ /* :nodoc: */
3550
3656
  static VALUE
3551
3657
  date_s_weeknum(int argc, VALUE *argv, VALUE klass)
3552
3658
  {
@@ -3596,6 +3702,7 @@ date_s_weeknum(int argc, VALUE *argv, VALUE klass)
3596
3702
  return ret;
3597
3703
  }
3598
3704
 
3705
+ /* :nodoc: */
3599
3706
  static VALUE
3600
3707
  date_s_nth_kday(int argc, VALUE *argv, VALUE klass)
3601
3708
  {
@@ -3670,11 +3777,14 @@ static void set_sg(union DateData *, double);
3670
3777
 
3671
3778
  /*
3672
3779
  * call-seq:
3673
- * Date.today([start=Date::ITALY]) -> date
3780
+ * Date.today(start = Date::ITALY) -> date
3781
+ *
3782
+ * Returns a new \Date object constructed from the present date:
3674
3783
  *
3675
- * Creates a date object denoting the present day.
3784
+ * Date.today.to_s # => "2022-07-06"
3785
+ *
3786
+ * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
3676
3787
  *
3677
- * Date.today #=> #<Date: 2011-06-11 ...>
3678
3788
  */
3679
3789
  static VALUE
3680
3790
  date_s_today(int argc, VALUE *argv, VALUE klass)
@@ -3768,7 +3878,6 @@ static VALUE
3768
3878
  rt_complete_frags(VALUE klass, VALUE hash)
3769
3879
  {
3770
3880
  static VALUE tab = Qnil;
3771
- int g;
3772
3881
  long e;
3773
3882
  VALUE k, a, d;
3774
3883
 
@@ -3865,9 +3974,13 @@ rt_complete_frags(VALUE klass, VALUE hash)
3865
3974
  rb_gc_register_mark_object(tab);
3866
3975
  }
3867
3976
 
3977
+ k = a = Qnil;
3978
+
3868
3979
  {
3869
- long i, eno = 0, idx = 0;
3980
+ long i, eno = 0;
3981
+ VALUE t = Qnil;
3870
3982
 
3983
+ e = 0;
3871
3984
  for (i = 0; i < RARRAY_LEN(tab); i++) {
3872
3985
  VALUE x, a;
3873
3986
 
@@ -3882,23 +3995,20 @@ rt_complete_frags(VALUE klass, VALUE hash)
3882
3995
  n++;
3883
3996
  if (n > eno) {
3884
3997
  eno = n;
3885
- idx = i;
3998
+ t = x;
3886
3999
  }
3887
4000
  }
3888
4001
  }
3889
- if (eno == 0)
3890
- g = 0;
3891
- else {
3892
- g = 1;
3893
- k = RARRAY_AREF(RARRAY_AREF(tab, idx), 0);
3894
- a = RARRAY_AREF(RARRAY_AREF(tab, idx), 1);
3895
- e = eno;
4002
+ if (eno > 0) {
4003
+ k = RARRAY_AREF(t, 0);
4004
+ a = RARRAY_AREF(t, 1);
3896
4005
  }
4006
+ e = eno;
3897
4007
  }
3898
4008
 
3899
4009
  d = Qnil;
3900
4010
 
3901
- if (g && !NIL_P(k) && (RARRAY_LEN(a) - e)) {
4011
+ if (!NIL_P(k) && (RARRAY_LEN(a) > e)) {
3902
4012
  if (k == sym("ordinal")) {
3903
4013
  if (NIL_P(ref_hash("year"))) {
3904
4014
  if (NIL_P(d))
@@ -3985,7 +4095,7 @@ rt_complete_frags(VALUE klass, VALUE hash)
3985
4095
  }
3986
4096
  }
3987
4097
 
3988
- if (g && k == sym("time")) {
4098
+ if (k == sym("time")) {
3989
4099
  if (f_le_p(klass, cDateTime)) {
3990
4100
  if (NIL_P(d))
3991
4101
  d = date_s_today(0, (VALUE *)0, cDate);
@@ -4265,16 +4375,20 @@ date_s__strptime_internal(int argc, VALUE *argv, VALUE klass,
4265
4375
 
4266
4376
  /*
4267
4377
  * call-seq:
4268
- * Date._strptime(string[, format='%F']) -> hash
4378
+ * Date._strptime(string, format = '%F') -> hash
4269
4379
  *
4270
- * Parses the given representation of date and time with the given
4271
- * template, and returns a hash of parsed elements. _strptime does
4272
- * not support specification of flags and width unlike strftime.
4380
+ * Returns a hash of values parsed from +string+
4381
+ * according to the given +format+:
4273
4382
  *
4274
- * Date._strptime('2001-02-03', '%Y-%m-%d')
4275
- * #=> {:year=>2001, :mon=>2, :mday=>3}
4383
+ * Date._strptime('2001-02-03', '%Y-%m-%d') # => {:year=>2001, :mon=>2, :mday=>3}
4276
4384
  *
4277
- * See also strptime(3) and #strftime.
4385
+ * For other formats, see
4386
+ * {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc].
4387
+ * (Unlike Date.strftime, does not support flags and width.)
4388
+ *
4389
+ * See also {strptime(3)}[https://man7.org/linux/man-pages/man3/strptime.3.html].
4390
+ *
4391
+ * Related: Date.strptime (returns a \Date object).
4278
4392
  */
4279
4393
  static VALUE
4280
4394
  date_s__strptime(int argc, VALUE *argv, VALUE klass)
@@ -4284,21 +4398,28 @@ date_s__strptime(int argc, VALUE *argv, VALUE klass)
4284
4398
 
4285
4399
  /*
4286
4400
  * call-seq:
4287
- * Date.strptime([string='-4712-01-01'[, format='%F'[, start=Date::ITALY]]]) -> date
4401
+ * Date.strptime(string = '-4712-01-01', format = '%F', start = Date::ITALY) -> date
4288
4402
  *
4289
- * Parses the given representation of date and time with the given
4290
- * template, and creates a date object. strptime does not support
4291
- * specification of flags and width unlike strftime.
4403
+ * Returns a new \Date object with values parsed from +string+,
4404
+ * according to the given +format+:
4292
4405
  *
4293
- * Date.strptime('2001-02-03', '%Y-%m-%d') #=> #<Date: 2001-02-03 ...>
4294
- * Date.strptime('03-02-2001', '%d-%m-%Y') #=> #<Date: 2001-02-03 ...>
4295
- * Date.strptime('2001-034', '%Y-%j') #=> #<Date: 2001-02-03 ...>
4296
- * Date.strptime('2001-W05-6', '%G-W%V-%u') #=> #<Date: 2001-02-03 ...>
4297
- * Date.strptime('2001 04 6', '%Y %U %w') #=> #<Date: 2001-02-03 ...>
4298
- * Date.strptime('2001 05 6', '%Y %W %u') #=> #<Date: 2001-02-03 ...>
4299
- * Date.strptime('sat3feb01', '%a%d%b%y') #=> #<Date: 2001-02-03 ...>
4406
+ * Date.strptime('2001-02-03', '%Y-%m-%d') # => #<Date: 2001-02-03>
4407
+ * Date.strptime('03-02-2001', '%d-%m-%Y') # => #<Date: 2001-02-03>
4408
+ * Date.strptime('2001-034', '%Y-%j') # => #<Date: 2001-02-03>
4409
+ * Date.strptime('2001-W05-6', '%G-W%V-%u') # => #<Date: 2001-02-03>
4410
+ * Date.strptime('2001 04 6', '%Y %U %w') # => #<Date: 2001-02-03>
4411
+ * Date.strptime('2001 05 6', '%Y %W %u') # => #<Date: 2001-02-03>
4412
+ * Date.strptime('sat3feb01', '%a%d%b%y') # => #<Date: 2001-02-03>
4300
4413
  *
4301
- * See also strptime(3) and #strftime.
4414
+ * For other formats, see
4415
+ * {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc].
4416
+ * (Unlike Date.strftime, does not support flags and width.)
4417
+ *
4418
+ * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
4419
+ *
4420
+ * See also {strptime(3)}[https://man7.org/linux/man-pages/man3/strptime.3.html].
4421
+ *
4422
+ * Related: Date._strptime (returns a hash).
4302
4423
  */
4303
4424
  static VALUE
4304
4425
  date_s_strptime(int argc, VALUE *argv, VALUE klass)
@@ -4309,7 +4430,7 @@ date_s_strptime(int argc, VALUE *argv, VALUE klass)
4309
4430
 
4310
4431
  switch (argc) {
4311
4432
  case 0:
4312
- str = rb_str_new2("-4712-01-01");
4433
+ str = rb_str_new2(JULIAN_EPOCH_DATE);
4313
4434
  case 1:
4314
4435
  fmt = rb_str_new2("%F");
4315
4436
  case 2:
@@ -4339,16 +4460,22 @@ get_limit(VALUE opt)
4339
4460
  return 128;
4340
4461
  }
4341
4462
 
4342
- static void
4463
+ #ifndef HAVE_RB_CATEGORY_WARN
4464
+ #define rb_category_warn(category, fmt) rb_warn(fmt)
4465
+ #endif
4466
+
4467
+ static VALUE
4343
4468
  check_limit(VALUE str, VALUE opt)
4344
4469
  {
4470
+ size_t slen, limit;
4345
4471
  StringValue(str);
4346
- size_t slen = RSTRING_LEN(str);
4347
- size_t limit = get_limit(opt);
4472
+ slen = RSTRING_LEN(str);
4473
+ limit = get_limit(opt);
4348
4474
  if (slen > limit) {
4349
4475
  rb_raise(rb_eArgError,
4350
4476
  "string length (%"PRI_SIZE_PREFIX"u) exceeds the limit %"PRI_SIZE_PREFIX"u", slen, limit);
4351
4477
  }
4478
+ return str;
4352
4479
  }
4353
4480
 
4354
4481
  static VALUE
@@ -4356,10 +4483,8 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
4356
4483
  {
4357
4484
  VALUE vstr, vcomp, hash, opt;
4358
4485
 
4359
- rb_scan_args(argc, argv, "11:", &vstr, &vcomp, &opt);
4360
- if (!NIL_P(opt)) argc--;
4361
- check_limit(vstr, opt);
4362
- StringValue(vstr);
4486
+ argc = rb_scan_args(argc, argv, "11:", &vstr, &vcomp, &opt);
4487
+ vstr = check_limit(vstr, opt);
4363
4488
  if (!rb_enc_str_asciicompat_p(vstr))
4364
4489
  rb_raise(rb_eArgError,
4365
4490
  "string should have ASCII compatible encoding");
@@ -4373,25 +4498,32 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
4373
4498
 
4374
4499
  /*
4375
4500
  * call-seq:
4376
- * Date._parse(string[, comp=true], limit: 128) -> hash
4501
+ * Date._parse(string, comp = true, limit: 128) -> hash
4377
4502
  *
4378
- * Parses the given representation of date and time, and returns a
4379
- * hash of parsed elements.
4503
+ * <b>Note</b>:
4504
+ * This method recognizes many forms in +string+,
4505
+ * but it is not a validator.
4506
+ * For formats, see
4507
+ * {"Specialized Format Strings" in Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc@Specialized+Format+Strings]
4380
4508
  *
4381
- * This method *does not* function as a validator. If the input
4382
- * string does not match valid formats strictly, you may get a cryptic
4383
- * result. Should consider to use `Date._strptime` or
4384
- * `DateTime._strptime` instead of this method as possible.
4509
+ * If +string+ does not specify a valid date,
4510
+ * the result is unpredictable;
4511
+ * consider using Date._strptime instead.
4385
4512
  *
4386
- * If the optional second argument is true and the detected year is in
4387
- * the range "00" to "99", considers the year a 2-digit form and makes
4388
- * it full.
4513
+ * Returns a hash of values parsed from +string+:
4389
4514
  *
4390
- * Date._parse('2001-02-03') #=> {:year=>2001, :mon=>2, :mday=>3}
4515
+ * Date._parse('2001-02-03') # => {:year=>2001, :mon=>2, :mday=>3}
4391
4516
  *
4392
- * Raise an ArgumentError when the string length is longer than _limit_.
4393
- * You can stop this check by passing `limit: nil`, but note that
4394
- * it may take a long time to parse.
4517
+ * If +comp+ is +true+ and the given year is in the range <tt>(0..99)</tt>,
4518
+ * the current century is supplied;
4519
+ * otherwise, the year is taken as given:
4520
+ *
4521
+ * Date._parse('01-02-03', true) # => {:year=>2001, :mon=>2, :mday=>3}
4522
+ * Date._parse('01-02-03', false) # => {:year=>1, :mon=>2, :mday=>3}
4523
+ *
4524
+ * See argument {limit}[rdoc-ref:Date@Argument+limit].
4525
+ *
4526
+ * Related: Date.parse(returns a \Date object).
4395
4527
  */
4396
4528
  static VALUE
4397
4529
  date_s__parse(int argc, VALUE *argv, VALUE klass)
@@ -4401,39 +4533,47 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
4401
4533
 
4402
4534
  /*
4403
4535
  * call-seq:
4404
- * Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]], limit: 128) -> date
4536
+ * Date.parse(string = '-4712-01-01', comp = true, start = Date::ITALY, limit: 128) -> date
4405
4537
  *
4406
- * Parses the given representation of date and time, and creates a
4407
- * date object.
4538
+ * <b>Note</b>:
4539
+ * This method recognizes many forms in +string+,
4540
+ * but it is not a validator.
4541
+ * For formats, see
4542
+ * {"Specialized Format Strings" in Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc@Specialized+Format+Strings]
4543
+ * If +string+ does not specify a valid date,
4544
+ * the result is unpredictable;
4545
+ * consider using Date._strptime instead.
4408
4546
  *
4409
- * This method *does not* function as a validator. If the input
4410
- * string does not match valid formats strictly, you may get a cryptic
4411
- * result. Should consider to use `Date.strptime` instead of this
4412
- * method as possible.
4547
+ * Returns a new \Date object with values parsed from +string+:
4413
4548
  *
4414
- * If the optional second argument is true and the detected year is in
4415
- * the range "00" to "99", considers the year a 2-digit form and makes
4416
- * it full.
4549
+ * Date.parse('2001-02-03') # => #<Date: 2001-02-03>
4550
+ * Date.parse('20010203') # => #<Date: 2001-02-03>
4551
+ * Date.parse('3rd Feb 2001') # => #<Date: 2001-02-03>
4417
4552
  *
4418
- * Date.parse('2001-02-03') #=> #<Date: 2001-02-03 ...>
4419
- * Date.parse('20010203') #=> #<Date: 2001-02-03 ...>
4420
- * Date.parse('3rd Feb 2001') #=> #<Date: 2001-02-03 ...>
4553
+ * If +comp+ is +true+ and the given year is in the range <tt>(0..99)</tt>,
4554
+ * the current century is supplied;
4555
+ * otherwise, the year is taken as given:
4421
4556
  *
4422
- * Raise an ArgumentError when the string length is longer than _limit_.
4423
- * You can stop this check by passing `limit: nil`, but note that
4424
- * it may take a long time to parse.
4557
+ * Date.parse('01-02-03', true) # => #<Date: 2001-02-03>
4558
+ * Date.parse('01-02-03', false) # => #<Date: 0001-02-03>
4559
+ *
4560
+ * See:
4561
+ *
4562
+ * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
4563
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
4564
+ *
4565
+ * Related: Date._parse (returns a hash).
4425
4566
  */
4426
4567
  static VALUE
4427
4568
  date_s_parse(int argc, VALUE *argv, VALUE klass)
4428
4569
  {
4429
4570
  VALUE str, comp, sg, opt;
4430
4571
 
4431
- rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
4432
- if (!NIL_P(opt)) argc--;
4572
+ argc = rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
4433
4573
 
4434
4574
  switch (argc) {
4435
4575
  case 0:
4436
- str = rb_str_new2("-4712-01-01");
4576
+ str = rb_str_new2(JULIAN_EPOCH_DATE);
4437
4577
  case 1:
4438
4578
  comp = Qtrue;
4439
4579
  case 2:
@@ -4442,11 +4582,11 @@ date_s_parse(int argc, VALUE *argv, VALUE klass)
4442
4582
 
4443
4583
  {
4444
4584
  int argc2 = 2;
4445
- VALUE argv2[3];
4585
+ VALUE argv2[3], hash;
4446
4586
  argv2[0] = str;
4447
4587
  argv2[1] = comp;
4448
4588
  if (!NIL_P(opt)) argv2[argc2++] = opt;
4449
- VALUE hash = date_s__parse(argc2, argv2, klass);
4589
+ hash = date_s__parse(argc2, argv2, klass);
4450
4590
  return d_new_by_frags(klass, hash, sg);
4451
4591
  }
4452
4592
  }
@@ -4460,13 +4600,18 @@ VALUE date__jisx0301(VALUE);
4460
4600
 
4461
4601
  /*
4462
4602
  * call-seq:
4463
- * Date._iso8601(string, limit: 128) -> hash
4603
+ * Date._iso8601(string, limit: 128) -> hash
4464
4604
  *
4465
- * Returns a hash of parsed elements.
4605
+ * Returns a hash of values parsed from +string+, which should contain
4606
+ * an {ISO 8601 formatted date}[rdoc-ref:language/strftime_formatting.rdoc@ISO+8601+Format+Specifications]:
4466
4607
  *
4467
- * Raise an ArgumentError when the string length is longer than _limit_.
4468
- * You can stop this check by passing `limit: nil`, but note that
4469
- * it may take a long time to parse.
4608
+ * d = Date.new(2001, 2, 3)
4609
+ * s = d.iso8601 # => "2001-02-03"
4610
+ * Date._iso8601(s) # => {:mday=>3, :year=>2001, :mon=>2}
4611
+ *
4612
+ * See argument {limit}[rdoc-ref:Date@Argument+limit].
4613
+ *
4614
+ * Related: Date.iso8601 (returns a \Date object).
4470
4615
  */
4471
4616
  static VALUE
4472
4617
  date_s__iso8601(int argc, VALUE *argv, VALUE klass)
@@ -4474,60 +4619,69 @@ date_s__iso8601(int argc, VALUE *argv, VALUE klass)
4474
4619
  VALUE str, opt;
4475
4620
 
4476
4621
  rb_scan_args(argc, argv, "1:", &str, &opt);
4477
- check_limit(str, opt);
4622
+ if (!NIL_P(str)) str = check_limit(str, opt);
4478
4623
 
4479
4624
  return date__iso8601(str);
4480
4625
  }
4481
4626
 
4482
4627
  /*
4483
4628
  * call-seq:
4484
- * Date.iso8601(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date
4629
+ * Date.iso8601(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date
4485
4630
  *
4486
- * Creates a new Date object by parsing from a string according to
4487
- * some typical ISO 8601 formats.
4631
+ * Returns a new \Date object with values parsed from +string+,
4632
+ * which should contain
4633
+ * an {ISO 8601 formatted date}[rdoc-ref:language/strftime_formatting.rdoc@ISO+8601+Format+Specifications]:
4488
4634
  *
4489
- * Date.iso8601('2001-02-03') #=> #<Date: 2001-02-03 ...>
4490
- * Date.iso8601('20010203') #=> #<Date: 2001-02-03 ...>
4491
- * Date.iso8601('2001-W05-6') #=> #<Date: 2001-02-03 ...>
4635
+ * d = Date.new(2001, 2, 3)
4636
+ * s = d.iso8601 # => "2001-02-03"
4637
+ * Date.iso8601(s) # => #<Date: 2001-02-03>
4492
4638
  *
4493
- * Raise an ArgumentError when the string length is longer than _limit_.
4494
- * You can stop this check by passing `limit: nil`, but note that
4495
- * it may take a long time to parse.
4639
+ * See:
4640
+ *
4641
+ * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
4642
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
4643
+ *
4644
+ * Related: Date._iso8601 (returns a hash).
4496
4645
  */
4497
4646
  static VALUE
4498
4647
  date_s_iso8601(int argc, VALUE *argv, VALUE klass)
4499
4648
  {
4500
4649
  VALUE str, sg, opt;
4501
4650
 
4502
- rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4503
- if (!NIL_P(opt)) argc--;
4651
+ argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4504
4652
 
4505
4653
  switch (argc) {
4506
4654
  case 0:
4507
- str = rb_str_new2("-4712-01-01");
4655
+ str = rb_str_new2(JULIAN_EPOCH_DATE);
4508
4656
  case 1:
4509
4657
  sg = INT2FIX(DEFAULT_SG);
4510
4658
  }
4511
4659
 
4512
4660
  {
4513
4661
  int argc2 = 1;
4514
- VALUE argv2[2];
4662
+ VALUE argv2[2], hash;
4515
4663
  argv2[0] = str;
4516
4664
  if (!NIL_P(opt)) argv2[argc2++] = opt;
4517
- VALUE hash = date_s__iso8601(argc2, argv2, klass);
4665
+ hash = date_s__iso8601(argc2, argv2, klass);
4518
4666
  return d_new_by_frags(klass, hash, sg);
4519
4667
  }
4520
4668
  }
4521
4669
 
4522
4670
  /*
4523
4671
  * call-seq:
4524
- * Date._rfc3339(string, limit: 128) -> hash
4672
+ * Date._rfc3339(string, limit: 128) -> hash
4525
4673
  *
4526
- * Returns a hash of parsed elements.
4674
+ * Returns a hash of values parsed from +string+, which should be a valid
4675
+ * {RFC 3339 format}[rdoc-ref:language/strftime_formatting.rdoc@RFC+3339+Format]:
4527
4676
  *
4528
- * Raise an ArgumentError when the string length is longer than _limit_.
4529
- * You can stop this check by passing `limit: nil`, but note that
4530
- * it may take a long time to parse.
4677
+ * d = Date.new(2001, 2, 3)
4678
+ * s = d.rfc3339 # => "2001-02-03T00:00:00+00:00"
4679
+ * Date._rfc3339(s)
4680
+ * # => {:year=>2001, :mon=>2, :mday=>3, :hour=>0, :min=>0, :sec=>0, :zone=>"+00:00", :offset=>0}
4681
+ *
4682
+ * See argument {limit}[rdoc-ref:Date@Argument+limit].
4683
+ *
4684
+ * Related: Date.rfc3339 (returns a \Date object).
4531
4685
  */
4532
4686
  static VALUE
4533
4687
  date_s__rfc3339(int argc, VALUE *argv, VALUE klass)
@@ -4535,58 +4689,68 @@ date_s__rfc3339(int argc, VALUE *argv, VALUE klass)
4535
4689
  VALUE str, opt;
4536
4690
 
4537
4691
  rb_scan_args(argc, argv, "1:", &str, &opt);
4538
- check_limit(str, opt);
4692
+ if (!NIL_P(str)) str = check_limit(str, opt);
4539
4693
 
4540
4694
  return date__rfc3339(str);
4541
4695
  }
4542
4696
 
4543
4697
  /*
4544
4698
  * call-seq:
4545
- * Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> date
4699
+ * Date.rfc3339(string = '-4712-01-01T00:00:00+00:00', start = Date::ITALY, limit: 128) -> date
4546
4700
  *
4547
- * Creates a new Date object by parsing from a string according to
4548
- * some typical RFC 3339 formats.
4701
+ * Returns a new \Date object with values parsed from +string+,
4702
+ * which should be a valid
4703
+ * {RFC 3339 format}[rdoc-ref:language/strftime_formatting.rdoc@RFC+3339+Format]:
4549
4704
  *
4550
- * Date.rfc3339('2001-02-03T04:05:06+07:00') #=> #<Date: 2001-02-03 ...>
4705
+ * d = Date.new(2001, 2, 3)
4706
+ * s = d.rfc3339 # => "2001-02-03T00:00:00+00:00"
4707
+ * Date.rfc3339(s) # => #<Date: 2001-02-03>
4551
4708
  *
4552
- * Raise an ArgumentError when the string length is longer than _limit_.
4553
- * You can stop this check by passing `limit: nil`, but note that
4554
- * it may take a long time to parse.
4709
+ * See:
4710
+ *
4711
+ * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
4712
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
4713
+ *
4714
+ * Related: Date._rfc3339 (returns a hash).
4555
4715
  */
4556
4716
  static VALUE
4557
4717
  date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
4558
4718
  {
4559
4719
  VALUE str, sg, opt;
4560
4720
 
4561
- rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4562
- if (!NIL_P(opt)) argc--;
4721
+ argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4563
4722
 
4564
4723
  switch (argc) {
4565
4724
  case 0:
4566
- str = rb_str_new2("-4712-01-01T00:00:00+00:00");
4725
+ str = rb_str_new2(JULIAN_EPOCH_DATETIME);
4567
4726
  case 1:
4568
4727
  sg = INT2FIX(DEFAULT_SG);
4569
4728
  }
4570
4729
 
4571
4730
  {
4572
4731
  int argc2 = 1;
4573
- VALUE argv2[2];
4732
+ VALUE argv2[2], hash;
4574
4733
  argv2[0] = str;
4575
4734
  if (!NIL_P(opt)) argv2[argc2++] = opt;
4576
- VALUE hash = date_s__rfc3339(argc2, argv2, klass);
4735
+ hash = date_s__rfc3339(argc2, argv2, klass);
4577
4736
  return d_new_by_frags(klass, hash, sg);
4578
4737
  }
4579
4738
  }
4580
4739
 
4581
4740
  /*
4582
4741
  * call-seq:
4583
- * Date._xmlschema(string, limit: 128) -> hash
4742
+ * Date._xmlschema(string, limit: 128) -> hash
4584
4743
  *
4585
- * Returns a hash of parsed elements.
4744
+ * Returns a hash of values parsed from +string+, which should be a valid
4745
+ * XML date format:
4586
4746
  *
4587
- * Raise an ArgumentError when the string length is longer than _limit_.
4588
- * You can stop this check by passing `limit: nil`, but note that
4589
- * it may take a long time to parse.
4747
+ * d = Date.new(2001, 2, 3)
4748
+ * s = d.xmlschema # => "2001-02-03"
4749
+ * Date._xmlschema(s) # => {:year=>2001, :mon=>2, :mday=>3}
4750
+ *
4751
+ * See argument {limit}[rdoc-ref:Date@Argument+limit].
4752
+ *
4753
+ * Related: Date.xmlschema (returns a \Date object).
4590
4754
  */
4591
4755
  static VALUE
4592
4756
  date_s__xmlschema(int argc, VALUE *argv, VALUE klass)
@@ -4594,59 +4758,68 @@ date_s__xmlschema(int argc, VALUE *argv, VALUE klass)
4594
4758
  VALUE str, opt;
4595
4759
 
4596
4760
  rb_scan_args(argc, argv, "1:", &str, &opt);
4597
- check_limit(str, opt);
4761
+ if (!NIL_P(str)) str = check_limit(str, opt);
4598
4762
 
4599
4763
  return date__xmlschema(str);
4600
4764
  }
4601
4765
 
4602
4766
  /*
4603
4767
  * call-seq:
4604
- * Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date
4768
+ * Date.xmlschema(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date
4605
4769
  *
4606
- * Creates a new Date object by parsing from a string according to
4607
- * some typical XML Schema formats.
4770
+ * Returns a new \Date object with values parsed from +string+,
4771
+ * which should be a valid XML date format:
4608
4772
  *
4609
- * Date.xmlschema('2001-02-03') #=> #<Date: 2001-02-03 ...>
4773
+ * d = Date.new(2001, 2, 3)
4774
+ * s = d.xmlschema # => "2001-02-03"
4775
+ * Date.xmlschema(s) # => #<Date: 2001-02-03>
4610
4776
  *
4611
- * Raise an ArgumentError when the string length is longer than _limit_.
4612
- * You can stop this check by passing `limit: nil`, but note that
4613
- * it may take a long time to parse.
4777
+ * See:
4778
+ *
4779
+ * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
4780
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
4781
+ *
4782
+ * Related: Date._xmlschema (returns a hash).
4614
4783
  */
4615
4784
  static VALUE
4616
4785
  date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
4617
4786
  {
4618
4787
  VALUE str, sg, opt;
4619
4788
 
4620
- rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4621
- if (!NIL_P(opt)) argc--;
4789
+ argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4622
4790
 
4623
4791
  switch (argc) {
4624
4792
  case 0:
4625
- str = rb_str_new2("-4712-01-01");
4793
+ str = rb_str_new2(JULIAN_EPOCH_DATE);
4626
4794
  case 1:
4627
4795
  sg = INT2FIX(DEFAULT_SG);
4628
4796
  }
4629
4797
 
4630
4798
  {
4631
4799
  int argc2 = 1;
4632
- VALUE argv2[2];
4800
+ VALUE argv2[2], hash;
4633
4801
  argv2[0] = str;
4634
4802
  if (!NIL_P(opt)) argv2[argc2++] = opt;
4635
- VALUE hash = date_s__xmlschema(argc2, argv2, klass);
4803
+ hash = date_s__xmlschema(argc2, argv2, klass);
4636
4804
  return d_new_by_frags(klass, hash, sg);
4637
4805
  }
4638
4806
  }
4639
4807
 
4640
4808
  /*
4641
4809
  * call-seq:
4642
- * Date._rfc2822(string, limit: 128) -> hash
4643
- * Date._rfc822(string, limit: 128) -> hash
4810
+ * Date._rfc2822(string, limit: 128) -> hash
4644
4811
  *
4645
- * Returns a hash of parsed elements.
4812
+ * Returns a hash of values parsed from +string+, which should be a valid
4813
+ * {RFC 2822 date format}[rdoc-ref:language/strftime_formatting.rdoc@RFC+2822+Format]:
4646
4814
  *
4647
- * Raise an ArgumentError when the string length is longer than _limit_.
4648
- * You can stop this check by passing `limit: nil`, but note that
4649
- * it may take a long time to parse.
4815
+ * d = Date.new(2001, 2, 3)
4816
+ * s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000"
4817
+ * Date._rfc2822(s)
4818
+ * # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"+0000", :offset=>0}
4819
+ *
4820
+ * See argument {limit}[rdoc-ref:Date@Argument+limit].
4821
+ *
4822
+ * Related: Date.rfc2822 (returns a \Date object).
4650
4823
  */
4651
4824
  static VALUE
4652
4825
  date_s__rfc2822(int argc, VALUE *argv, VALUE klass)
@@ -4654,59 +4827,67 @@ date_s__rfc2822(int argc, VALUE *argv, VALUE klass)
4654
4827
  VALUE str, opt;
4655
4828
 
4656
4829
  rb_scan_args(argc, argv, "1:", &str, &opt);
4657
- check_limit(str, opt);
4830
+ if (!NIL_P(str)) str = check_limit(str, opt);
4658
4831
 
4659
4832
  return date__rfc2822(str);
4660
4833
  }
4661
4834
 
4662
4835
  /*
4663
4836
  * call-seq:
4664
- * Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> date
4665
- * Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> date
4837
+ * Date.rfc2822(string = 'Mon, 1 Jan -4712 00:00:00 +0000', start = Date::ITALY, limit: 128) -> date
4666
4838
  *
4667
- * Creates a new Date object by parsing from a string according to
4668
- * some typical RFC 2822 formats.
4839
+ * Returns a new \Date object with values parsed from +string+,
4840
+ * which should be a valid
4841
+ * {RFC 2822 date format}[rdoc-ref:language/strftime_formatting.rdoc@RFC+2822+Format]:
4669
4842
  *
4670
- * Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000')
4671
- * #=> #<Date: 2001-02-03 ...>
4843
+ * d = Date.new(2001, 2, 3)
4844
+ * s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000"
4845
+ * Date.rfc2822(s) # => #<Date: 2001-02-03>
4672
4846
  *
4673
- * Raise an ArgumentError when the string length is longer than _limit_.
4674
- * You can stop this check by passing `limit: nil`, but note that
4675
- * it may take a long time to parse.
4847
+ * See:
4848
+ *
4849
+ * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
4850
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
4851
+ *
4852
+ * Related: Date._rfc2822 (returns a hash).
4676
4853
  */
4677
4854
  static VALUE
4678
4855
  date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
4679
4856
  {
4680
4857
  VALUE str, sg, opt;
4681
4858
 
4682
- rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4859
+ argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4683
4860
 
4684
4861
  switch (argc) {
4685
4862
  case 0:
4686
- str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000");
4863
+ str = rb_str_new2(JULIAN_EPOCH_DATETIME_RFC3339);
4687
4864
  case 1:
4688
4865
  sg = INT2FIX(DEFAULT_SG);
4689
4866
  }
4690
4867
 
4691
4868
  {
4692
4869
  int argc2 = 1;
4693
- VALUE argv2[2];
4870
+ VALUE argv2[2], hash;
4694
4871
  argv2[0] = str;
4695
4872
  if (!NIL_P(opt)) argv2[argc2++] = opt;
4696
- VALUE hash = date_s__rfc2822(argc2, argv2, klass);
4873
+ hash = date_s__rfc2822(argc2, argv2, klass);
4697
4874
  return d_new_by_frags(klass, hash, sg);
4698
4875
  }
4699
4876
  }
4700
4877
 
4701
4878
  /*
4702
4879
  * call-seq:
4703
- * Date._httpdate(string, limit: 128) -> hash
4880
+ * Date._httpdate(string, limit: 128) -> hash
4704
4881
  *
4705
- * Returns a hash of parsed elements.
4882
+ * Returns a hash of values parsed from +string+, which should be a valid
4883
+ * {HTTP date format}[rdoc-ref:language/strftime_formatting.rdoc@HTTP+Format]:
4706
4884
  *
4707
- * Raise an ArgumentError when the string length is longer than _limit_.
4708
- * You can stop this check by passing `limit: nil`, but note that
4709
- * it may take a long time to parse.
4885
+ * d = Date.new(2001, 2, 3)
4886
+ * s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT"
4887
+ * Date._httpdate(s)
4888
+ * # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"GMT", :offset=>0}
4889
+ *
4890
+ * Related: Date.httpdate (returns a \Date object).
4710
4891
  */
4711
4892
  static VALUE
4712
4893
  date_s__httpdate(int argc, VALUE *argv, VALUE klass)
@@ -4714,58 +4895,68 @@ date_s__httpdate(int argc, VALUE *argv, VALUE klass)
4714
4895
  VALUE str, opt;
4715
4896
 
4716
4897
  rb_scan_args(argc, argv, "1:", &str, &opt);
4717
- check_limit(str, opt);
4898
+ if (!NIL_P(str)) str = check_limit(str, opt);
4718
4899
 
4719
4900
  return date__httpdate(str);
4720
4901
  }
4721
4902
 
4722
4903
  /*
4723
4904
  * call-seq:
4724
- * Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY], limit: 128) -> date
4905
+ * Date.httpdate(string = 'Mon, 01 Jan -4712 00:00:00 GMT', start = Date::ITALY, limit: 128) -> date
4725
4906
  *
4726
- * Creates a new Date object by parsing from a string according to
4727
- * some RFC 2616 format.
4907
+ * Returns a new \Date object with values parsed from +string+,
4908
+ * which should be a valid
4909
+ * {HTTP date format}[rdoc-ref:language/strftime_formatting.rdoc@HTTP+Format]:
4728
4910
  *
4729
- * Date.httpdate('Sat, 03 Feb 2001 00:00:00 GMT')
4730
- * #=> #<Date: 2001-02-03 ...>
4911
+ * d = Date.new(2001, 2, 3)
4912
+ s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT"
4913
+ Date.httpdate(s) # => #<Date: 2001-02-03>
4731
4914
  *
4732
- * Raise an ArgumentError when the string length is longer than _limit_.
4733
- * You can stop this check by passing `limit: nil`, but note that
4734
- * it may take a long time to parse.
4915
+ * See:
4916
+ *
4917
+ * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
4918
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
4919
+ *
4920
+ * Related: Date._httpdate (returns a hash).
4735
4921
  */
4736
4922
  static VALUE
4737
4923
  date_s_httpdate(int argc, VALUE *argv, VALUE klass)
4738
4924
  {
4739
4925
  VALUE str, sg, opt;
4740
4926
 
4741
- rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4927
+ argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4742
4928
 
4743
4929
  switch (argc) {
4744
4930
  case 0:
4745
- str = rb_str_new2("Mon, 01 Jan -4712 00:00:00 GMT");
4931
+ str = rb_str_new2(JULIAN_EPOCH_DATETIME_HTTPDATE);
4746
4932
  case 1:
4747
4933
  sg = INT2FIX(DEFAULT_SG);
4748
4934
  }
4749
4935
 
4750
4936
  {
4751
4937
  int argc2 = 1;
4752
- VALUE argv2[2];
4938
+ VALUE argv2[2], hash;
4753
4939
  argv2[0] = str;
4754
4940
  if (!NIL_P(opt)) argv2[argc2++] = opt;
4755
- VALUE hash = date_s__httpdate(argc2, argv2, klass);
4941
+ hash = date_s__httpdate(argc2, argv2, klass);
4756
4942
  return d_new_by_frags(klass, hash, sg);
4757
4943
  }
4758
4944
  }
4759
4945
 
4760
4946
  /*
4761
4947
  * call-seq:
4762
- * Date._jisx0301(string, limit: 128) -> hash
4948
+ * Date._jisx0301(string, limit: 128) -> hash
4763
4949
  *
4764
- * Returns a hash of parsed elements.
4950
+ * Returns a hash of values parsed from +string+, which should be a valid
4951
+ * {JIS X 0301 date format}[rdoc-ref:language/strftime_formatting.rdoc@JIS+X+0301+Format]:
4765
4952
  *
4766
- * Raise an ArgumentError when the string length is longer than _limit_.
4767
- * You can stop this check by passing `limit: nil`, but note that
4768
- * it may take a long time to parse.
4953
+ * d = Date.new(2001, 2, 3)
4954
+ * s = d.jisx0301 # => "H13.02.03"
4955
+ * Date._jisx0301(s) # => {:year=>2001, :mon=>2, :mday=>3}
4956
+ *
4957
+ * See argument {limit}[rdoc-ref:Date@Argument+limit].
4958
+ *
4959
+ * Related: Date.jisx0301 (returns a \Date object).
4769
4960
  */
4770
4961
  static VALUE
4771
4962
  date_s__jisx0301(int argc, VALUE *argv, VALUE klass)
@@ -4773,49 +4964,53 @@ date_s__jisx0301(int argc, VALUE *argv, VALUE klass)
4773
4964
  VALUE str, opt;
4774
4965
 
4775
4966
  rb_scan_args(argc, argv, "1:", &str, &opt);
4776
- check_limit(str, opt);
4967
+ if (!NIL_P(str)) str = check_limit(str, opt);
4777
4968
 
4778
4969
  return date__jisx0301(str);
4779
4970
  }
4780
4971
 
4781
4972
  /*
4782
4973
  * call-seq:
4783
- * Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY], limit: 128) -> date
4974
+ * Date.jisx0301(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date
4784
4975
  *
4785
- * Creates a new Date object by parsing from a string according to
4786
- * some typical JIS X 0301 formats.
4976
+ * Returns a new \Date object with values parsed from +string+,
4977
+ * which should be a valid {JIS X 0301 format}[rdoc-ref:language/strftime_formatting.rdoc@JIS+X+0301+Format]:
4787
4978
  *
4788
- * Date.jisx0301('H13.02.03') #=> #<Date: 2001-02-03 ...>
4979
+ * d = Date.new(2001, 2, 3)
4980
+ * s = d.jisx0301 # => "H13.02.03"
4981
+ * Date.jisx0301(s) # => #<Date: 2001-02-03>
4789
4982
  *
4790
4983
  * For no-era year, legacy format, Heisei is assumed.
4791
4984
  *
4792
- * Date.jisx0301('13.02.03') #=> #<Date: 2001-02-03 ...>
4985
+ * Date.jisx0301('13.02.03') # => #<Date: 2001-02-03>
4793
4986
  *
4794
- * Raise an ArgumentError when the string length is longer than _limit_.
4795
- * You can stop this check by passing `limit: nil`, but note that
4796
- * it may take a long time to parse.
4987
+ * See:
4988
+ *
4989
+ * - Argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
4990
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
4991
+ *
4992
+ * Related: Date._jisx0301 (returns a hash).
4797
4993
  */
4798
4994
  static VALUE
4799
4995
  date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
4800
4996
  {
4801
4997
  VALUE str, sg, opt;
4802
4998
 
4803
- rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4804
- if (!NIL_P(opt)) argc--;
4999
+ argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4805
5000
 
4806
5001
  switch (argc) {
4807
5002
  case 0:
4808
- str = rb_str_new2("-4712-01-01");
5003
+ str = rb_str_new2(JULIAN_EPOCH_DATE);
4809
5004
  case 1:
4810
5005
  sg = INT2FIX(DEFAULT_SG);
4811
5006
  }
4812
5007
 
4813
5008
  {
4814
5009
  int argc2 = 1;
4815
- VALUE argv2[2];
5010
+ VALUE argv2[2], hash;
4816
5011
  argv2[0] = str;
4817
5012
  if (!NIL_P(opt)) argv2[argc2++] = opt;
4818
- VALUE hash = date_s__jisx0301(argc2, argv2, klass);
5013
+ hash = date_s__jisx0301(argc2, argv2, klass);
4819
5014
  return d_new_by_frags(klass, hash, sg);
4820
5015
  }
4821
5016
  }
@@ -4985,6 +5180,7 @@ d_lite_initialize_copy(VALUE copy, VALUE date)
4985
5180
  }
4986
5181
 
4987
5182
  #ifndef NDEBUG
5183
+ /* :nodoc: */
4988
5184
  static VALUE
4989
5185
  d_lite_fill(VALUE self)
4990
5186
  {
@@ -5074,12 +5270,15 @@ d_lite_mjd(VALUE self)
5074
5270
 
5075
5271
  /*
5076
5272
  * call-seq:
5077
- * d.ld -> integer
5273
+ * ld -> integer
5078
5274
  *
5079
- * Returns the Lilian day number. This is a whole number, which is
5080
- * adjusted by the offset as the local time.
5275
+ * Returns the
5276
+ * {Lilian day number}[https://en.wikipedia.org/wiki/Lilian_date],
5277
+ * which is the number of days since the beginning of the Gregorian
5278
+ * calendar, October 15, 1582.
5279
+ *
5280
+ * Date.new(2001, 2, 3).ld # => 152784
5081
5281
  *
5082
- * Date.new(2001,2,3).ld #=> 152784
5083
5282
  */
5084
5283
  static VALUE
5085
5284
  d_lite_ld(VALUE self)
@@ -5090,12 +5289,13 @@ d_lite_ld(VALUE self)
5090
5289
 
5091
5290
  /*
5092
5291
  * call-seq:
5093
- * d.year -> integer
5292
+ * year -> integer
5293
+ *
5294
+ * Returns the year:
5094
5295
  *
5095
- * Returns the year.
5296
+ * Date.new(2001, 2, 3).year # => 2001
5297
+ * (Date.new(1, 1, 1) - 1).year # => 0
5096
5298
  *
5097
- * Date.new(2001,2,3).year #=> 2001
5098
- * (Date.new(1,1,1) - 1).year #=> 0
5099
5299
  */
5100
5300
  static VALUE
5101
5301
  d_lite_year(VALUE self)
@@ -5106,11 +5306,12 @@ d_lite_year(VALUE self)
5106
5306
 
5107
5307
  /*
5108
5308
  * call-seq:
5109
- * d.yday -> fixnum
5309
+ * yday -> integer
5110
5310
  *
5111
- * Returns the day of the year (1-366).
5311
+ * Returns the day of the year, in range (1..366):
5312
+ *
5313
+ * Date.new(2001, 2, 3).yday # => 34
5112
5314
  *
5113
- * Date.new(2001,2,3).yday #=> 34
5114
5315
  */
5115
5316
  static VALUE
5116
5317
  d_lite_yday(VALUE self)
@@ -5121,12 +5322,12 @@ d_lite_yday(VALUE self)
5121
5322
 
5122
5323
  /*
5123
5324
  * call-seq:
5124
- * d.mon -> fixnum
5125
- * d.month -> fixnum
5325
+ * mon -> integer
5326
+ *
5327
+ * Returns the month in range (1..12):
5126
5328
  *
5127
- * Returns the month (1-12).
5329
+ * Date.new(2001, 2, 3).mon # => 2
5128
5330
  *
5129
- * Date.new(2001,2,3).mon #=> 2
5130
5331
  */
5131
5332
  static VALUE
5132
5333
  d_lite_mon(VALUE self)
@@ -5137,12 +5338,12 @@ d_lite_mon(VALUE self)
5137
5338
 
5138
5339
  /*
5139
5340
  * call-seq:
5140
- * d.mday -> fixnum
5141
- * d.day -> fixnum
5341
+ * mday -> integer
5342
+ *
5343
+ * Returns the day of the month in range (1..31):
5142
5344
  *
5143
- * Returns the day of the month (1-31).
5345
+ * Date.new(2001, 2, 3).mday # => 3
5144
5346
  *
5145
- * Date.new(2001,2,3).mday #=> 3
5146
5347
  */
5147
5348
  static VALUE
5148
5349
  d_lite_mday(VALUE self)
@@ -5153,11 +5354,12 @@ d_lite_mday(VALUE self)
5153
5354
 
5154
5355
  /*
5155
5356
  * call-seq:
5156
- * d.day_fraction -> rational
5357
+ * day_fraction -> rational
5157
5358
  *
5158
- * Returns the fractional part of the day.
5359
+ * Returns the fractional part of the day in range (Rational(0, 1)...Rational(1, 1)):
5360
+ *
5361
+ * DateTime.new(2001,2,3,12).day_fraction # => (1/2)
5159
5362
  *
5160
- * DateTime.new(2001,2,3,12).day_fraction #=> (1/2)
5161
5363
  */
5162
5364
  static VALUE
5163
5365
  d_lite_day_fraction(VALUE self)
@@ -5170,12 +5372,14 @@ d_lite_day_fraction(VALUE self)
5170
5372
 
5171
5373
  /*
5172
5374
  * call-seq:
5173
- * d.cwyear -> integer
5375
+ * cwyear -> integer
5376
+ *
5377
+ * Returns commercial-date year for +self+
5378
+ * (see Date.commercial):
5174
5379
  *
5175
- * Returns the calendar week based year.
5380
+ * Date.new(2001, 2, 3).cwyear # => 2001
5381
+ * Date.new(2000, 1, 1).cwyear # => 1999
5176
5382
  *
5177
- * Date.new(2001,2,3).cwyear #=> 2001
5178
- * Date.new(2000,1,1).cwyear #=> 1999
5179
5383
  */
5180
5384
  static VALUE
5181
5385
  d_lite_cwyear(VALUE self)
@@ -5186,11 +5390,13 @@ d_lite_cwyear(VALUE self)
5186
5390
 
5187
5391
  /*
5188
5392
  * call-seq:
5189
- * d.cweek -> fixnum
5393
+ * cweek -> integer
5394
+ *
5395
+ * Returns commercial-date week index for +self+
5396
+ * (see Date.commercial):
5190
5397
  *
5191
- * Returns the calendar week number (1-53).
5398
+ * Date.new(2001, 2, 3).cweek # => 5
5192
5399
  *
5193
- * Date.new(2001,2,3).cweek #=> 5
5194
5400
  */
5195
5401
  static VALUE
5196
5402
  d_lite_cweek(VALUE self)
@@ -5201,11 +5407,14 @@ d_lite_cweek(VALUE self)
5201
5407
 
5202
5408
  /*
5203
5409
  * call-seq:
5204
- * d.cwday -> fixnum
5410
+ * cwday -> integer
5205
5411
  *
5206
- * Returns the day of calendar week (1-7, Monday is 1).
5412
+ * Returns the commercial-date weekday index for +self+
5413
+ * (see Date.commercial);
5414
+ * 1 is Monday:
5415
+ *
5416
+ * Date.new(2001, 2, 3).cwday # => 6
5207
5417
  *
5208
- * Date.new(2001,2,3).cwday #=> 6
5209
5418
  */
5210
5419
  static VALUE
5211
5420
  d_lite_cwday(VALUE self)
@@ -5215,6 +5424,7 @@ d_lite_cwday(VALUE self)
5215
5424
  }
5216
5425
 
5217
5426
  #ifndef NDEBUG
5427
+ /* :nodoc: */
5218
5428
  static VALUE
5219
5429
  d_lite_wnum0(VALUE self)
5220
5430
  {
@@ -5222,6 +5432,7 @@ d_lite_wnum0(VALUE self)
5222
5432
  return INT2FIX(m_wnum0(dat));
5223
5433
  }
5224
5434
 
5435
+ /* :nodoc: */
5225
5436
  static VALUE
5226
5437
  d_lite_wnum1(VALUE self)
5227
5438
  {
@@ -5232,11 +5443,12 @@ d_lite_wnum1(VALUE self)
5232
5443
 
5233
5444
  /*
5234
5445
  * call-seq:
5235
- * d.wday -> fixnum
5446
+ * wday -> integer
5236
5447
  *
5237
- * Returns the day of week (0-6, Sunday is zero).
5448
+ * Returns the day of week in range (0..6); Sunday is 0:
5449
+ *
5450
+ * Date.new(2001, 2, 3).wday # => 6
5238
5451
  *
5239
- * Date.new(2001,2,3).wday #=> 6
5240
5452
  */
5241
5453
  static VALUE
5242
5454
  d_lite_wday(VALUE self)
@@ -5247,9 +5459,9 @@ d_lite_wday(VALUE self)
5247
5459
 
5248
5460
  /*
5249
5461
  * call-seq:
5250
- * d.sunday? -> bool
5462
+ * sunday? -> true or false
5251
5463
  *
5252
- * Returns true if the date is Sunday.
5464
+ * Returns +true+ if +self+ is a Sunday, +false+ otherwise.
5253
5465
  */
5254
5466
  static VALUE
5255
5467
  d_lite_sunday_p(VALUE self)
@@ -5260,9 +5472,9 @@ d_lite_sunday_p(VALUE self)
5260
5472
 
5261
5473
  /*
5262
5474
  * call-seq:
5263
- * d.monday? -> bool
5475
+ * monday? -> true or false
5264
5476
  *
5265
- * Returns true if the date is Monday.
5477
+ * Returns +true+ if +self+ is a Monday, +false+ otherwise.
5266
5478
  */
5267
5479
  static VALUE
5268
5480
  d_lite_monday_p(VALUE self)
@@ -5273,9 +5485,9 @@ d_lite_monday_p(VALUE self)
5273
5485
 
5274
5486
  /*
5275
5487
  * call-seq:
5276
- * d.tuesday? -> bool
5488
+ * tuesday? -> true or false
5277
5489
  *
5278
- * Returns true if the date is Tuesday.
5490
+ * Returns +true+ if +self+ is a Tuesday, +false+ otherwise.
5279
5491
  */
5280
5492
  static VALUE
5281
5493
  d_lite_tuesday_p(VALUE self)
@@ -5286,9 +5498,9 @@ d_lite_tuesday_p(VALUE self)
5286
5498
 
5287
5499
  /*
5288
5500
  * call-seq:
5289
- * d.wednesday? -> bool
5501
+ * wednesday? -> true or false
5290
5502
  *
5291
- * Returns true if the date is Wednesday.
5503
+ * Returns +true+ if +self+ is a Wednesday, +false+ otherwise.
5292
5504
  */
5293
5505
  static VALUE
5294
5506
  d_lite_wednesday_p(VALUE self)
@@ -5299,9 +5511,9 @@ d_lite_wednesday_p(VALUE self)
5299
5511
 
5300
5512
  /*
5301
5513
  * call-seq:
5302
- * d.thursday? -> bool
5514
+ * thursday? -> true or false
5303
5515
  *
5304
- * Returns true if the date is Thursday.
5516
+ * Returns +true+ if +self+ is a Thursday, +false+ otherwise.
5305
5517
  */
5306
5518
  static VALUE
5307
5519
  d_lite_thursday_p(VALUE self)
@@ -5312,9 +5524,9 @@ d_lite_thursday_p(VALUE self)
5312
5524
 
5313
5525
  /*
5314
5526
  * call-seq:
5315
- * d.friday? -> bool
5527
+ * friday? -> true or false
5316
5528
  *
5317
- * Returns true if the date is Friday.
5529
+ * Returns +true+ if +self+ is a Friday, +false+ otherwise.
5318
5530
  */
5319
5531
  static VALUE
5320
5532
  d_lite_friday_p(VALUE self)
@@ -5325,9 +5537,9 @@ d_lite_friday_p(VALUE self)
5325
5537
 
5326
5538
  /*
5327
5539
  * call-seq:
5328
- * d.saturday? -> bool
5540
+ * saturday? -> true or false
5329
5541
  *
5330
- * Returns true if the date is Saturday.
5542
+ * Returns +true+ if +self+ is a Saturday, +false+ otherwise.
5331
5543
  */
5332
5544
  static VALUE
5333
5545
  d_lite_saturday_p(VALUE self)
@@ -5337,6 +5549,7 @@ d_lite_saturday_p(VALUE self)
5337
5549
  }
5338
5550
 
5339
5551
  #ifndef NDEBUG
5552
+ /* :nodoc: */
5340
5553
  static VALUE
5341
5554
  d_lite_nth_kday_p(VALUE self, VALUE n, VALUE k)
5342
5555
  {
@@ -5358,11 +5571,12 @@ d_lite_nth_kday_p(VALUE self, VALUE n, VALUE k)
5358
5571
 
5359
5572
  /*
5360
5573
  * call-seq:
5361
- * d.hour -> fixnum
5574
+ * hour -> integer
5362
5575
  *
5363
- * Returns the hour (0-23).
5576
+ * Returns the hour in range (0..23):
5577
+ *
5578
+ * DateTime.new(2001, 2, 3, 4, 5, 6).hour # => 4
5364
5579
  *
5365
- * DateTime.new(2001,2,3,4,5,6).hour #=> 4
5366
5580
  */
5367
5581
  static VALUE
5368
5582
  d_lite_hour(VALUE self)
@@ -5373,12 +5587,12 @@ d_lite_hour(VALUE self)
5373
5587
 
5374
5588
  /*
5375
5589
  * call-seq:
5376
- * d.min -> fixnum
5377
- * d.minute -> fixnum
5590
+ * min -> integer
5591
+ *
5592
+ * Returns the minute in range (0..59):
5378
5593
  *
5379
- * Returns the minute (0-59).
5594
+ * DateTime.new(2001, 2, 3, 4, 5, 6).min # => 5
5380
5595
  *
5381
- * DateTime.new(2001,2,3,4,5,6).min #=> 5
5382
5596
  */
5383
5597
  static VALUE
5384
5598
  d_lite_min(VALUE self)
@@ -5389,12 +5603,12 @@ d_lite_min(VALUE self)
5389
5603
 
5390
5604
  /*
5391
5605
  * call-seq:
5392
- * d.sec -> fixnum
5393
- * d.second -> fixnum
5606
+ * sec -> integer
5607
+ *
5608
+ * Returns the second in range (0..59):
5394
5609
  *
5395
- * Returns the second (0-59).
5610
+ * DateTime.new(2001, 2, 3, 4, 5, 6).sec # => 6
5396
5611
  *
5397
- * DateTime.new(2001,2,3,4,5,6).sec #=> 6
5398
5612
  */
5399
5613
  static VALUE
5400
5614
  d_lite_sec(VALUE self)
@@ -5405,12 +5619,13 @@ d_lite_sec(VALUE self)
5405
5619
 
5406
5620
  /*
5407
5621
  * call-seq:
5408
- * d.sec_fraction -> rational
5409
- * d.second_fraction -> rational
5622
+ * sec_fraction -> rational
5410
5623
  *
5411
- * Returns the fractional part of the second.
5624
+ * Returns the fractional part of the second in range
5625
+ * (Rational(0, 1)...Rational(1, 1)):
5626
+ *
5627
+ * DateTime.new(2001, 2, 3, 4, 5, 6.5).sec_fraction # => (1/2)
5412
5628
  *
5413
- * DateTime.new(2001,2,3,4,5,6.5).sec_fraction #=> (1/2)
5414
5629
  */
5415
5630
  static VALUE
5416
5631
  d_lite_sec_fraction(VALUE self)
@@ -5451,12 +5666,14 @@ d_lite_zone(VALUE self)
5451
5666
 
5452
5667
  /*
5453
5668
  * call-seq:
5454
- * d.julian? -> bool
5669
+ * d.julian? -> true or false
5670
+ *
5671
+ * Returns +true+ if the date is before the date of calendar reform,
5672
+ * +false+ otherwise:
5455
5673
  *
5456
- * Returns true if the date is before the day of calendar reform.
5674
+ * (Date.new(1582, 10, 15) - 1).julian? # => true
5675
+ * Date.new(1582, 10, 15).julian? # => false
5457
5676
  *
5458
- * Date.new(1582,10,15).julian? #=> false
5459
- * (Date.new(1582,10,15) - 1).julian? #=> true
5460
5677
  */
5461
5678
  static VALUE
5462
5679
  d_lite_julian_p(VALUE self)
@@ -5467,12 +5684,14 @@ d_lite_julian_p(VALUE self)
5467
5684
 
5468
5685
  /*
5469
5686
  * call-seq:
5470
- * d.gregorian? -> bool
5687
+ * gregorian? -> true or false
5688
+ *
5689
+ * Returns +true+ if the date is on or after
5690
+ * the date of calendar reform, +false+ otherwise:
5471
5691
  *
5472
- * Returns true if the date is on or after the day of calendar reform.
5692
+ * Date.new(1582, 10, 15).gregorian? # => true
5693
+ * (Date.new(1582, 10, 15) - 1).gregorian? # => false
5473
5694
  *
5474
- * Date.new(1582,10,15).gregorian? #=> true
5475
- * (Date.new(1582,10,15) - 1).gregorian? #=> false
5476
5695
  */
5477
5696
  static VALUE
5478
5697
  d_lite_gregorian_p(VALUE self)
@@ -5483,12 +5702,13 @@ d_lite_gregorian_p(VALUE self)
5483
5702
 
5484
5703
  /*
5485
5704
  * call-seq:
5486
- * d.leap? -> bool
5705
+ * leap? -> true or false
5487
5706
  *
5488
- * Returns true if the year is a leap year.
5707
+ * Returns +true+ if the year is a leap year, +false+ otherwise:
5708
+ *
5709
+ * Date.new(2000).leap? # => true
5710
+ * Date.new(2001).leap? # => false
5489
5711
  *
5490
- * Date.new(2000).leap? #=> true
5491
- * Date.new(2001).leap? #=> false
5492
5712
  */
5493
5713
  static VALUE
5494
5714
  d_lite_leap_p(VALUE self)
@@ -5507,12 +5727,25 @@ d_lite_leap_p(VALUE self)
5507
5727
 
5508
5728
  /*
5509
5729
  * call-seq:
5510
- * d.start -> float
5730
+ * start -> float
5731
+ *
5732
+ * Returns the Julian start date for calendar reform;
5733
+ * if not an infinity, the returned value is suitable
5734
+ * for passing to Date#jd:
5735
+ *
5736
+ * d = Date.new(2001, 2, 3, Date::ITALY)
5737
+ * s = d.start # => 2299161.0
5738
+ * Date.jd(s).to_s # => "1582-10-15"
5739
+ *
5740
+ * d = Date.new(2001, 2, 3, Date::ENGLAND)
5741
+ * s = d.start # => 2361222.0
5742
+ * Date.jd(s).to_s # => "1752-09-14"
5743
+ *
5744
+ * Date.new(2001, 2, 3, Date::GREGORIAN).start # => -Infinity
5745
+ * Date.new(2001, 2, 3, Date::JULIAN).start # => Infinity
5511
5746
  *
5512
- * Returns the Julian day number denoting the day of calendar reform.
5747
+ * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
5513
5748
  *
5514
- * Date.new(2001,2,3).start #=> 2299161.0
5515
- * Date.new(2001,2,3,Date::GREGORIAN).start #=> -Infinity
5516
5749
  */
5517
5750
  static VALUE
5518
5751
  d_lite_start(VALUE self)
@@ -5577,12 +5810,17 @@ dup_obj_with_new_start(VALUE obj, double sg)
5577
5810
 
5578
5811
  /*
5579
5812
  * call-seq:
5580
- * d.new_start([start=Date::ITALY]) -> date
5813
+ * new_start(start = Date::ITALY]) -> new_date
5581
5814
  *
5582
- * Duplicates self and resets its day of calendar reform.
5815
+ * Returns a copy of +self+ with the given +start+ value:
5816
+ *
5817
+ * d0 = Date.new(2000, 2, 3)
5818
+ * d0.julian? # => false
5819
+ * d1 = d0.new_start(Date::JULIAN)
5820
+ * d1.julian? # => true
5821
+ *
5822
+ * See argument {start}[rdoc-ref:language/calendars.rdoc@Argument+start].
5583
5823
  *
5584
- * d = Date.new(1582,10,15)
5585
- * d.new_start(Date::JULIAN) #=> #<Date: 1582-10-05 ...>
5586
5824
  */
5587
5825
  static VALUE
5588
5826
  d_lite_new_start(int argc, VALUE *argv, VALUE self)
@@ -5601,9 +5839,10 @@ d_lite_new_start(int argc, VALUE *argv, VALUE self)
5601
5839
 
5602
5840
  /*
5603
5841
  * call-seq:
5604
- * d.italy -> date
5842
+ * italy -> new_date
5843
+ *
5844
+ * Equivalent to Date#new_start with argument Date::ITALY.
5605
5845
  *
5606
- * This method is equivalent to new_start(Date::ITALY).
5607
5846
  */
5608
5847
  static VALUE
5609
5848
  d_lite_italy(VALUE self)
@@ -5613,9 +5852,9 @@ d_lite_italy(VALUE self)
5613
5852
 
5614
5853
  /*
5615
5854
  * call-seq:
5616
- * d.england -> date
5855
+ * england -> new_date
5617
5856
  *
5618
- * This method is equivalent to new_start(Date::ENGLAND).
5857
+ * Equivalent to Date#new_start with argument Date::ENGLAND.
5619
5858
  */
5620
5859
  static VALUE
5621
5860
  d_lite_england(VALUE self)
@@ -5625,9 +5864,9 @@ d_lite_england(VALUE self)
5625
5864
 
5626
5865
  /*
5627
5866
  * call-seq:
5628
- * d.julian -> date
5867
+ * julian -> new_date
5629
5868
  *
5630
- * This method is equivalent to new_start(Date::JULIAN).
5869
+ * Equivalent to Date#new_start with argument Date::JULIAN.
5631
5870
  */
5632
5871
  static VALUE
5633
5872
  d_lite_julian(VALUE self)
@@ -5637,9 +5876,9 @@ d_lite_julian(VALUE self)
5637
5876
 
5638
5877
  /*
5639
5878
  * call-seq:
5640
- * d.gregorian -> date
5879
+ * gregorian -> new_date
5641
5880
  *
5642
- * This method is equivalent to new_start(Date::GREGORIAN).
5881
+ * Equivalent to Date#new_start with argument Date::GREGORIAN.
5643
5882
  */
5644
5883
  static VALUE
5645
5884
  d_lite_gregorian(VALUE self)
@@ -6085,9 +6324,11 @@ minus_dd(VALUE self, VALUE other)
6085
6324
  * call-seq:
6086
6325
  * d - other -> date or rational
6087
6326
  *
6088
- * Returns the difference between the two dates if the other is a date
6089
- * object. If the other is a numeric value, returns a date object
6090
- * pointing +other+ days before self. If the other is a fractional number,
6327
+ * If the other is a date object, returns a Rational
6328
+ * whose value is the difference between the two dates in days.
6329
+ * If the other is a numeric value, returns a date object
6330
+ * pointing +other+ days before self.
6331
+ * If the other is a fractional number,
6091
6332
  * assumes its precision is at most nanosecond.
6092
6333
  *
6093
6334
  * Date.new(2001,2,3) - 1 #=> #<Date: 2001-02-02 ...>
@@ -6120,9 +6361,9 @@ d_lite_minus(VALUE self, VALUE other)
6120
6361
 
6121
6362
  /*
6122
6363
  * call-seq:
6123
- * d.next_day([n=1]) -> date
6364
+ * next_day(n = 1) -> new_date
6124
6365
  *
6125
- * This method is equivalent to d + n.
6366
+ * Equivalent to Date#+ with argument +n+.
6126
6367
  */
6127
6368
  static VALUE
6128
6369
  d_lite_next_day(int argc, VALUE *argv, VALUE self)
@@ -6137,9 +6378,9 @@ d_lite_next_day(int argc, VALUE *argv, VALUE self)
6137
6378
 
6138
6379
  /*
6139
6380
  * call-seq:
6140
- * d.prev_day([n=1]) -> date
6381
+ * prev_day(n = 1) -> new_date
6141
6382
  *
6142
- * This method is equivalent to d - n.
6383
+ * Equivalent to Date#- with argument +n+.
6143
6384
  */
6144
6385
  static VALUE
6145
6386
  d_lite_prev_day(int argc, VALUE *argv, VALUE self)
@@ -6154,10 +6395,14 @@ d_lite_prev_day(int argc, VALUE *argv, VALUE self)
6154
6395
 
6155
6396
  /*
6156
6397
  * call-seq:
6157
- * d.succ -> date
6158
- * d.next -> date
6398
+ * d.next -> new_date
6399
+ *
6400
+ * Returns a new \Date object representing the following day:
6401
+ *
6402
+ * d = Date.new(2001, 2, 3)
6403
+ * d.to_s # => "2001-02-03"
6404
+ * d.next.to_s # => "2001-02-04"
6159
6405
  *
6160
- * Returns a date object denoting the following day.
6161
6406
  */
6162
6407
  static VALUE
6163
6408
  d_lite_next(VALUE self)
@@ -6167,26 +6412,30 @@ d_lite_next(VALUE self)
6167
6412
 
6168
6413
  /*
6169
6414
  * call-seq:
6170
- * d >> n -> date
6415
+ * d >> n -> new_date
6416
+ *
6417
+ * Returns a new \Date object representing the date
6418
+ * +n+ months later; +n+ should be a numeric:
6171
6419
  *
6172
- * Returns a date object pointing +n+ months after self.
6173
- * The argument +n+ should be a numeric value.
6420
+ * (Date.new(2001, 2, 3) >> 1).to_s # => "2001-03-03"
6421
+ * (Date.new(2001, 2, 3) >> -2).to_s # => "2000-12-03"
6174
6422
  *
6175
- * Date.new(2001,2,3) >> 1 #=> #<Date: 2001-03-03 ...>
6176
- * Date.new(2001,2,3) >> -2 #=> #<Date: 2000-12-03 ...>
6423
+ * When the same day does not exist for the new month,
6424
+ * the last day of that month is used instead:
6177
6425
  *
6178
- * When the same day does not exist for the corresponding month,
6179
- * the last day of the month is used instead:
6426
+ * (Date.new(2001, 1, 31) >> 1).to_s # => "2001-02-28"
6427
+ * (Date.new(2001, 1, 31) >> -4).to_s # => "2000-09-30"
6180
6428
  *
6181
- * Date.new(2001,1,28) >> 1 #=> #<Date: 2001-02-28 ...>
6182
- * Date.new(2001,1,31) >> 1 #=> #<Date: 2001-02-28 ...>
6429
+ * This results in the following, possibly unexpected, behaviors:
6183
6430
  *
6184
- * This also results in the following, possibly unexpected, behavior:
6431
+ * d0 = Date.new(2001, 1, 31)
6432
+ * d1 = d0 >> 1 # => #<Date: 2001-02-28>
6433
+ * d2 = d1 >> 1 # => #<Date: 2001-03-28>
6185
6434
  *
6186
- * Date.new(2001,1,31) >> 2 #=> #<Date: 2001-03-31 ...>
6187
- * Date.new(2001,1,31) >> 1 >> 1 #=> #<Date: 2001-03-28 ...>
6435
+ * d0 = Date.new(2001, 1, 31)
6436
+ * d1 = d0 >> 1 # => #<Date: 2001-02-28>
6437
+ * d2 = d1 >> -1 # => #<Date: 2001-01-28>
6188
6438
  *
6189
- * Date.new(2001,1,31) >> 1 >> -1 #=> #<Date: 2001-01-28 ...>
6190
6439
  */
6191
6440
  static VALUE
6192
6441
  d_lite_rshift(VALUE self, VALUE other)
@@ -6231,24 +6480,28 @@ d_lite_rshift(VALUE self, VALUE other)
6231
6480
  * call-seq:
6232
6481
  * d << n -> date
6233
6482
  *
6234
- * Returns a date object pointing +n+ months before self.
6235
- * The argument +n+ should be a numeric value.
6483
+ * Returns a new \Date object representing the date
6484
+ * +n+ months earlier; +n+ should be a numeric:
6236
6485
  *
6237
- * Date.new(2001,2,3) << 1 #=> #<Date: 2001-01-03 ...>
6238
- * Date.new(2001,2,3) << -2 #=> #<Date: 2001-04-03 ...>
6486
+ * (Date.new(2001, 2, 3) << 1).to_s # => "2001-01-03"
6487
+ * (Date.new(2001, 2, 3) << -2).to_s # => "2001-04-03"
6239
6488
  *
6240
- * When the same day does not exist for the corresponding month,
6241
- * the last day of the month is used instead:
6489
+ * When the same day does not exist for the new month,
6490
+ * the last day of that month is used instead:
6242
6491
  *
6243
- * Date.new(2001,3,28) << 1 #=> #<Date: 2001-02-28 ...>
6244
- * Date.new(2001,3,31) << 1 #=> #<Date: 2001-02-28 ...>
6492
+ * (Date.new(2001, 3, 31) << 1).to_s # => "2001-02-28"
6493
+ * (Date.new(2001, 3, 31) << -6).to_s # => "2001-09-30"
6245
6494
  *
6246
- * This also results in the following, possibly unexpected, behavior:
6495
+ * This results in the following, possibly unexpected, behaviors:
6247
6496
  *
6248
- * Date.new(2001,3,31) << 2 #=> #<Date: 2001-01-31 ...>
6249
- * Date.new(2001,3,31) << 1 << 1 #=> #<Date: 2001-01-28 ...>
6497
+ * d0 = Date.new(2001, 3, 31)
6498
+ * d0 << 2 # => #<Date: 2001-01-31>
6499
+ * d0 << 1 << 1 # => #<Date: 2001-01-28>
6500
+ *
6501
+ * d0 = Date.new(2001, 3, 31)
6502
+ * d1 = d0 << 1 # => #<Date: 2001-02-28>
6503
+ * d2 = d1 << -1 # => #<Date: 2001-03-28>
6250
6504
  *
6251
- * Date.new(2001,3,31) << 1 << -1 #=> #<Date: 2001-03-28 ...>
6252
6505
  */
6253
6506
  static VALUE
6254
6507
  d_lite_lshift(VALUE self, VALUE other)
@@ -6259,11 +6512,9 @@ d_lite_lshift(VALUE self, VALUE other)
6259
6512
 
6260
6513
  /*
6261
6514
  * call-seq:
6262
- * d.next_month([n=1]) -> date
6263
- *
6264
- * This method is equivalent to d >> n.
6515
+ * next_month(n = 1) -> new_date
6265
6516
  *
6266
- * See Date#>> for examples.
6517
+ * Equivalent to #>> with argument +n+.
6267
6518
  */
6268
6519
  static VALUE
6269
6520
  d_lite_next_month(int argc, VALUE *argv, VALUE self)
@@ -6278,11 +6529,9 @@ d_lite_next_month(int argc, VALUE *argv, VALUE self)
6278
6529
 
6279
6530
  /*
6280
6531
  * call-seq:
6281
- * d.prev_month([n=1]) -> date
6282
- *
6283
- * This method is equivalent to d << n.
6532
+ * prev_month(n = 1) -> new_date
6284
6533
  *
6285
- * See Date#<< for examples.
6534
+ * Equivalent to #<< with argument +n+.
6286
6535
  */
6287
6536
  static VALUE
6288
6537
  d_lite_prev_month(int argc, VALUE *argv, VALUE self)
@@ -6297,15 +6546,9 @@ d_lite_prev_month(int argc, VALUE *argv, VALUE self)
6297
6546
 
6298
6547
  /*
6299
6548
  * call-seq:
6300
- * d.next_year([n=1]) -> date
6549
+ * next_year(n = 1) -> new_date
6301
6550
  *
6302
- * This method is equivalent to d >> (n * 12).
6303
- *
6304
- * Date.new(2001,2,3).next_year #=> #<Date: 2002-02-03 ...>
6305
- * Date.new(2008,2,29).next_year #=> #<Date: 2009-02-28 ...>
6306
- * Date.new(2008,2,29).next_year(4) #=> #<Date: 2012-02-29 ...>
6307
- *
6308
- * See also Date#>>.
6551
+ * Equivalent to #>> with argument <tt>n * 12</tt>.
6309
6552
  */
6310
6553
  static VALUE
6311
6554
  d_lite_next_year(int argc, VALUE *argv, VALUE self)
@@ -6320,15 +6563,9 @@ d_lite_next_year(int argc, VALUE *argv, VALUE self)
6320
6563
 
6321
6564
  /*
6322
6565
  * call-seq:
6323
- * d.prev_year([n=1]) -> date
6324
- *
6325
- * This method is equivalent to d << (n * 12).
6566
+ * prev_year(n = 1) -> new_date
6326
6567
  *
6327
- * Date.new(2001,2,3).prev_year #=> #<Date: 2000-02-03 ...>
6328
- * Date.new(2008,2,29).prev_year #=> #<Date: 2007-02-28 ...>
6329
- * Date.new(2008,2,29).prev_year(4) #=> #<Date: 2004-02-29 ...>
6330
- *
6331
- * See also Date#<<.
6568
+ * Equivalent to #<< with argument <tt>n * 12</tt>.
6332
6569
  */
6333
6570
  static VALUE
6334
6571
  d_lite_prev_year(int argc, VALUE *argv, VALUE self)
@@ -6345,14 +6582,33 @@ static VALUE d_lite_cmp(VALUE, VALUE);
6345
6582
 
6346
6583
  /*
6347
6584
  * call-seq:
6348
- * d.step(limit[, step=1]) -> enumerator
6349
- * d.step(limit[, step=1]){|date| ...} -> self
6585
+ * step(limit, step = 1){|date| ... } -> self
6586
+ *
6587
+ * Calls the block with specified dates;
6588
+ * returns +self+.
6589
+ *
6590
+ * - The first +date+ is +self+.
6591
+ * - Each successive +date+ is <tt>date + step</tt>,
6592
+ * where +step+ is the numeric step size in days.
6593
+ * - The last date is the last one that is before or equal to +limit+,
6594
+ * which should be a \Date object.
6595
+ *
6596
+ * Example:
6597
+ *
6598
+ * limit = Date.new(2001, 12, 31)
6599
+ * Date.new(2001).step(limit){|date| p date.to_s if date.mday == 31 }
6600
+ *
6601
+ * Output:
6350
6602
  *
6351
- * Iterates evaluation of the given block, which takes a date object.
6352
- * The limit should be a date object.
6603
+ * "2001-01-31"
6604
+ * "2001-03-31"
6605
+ * "2001-05-31"
6606
+ * "2001-07-31"
6607
+ * "2001-08-31"
6608
+ * "2001-10-31"
6609
+ * "2001-12-31"
6353
6610
  *
6354
- * Date.new(2001).step(Date.new(2001,-1,-1)).select{|d| d.sunday?}.size
6355
- * #=> 52
6611
+ * Returns an Enumerator if no block is given.
6356
6612
  */
6357
6613
  static VALUE
6358
6614
  d_lite_step(int argc, VALUE *argv, VALUE self)
@@ -6395,10 +6651,9 @@ d_lite_step(int argc, VALUE *argv, VALUE self)
6395
6651
 
6396
6652
  /*
6397
6653
  * call-seq:
6398
- * d.upto(max) -> enumerator
6399
- * d.upto(max){|date| ...} -> self
6654
+ * upto(max){|date| ... } -> self
6400
6655
  *
6401
- * This method is equivalent to step(max, 1){|date| ...}.
6656
+ * Equivalent to #step with arguments +max+ and +1+.
6402
6657
  */
6403
6658
  static VALUE
6404
6659
  d_lite_upto(VALUE self, VALUE max)
@@ -6417,10 +6672,9 @@ d_lite_upto(VALUE self, VALUE max)
6417
6672
 
6418
6673
  /*
6419
6674
  * call-seq:
6420
- * d.downto(min) -> enumerator
6421
- * d.downto(min){|date| ...} -> self
6675
+ * downto(min){|date| ... } -> self
6422
6676
  *
6423
- * This method is equivalent to step(min, -1){|date| ...}.
6677
+ * Equivalent to #step with arguments +min+ and <tt>-1</tt>.
6424
6678
  */
6425
6679
  static VALUE
6426
6680
  d_lite_downto(VALUE self, VALUE min)
@@ -6508,19 +6762,43 @@ cmp_dd(VALUE self, VALUE other)
6508
6762
 
6509
6763
  /*
6510
6764
  * call-seq:
6511
- * d <=> other -> -1, 0, +1 or nil
6765
+ * self <=> other -> -1, 0, 1 or nil
6766
+ *
6767
+ * Compares +self+ and +other+, returning:
6768
+ *
6769
+ * - <tt>-1</tt> if +other+ is larger.
6770
+ * - <tt>0</tt> if the two are equal.
6771
+ * - <tt>1</tt> if +other+ is smaller.
6772
+ * - +nil+ if the two are incomparable.
6773
+ *
6774
+ * Argument +other+ may be:
6775
+ *
6776
+ * - Another \Date object:
6777
+ *
6778
+ * d = Date.new(2022, 7, 27) # => #<Date: 2022-07-27 ((2459788j,0s,0n),+0s,2299161j)>
6779
+ * prev_date = d.prev_day # => #<Date: 2022-07-26 ((2459787j,0s,0n),+0s,2299161j)>
6780
+ * next_date = d.next_day # => #<Date: 2022-07-28 ((2459789j,0s,0n),+0s,2299161j)>
6781
+ * d <=> next_date # => -1
6782
+ * d <=> d # => 0
6783
+ * d <=> prev_date # => 1
6512
6784
  *
6513
- * Compares the two dates and returns -1, zero, 1 or nil. The other
6514
- * should be a date object or a numeric value as an astronomical
6515
- * Julian day number.
6785
+ * - A DateTime object:
6516
6786
  *
6517
- * Date.new(2001,2,3) <=> Date.new(2001,2,4) #=> -1
6518
- * Date.new(2001,2,3) <=> Date.new(2001,2,3) #=> 0
6519
- * Date.new(2001,2,3) <=> Date.new(2001,2,2) #=> 1
6520
- * Date.new(2001,2,3) <=> Object.new #=> nil
6521
- * Date.new(2001,2,3) <=> Rational(4903887,2) #=> 0
6787
+ * d <=> DateTime.new(2022, 7, 26) # => 1
6788
+ * d <=> DateTime.new(2022, 7, 27) # => 0
6789
+ * d <=> DateTime.new(2022, 7, 28) # => -1
6790
+ *
6791
+ * - A numeric (compares <tt>self.ajd</tt> to +other+):
6792
+ *
6793
+ * d <=> 2459788 # => -1
6794
+ * d <=> 2459787 # => 1
6795
+ * d <=> 2459786 # => 1
6796
+ * d <=> d.ajd # => 0
6797
+ *
6798
+ * - Any other object:
6799
+ *
6800
+ * d <=> Object.new # => nil
6522
6801
  *
6523
- * See also Comparable.
6524
6802
  */
6525
6803
  static VALUE
6526
6804
  d_lite_cmp(VALUE self, VALUE other)
@@ -6580,20 +6858,39 @@ equal_gen(VALUE self, VALUE other)
6580
6858
 
6581
6859
  /*
6582
6860
  * call-seq:
6583
- * d === other -> bool
6584
- *
6585
- * Returns true if they are the same day.
6586
- *
6587
- * Date.new(2001,2,3) === Date.new(2001,2,3)
6588
- * #=> true
6589
- * Date.new(2001,2,3) === Date.new(2001,2,4)
6590
- * #=> false
6591
- * DateTime.new(2001,2,3) === DateTime.new(2001,2,3,12)
6592
- * #=> true
6593
- * DateTime.new(2001,2,3) === DateTime.new(2001,2,3,0,0,0,'+24:00')
6594
- * #=> true
6595
- * DateTime.new(2001,2,3) === DateTime.new(2001,2,4,0,0,0,'+24:00')
6596
- * #=> false
6861
+ * self === other -> true, false, or nil.
6862
+ *
6863
+ * Returns +true+ if +self+ and +other+ represent the same date,
6864
+ * +false+ if not, +nil+ if the two are not comparable.
6865
+ *
6866
+ * Argument +other+ may be:
6867
+ *
6868
+ * - Another \Date object:
6869
+ *
6870
+ * d = Date.new(2022, 7, 27) # => #<Date: 2022-07-27 ((2459788j,0s,0n),+0s,2299161j)>
6871
+ * prev_date = d.prev_day # => #<Date: 2022-07-26 ((2459787j,0s,0n),+0s,2299161j)>
6872
+ * next_date = d.next_day # => #<Date: 2022-07-28 ((2459789j,0s,0n),+0s,2299161j)>
6873
+ * d === prev_date # => false
6874
+ * d === d # => true
6875
+ * d === next_date # => false
6876
+ *
6877
+ * - A DateTime object:
6878
+ *
6879
+ * d === DateTime.new(2022, 7, 26) # => false
6880
+ * d === DateTime.new(2022, 7, 27) # => true
6881
+ * d === DateTime.new(2022, 7, 28) # => false
6882
+ *
6883
+ * - A numeric (compares <tt>self.jd</tt> to +other+):
6884
+ *
6885
+ * d === 2459788 # => true
6886
+ * d === 2459787 # => false
6887
+ * d === 2459786 # => false
6888
+ * d === d.jd # => true
6889
+ *
6890
+ * - An object not comparable:
6891
+ *
6892
+ * d === Object.new # => nil
6893
+ *
6597
6894
  */
6598
6895
  static VALUE
6599
6896
  d_lite_equal(VALUE self, VALUE other)
@@ -6638,13 +6935,24 @@ d_lite_eql_p(VALUE self, VALUE other)
6638
6935
  static VALUE
6639
6936
  d_lite_hash(VALUE self)
6640
6937
  {
6641
- st_index_t v, h[4];
6938
+ st_index_t v, h[5];
6939
+ VALUE nth;
6642
6940
 
6643
6941
  get_d1(self);
6644
- h[0] = m_nth(dat);
6645
- h[1] = m_jd(dat);
6646
- h[2] = m_df(dat);
6647
- h[3] = m_sf(dat);
6942
+ nth = m_nth(dat);
6943
+
6944
+ if (FIXNUM_P(nth)) {
6945
+ h[0] = 0;
6946
+ h[1] = (st_index_t)nth;
6947
+ } else {
6948
+ h[0] = 1;
6949
+ h[1] = (st_index_t)FIX2LONG(rb_hash(nth));
6950
+ }
6951
+
6952
+ h[2] = m_jd(dat);
6953
+ h[3] = m_df(dat);
6954
+ h[4] = m_sf(dat);
6955
+
6648
6956
  v = rb_memhash(h, sizeof(h));
6649
6957
  return ST2FIX(v);
6650
6958
  }
@@ -6656,12 +6964,14 @@ static VALUE strftimev(const char *, VALUE,
6656
6964
 
6657
6965
  /*
6658
6966
  * call-seq:
6659
- * d.to_s -> string
6967
+ * to_s -> string
6660
6968
  *
6661
- * Returns a string in an ISO 8601 format. (This method doesn't use the
6662
- * expanded representations.)
6969
+ * Returns a string representation of the date in +self+
6970
+ * in {ISO 8601 extended date format}[rdoc-ref:language/strftime_formatting.rdoc@ISO+8601+Format+Specifications]
6971
+ * (<tt>'%Y-%m-%d'</tt>):
6972
+ *
6973
+ * Date.new(2001, 2, 3).to_s # => "2001-02-03"
6663
6974
  *
6664
- * Date.new(2001,2,3).to_s #=> "2001-02-03"
6665
6975
  */
6666
6976
  static VALUE
6667
6977
  d_lite_to_s(VALUE self)
@@ -6670,6 +6980,7 @@ d_lite_to_s(VALUE self)
6670
6980
  }
6671
6981
 
6672
6982
  #ifndef NDEBUG
6983
+ /* :nodoc: */
6673
6984
  static VALUE
6674
6985
  mk_inspect_raw(union DateData *x, VALUE klass)
6675
6986
  {
@@ -6719,6 +7030,7 @@ mk_inspect_raw(union DateData *x, VALUE klass)
6719
7030
  }
6720
7031
  }
6721
7032
 
7033
+ /* :nodoc: */
6722
7034
  static VALUE
6723
7035
  d_lite_inspect_raw(VALUE self)
6724
7036
  {
@@ -6740,14 +7052,13 @@ mk_inspect(union DateData *x, VALUE klass, VALUE to_s)
6740
7052
 
6741
7053
  /*
6742
7054
  * call-seq:
6743
- * d.inspect -> string
7055
+ * inspect -> string
7056
+ *
7057
+ * Returns a string representation of +self+:
6744
7058
  *
6745
- * Returns the value as a string for inspection.
7059
+ * Date.new(2001, 2, 3).inspect
7060
+ * # => "#<Date: 2001-02-03 ((2451944j,0s,0n),+0s,2299161j)>"
6746
7061
  *
6747
- * Date.new(2001,2,3).inspect
6748
- * #=> "#<Date: 2001-02-03>"
6749
- * DateTime.new(2001,2,3,4,5,6,'-7').inspect
6750
- * #=> "#<DateTime: 2001-02-03T04:05:06-07:00>"
6751
7062
  */
6752
7063
  static VALUE
6753
7064
  d_lite_inspect(VALUE self)
@@ -6929,180 +7240,16 @@ date_strftime_internal(int argc, VALUE *argv, VALUE self,
6929
7240
 
6930
7241
  /*
6931
7242
  * call-seq:
6932
- * d.strftime([format='%F']) -> string
6933
- *
6934
- * Formats date according to the directives in the given format
6935
- * string.
6936
- * The directives begin with a percent (%) character.
6937
- * Any text not listed as a directive will be passed through to the
6938
- * output string.
6939
- *
6940
- * A directive consists of a percent (%) character,
6941
- * zero or more flags, an optional minimum field width,
6942
- * an optional modifier, and a conversion specifier
6943
- * as follows.
6944
- *
6945
- * %<flags><width><modifier><conversion>
6946
- *
6947
- * Flags:
6948
- * - don't pad a numerical output.
6949
- * _ use spaces for padding.
6950
- * 0 use zeros for padding.
6951
- * ^ upcase the result string.
6952
- * # change case.
6953
- *
6954
- * The minimum field width specifies the minimum width.
6955
- *
6956
- * The modifiers are "E", "O", ":", "::" and ":::".
6957
- * "E" and "O" are ignored. No effect to result currently.
6958
- *
6959
- * Format directives:
6960
- *
6961
- * Date (Year, Month, Day):
6962
- * %Y - Year with century (can be negative, 4 digits at least)
6963
- * -0001, 0000, 1995, 2009, 14292, etc.
6964
- * %C - year / 100 (round down. 20 in 2009)
6965
- * %y - year % 100 (00..99)
6966
- *
6967
- * %m - Month of the year, zero-padded (01..12)
6968
- * %_m blank-padded ( 1..12)
6969
- * %-m no-padded (1..12)
6970
- * %B - The full month name (``January'')
6971
- * %^B uppercased (``JANUARY'')
6972
- * %b - The abbreviated month name (``Jan'')
6973
- * %^b uppercased (``JAN'')
6974
- * %h - Equivalent to %b
6975
- *
6976
- * %d - Day of the month, zero-padded (01..31)
6977
- * %-d no-padded (1..31)
6978
- * %e - Day of the month, blank-padded ( 1..31)
6979
- *
6980
- * %j - Day of the year (001..366)
6981
- *
6982
- * Time (Hour, Minute, Second, Subsecond):
6983
- * %H - Hour of the day, 24-hour clock, zero-padded (00..23)
6984
- * %k - Hour of the day, 24-hour clock, blank-padded ( 0..23)
6985
- * %I - Hour of the day, 12-hour clock, zero-padded (01..12)
6986
- * %l - Hour of the day, 12-hour clock, blank-padded ( 1..12)
6987
- * %P - Meridian indicator, lowercase (``am'' or ``pm'')
6988
- * %p - Meridian indicator, uppercase (``AM'' or ``PM'')
6989
- *
6990
- * %M - Minute of the hour (00..59)
6991
- *
6992
- * %S - Second of the minute (00..60)
6993
- *
6994
- * %L - Millisecond of the second (000..999)
6995
- * %N - Fractional seconds digits, default is 9 digits (nanosecond)
6996
- * %3N millisecond (3 digits) %15N femtosecond (15 digits)
6997
- * %6N microsecond (6 digits) %18N attosecond (18 digits)
6998
- * %9N nanosecond (9 digits) %21N zeptosecond (21 digits)
6999
- * %12N picosecond (12 digits) %24N yoctosecond (24 digits)
7000
- *
7001
- * Time zone:
7002
- * %z - Time zone as hour and minute offset from UTC (e.g. +0900)
7003
- * %:z - hour and minute offset from UTC with a colon (e.g. +09:00)
7004
- * %::z - hour, minute and second offset from UTC (e.g. +09:00:00)
7005
- * %:::z - hour, minute and second offset from UTC
7006
- * (e.g. +09, +09:30, +09:30:30)
7007
- * %Z - Equivalent to %:z (e.g. +09:00)
7008
- *
7009
- * Weekday:
7010
- * %A - The full weekday name (``Sunday'')
7011
- * %^A uppercased (``SUNDAY'')
7012
- * %a - The abbreviated name (``Sun'')
7013
- * %^a uppercased (``SUN'')
7014
- * %u - Day of the week (Monday is 1, 1..7)
7015
- * %w - Day of the week (Sunday is 0, 0..6)
7016
- *
7017
- * ISO 8601 week-based year and week number:
7018
- * The week 1 of YYYY starts with a Monday and includes YYYY-01-04.
7019
- * The days in the year before the first week are in the last week of
7020
- * the previous year.
7021
- * %G - The week-based year
7022
- * %g - The last 2 digits of the week-based year (00..99)
7023
- * %V - Week number of the week-based year (01..53)
7024
- *
7025
- * Week number:
7026
- * The week 1 of YYYY starts with a Sunday or Monday (according to %U
7027
- * or %W). The days in the year before the first week are in week 0.
7028
- * %U - Week number of the year. The week starts with Sunday. (00..53)
7029
- * %W - Week number of the year. The week starts with Monday. (00..53)
7030
- *
7031
- * Seconds since the Unix Epoch:
7032
- * %s - Number of seconds since 1970-01-01 00:00:00 UTC.
7033
- * %Q - Number of milliseconds since 1970-01-01 00:00:00 UTC.
7034
- *
7035
- * Literal string:
7036
- * %n - Newline character (\n)
7037
- * %t - Tab character (\t)
7038
- * %% - Literal ``%'' character
7039
- *
7040
- * Combination:
7041
- * %c - date and time (%a %b %e %T %Y)
7042
- * %D - Date (%m/%d/%y)
7043
- * %F - The ISO 8601 date format (%Y-%m-%d)
7044
- * %v - VMS date (%e-%^b-%Y)
7045
- * %x - Same as %D
7046
- * %X - Same as %T
7047
- * %r - 12-hour time (%I:%M:%S %p)
7048
- * %R - 24-hour time (%H:%M)
7049
- * %T - 24-hour time (%H:%M:%S)
7050
- * %+ - date(1) (%a %b %e %H:%M:%S %Z %Y)
7051
- *
7052
- * This method is similar to the strftime() function defined in ISO C
7053
- * and POSIX.
7054
- * Several directives (%a, %A, %b, %B, %c, %p, %r, %x, %X, %E*, %O* and %Z)
7055
- * are locale dependent in the function.
7056
- * However, this method is locale independent.
7057
- * So, the result may differ even if the same format string is used in other
7058
- * systems such as C.
7059
- * It is good practice to avoid %x and %X because there are corresponding
7060
- * locale independent representations, %D and %T.
7061
- *
7062
- * Examples:
7063
- *
7064
- * d = DateTime.new(2007,11,19,8,37,48,"-06:00")
7065
- * #=> #<DateTime: 2007-11-19T08:37:48-0600 ...>
7066
- * d.strftime("Printed on %m/%d/%Y") #=> "Printed on 11/19/2007"
7067
- * d.strftime("at %I:%M%p") #=> "at 08:37AM"
7068
- *
7069
- * Various ISO 8601 formats:
7070
- * %Y%m%d => 20071119 Calendar date (basic)
7071
- * %F => 2007-11-19 Calendar date (extended)
7072
- * %Y-%m => 2007-11 Calendar date, reduced accuracy, specific month
7073
- * %Y => 2007 Calendar date, reduced accuracy, specific year
7074
- * %C => 20 Calendar date, reduced accuracy, specific century
7075
- * %Y%j => 2007323 Ordinal date (basic)
7076
- * %Y-%j => 2007-323 Ordinal date (extended)
7077
- * %GW%V%u => 2007W471 Week date (basic)
7078
- * %G-W%V-%u => 2007-W47-1 Week date (extended)
7079
- * %GW%V => 2007W47 Week date, reduced accuracy, specific week (basic)
7080
- * %G-W%V => 2007-W47 Week date, reduced accuracy, specific week (extended)
7081
- * %H%M%S => 083748 Local time (basic)
7082
- * %T => 08:37:48 Local time (extended)
7083
- * %H%M => 0837 Local time, reduced accuracy, specific minute (basic)
7084
- * %H:%M => 08:37 Local time, reduced accuracy, specific minute (extended)
7085
- * %H => 08 Local time, reduced accuracy, specific hour
7086
- * %H%M%S,%L => 083748,000 Local time with decimal fraction, comma as decimal sign (basic)
7087
- * %T,%L => 08:37:48,000 Local time with decimal fraction, comma as decimal sign (extended)
7088
- * %H%M%S.%L => 083748.000 Local time with decimal fraction, full stop as decimal sign (basic)
7089
- * %T.%L => 08:37:48.000 Local time with decimal fraction, full stop as decimal sign (extended)
7090
- * %H%M%S%z => 083748-0600 Local time and the difference from UTC (basic)
7091
- * %T%:z => 08:37:48-06:00 Local time and the difference from UTC (extended)
7092
- * %Y%m%dT%H%M%S%z => 20071119T083748-0600 Date and time of day for calendar date (basic)
7093
- * %FT%T%:z => 2007-11-19T08:37:48-06:00 Date and time of day for calendar date (extended)
7094
- * %Y%jT%H%M%S%z => 2007323T083748-0600 Date and time of day for ordinal date (basic)
7095
- * %Y-%jT%T%:z => 2007-323T08:37:48-06:00 Date and time of day for ordinal date (extended)
7096
- * %GW%V%uT%H%M%S%z => 2007W471T083748-0600 Date and time of day for week date (basic)
7097
- * %G-W%V-%uT%T%:z => 2007-W47-1T08:37:48-06:00 Date and time of day for week date (extended)
7098
- * %Y%m%dT%H%M => 20071119T0837 Calendar date and local time (basic)
7099
- * %FT%R => 2007-11-19T08:37 Calendar date and local time (extended)
7100
- * %Y%jT%H%MZ => 2007323T0837Z Ordinal date and UTC of day (basic)
7101
- * %Y-%jT%RZ => 2007-323T08:37Z Ordinal date and UTC of day (extended)
7102
- * %GW%V%uT%H%M%z => 2007W471T0837-0600 Week date and local time and difference from UTC (basic)
7103
- * %G-W%V-%uT%R%:z => 2007-W47-1T08:37-06:00 Week date and local time and difference from UTC (extended)
7104
- *
7105
- * See also strftime(3) and ::strptime.
7243
+ * strftime(format = '%F') -> string
7244
+ *
7245
+ * Returns a string representation of the date in +self+,
7246
+ * formatted according the given +format+:
7247
+ *
7248
+ * Date.new(2001, 2, 3).strftime # => "2001-02-03"
7249
+ *
7250
+ * For other formats, see
7251
+ * {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc].
7252
+ *
7106
7253
  */
7107
7254
  static VALUE
7108
7255
  d_lite_strftime(int argc, VALUE *argv, VALUE self)
@@ -7130,13 +7277,16 @@ strftimev(const char *fmt, VALUE self,
7130
7277
 
7131
7278
  /*
7132
7279
  * call-seq:
7133
- * d.asctime -> string
7134
- * d.ctime -> string
7280
+ * asctime -> string
7135
7281
  *
7136
- * Returns a string in asctime(3) format (but without "\n\0" at the
7137
- * end). This method is equivalent to strftime('%c').
7282
+ * Equivalent to #strftime with argument <tt>'%a %b %e %T %Y'</tt>
7283
+ * (or its {shorthand form}[rdoc-ref:language/strftime_formatting.rdoc@Shorthand+Conversion+Specifiers]
7284
+ * <tt>'%c'</tt>):
7285
+ *
7286
+ * Date.new(2001, 2, 3).asctime # => "Sat Feb 3 00:00:00 2001"
7287
+ *
7288
+ * See {asctime}[https://linux.die.net/man/3/asctime].
7138
7289
  *
7139
- * See also asctime(3) or ctime(3).
7140
7290
  */
7141
7291
  static VALUE
7142
7292
  d_lite_asctime(VALUE self)
@@ -7146,10 +7296,14 @@ d_lite_asctime(VALUE self)
7146
7296
 
7147
7297
  /*
7148
7298
  * call-seq:
7149
- * d.iso8601 -> string
7150
- * d.xmlschema -> string
7299
+ * iso8601 -> string
7300
+ *
7301
+ * Equivalent to #strftime with argument <tt>'%Y-%m-%d'</tt>
7302
+ * (or its {shorthand form}[rdoc-ref:language/strftime_formatting.rdoc@Shorthand+Conversion+Specifiers]
7303
+ * <tt>'%F'</tt>);
7304
+ *
7305
+ * Date.new(2001, 2, 3).iso8601 # => "2001-02-03"
7151
7306
  *
7152
- * This method is equivalent to strftime('%F').
7153
7307
  */
7154
7308
  static VALUE
7155
7309
  d_lite_iso8601(VALUE self)
@@ -7159,9 +7313,13 @@ d_lite_iso8601(VALUE self)
7159
7313
 
7160
7314
  /*
7161
7315
  * call-seq:
7162
- * d.rfc3339 -> string
7316
+ * rfc3339 -> string
7317
+ *
7318
+ * Equivalent to #strftime with argument <tt>'%FT%T%:z'</tt>;
7319
+ * see {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]:
7320
+ *
7321
+ * Date.new(2001, 2, 3).rfc3339 # => "2001-02-03T00:00:00+00:00"
7163
7322
  *
7164
- * This method is equivalent to strftime('%FT%T%:z').
7165
7323
  */
7166
7324
  static VALUE
7167
7325
  d_lite_rfc3339(VALUE self)
@@ -7171,10 +7329,13 @@ d_lite_rfc3339(VALUE self)
7171
7329
 
7172
7330
  /*
7173
7331
  * call-seq:
7174
- * d.rfc2822 -> string
7175
- * d.rfc822 -> string
7332
+ * rfc2822 -> string
7333
+ *
7334
+ * Equivalent to #strftime with argument <tt>'%a, %-d %b %Y %T %z'</tt>;
7335
+ * see {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]:
7336
+ *
7337
+ * Date.new(2001, 2, 3).rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000"
7176
7338
  *
7177
- * This method is equivalent to strftime('%a, %-d %b %Y %T %z').
7178
7339
  */
7179
7340
  static VALUE
7180
7341
  d_lite_rfc2822(VALUE self)
@@ -7184,10 +7345,13 @@ d_lite_rfc2822(VALUE self)
7184
7345
 
7185
7346
  /*
7186
7347
  * call-seq:
7187
- * d.httpdate -> string
7348
+ * httpdate -> string
7349
+ *
7350
+ * Equivalent to #strftime with argument <tt>'%a, %d %b %Y %T GMT'</tt>;
7351
+ * see {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]:
7352
+ *
7353
+ * Date.new(2001, 2, 3).httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT"
7188
7354
  *
7189
- * This method is equivalent to strftime('%a, %d %b %Y %T GMT').
7190
- * See also RFC 2616.
7191
7355
  */
7192
7356
  static VALUE
7193
7357
  d_lite_httpdate(VALUE self)
@@ -7238,11 +7402,13 @@ jisx0301_date_format(char *fmt, size_t size, VALUE jd, VALUE y)
7238
7402
 
7239
7403
  /*
7240
7404
  * call-seq:
7241
- * d.jisx0301 -> string
7405
+ * jisx0301 -> string
7242
7406
  *
7243
- * Returns a string in a JIS X 0301 format.
7407
+ * Returns a string representation of the date in +self+
7408
+ * in JIS X 0301 format.
7409
+ *
7410
+ * Date.new(2001, 2, 3).jisx0301 # => "H13.02.03"
7244
7411
  *
7245
- * Date.new(2001,2,3).jisx0301 #=> "H13.02.03"
7246
7412
  */
7247
7413
  static VALUE
7248
7414
  d_lite_jisx0301(VALUE self)
@@ -7257,7 +7423,98 @@ d_lite_jisx0301(VALUE self)
7257
7423
  return strftimev(fmt, self, set_tmx);
7258
7424
  }
7259
7425
 
7426
+ static VALUE
7427
+ deconstruct_keys(VALUE self, VALUE keys, int is_datetime)
7428
+ {
7429
+ VALUE h = rb_hash_new();
7430
+ long i;
7431
+
7432
+ get_d1(self);
7433
+
7434
+ if (NIL_P(keys)) {
7435
+ rb_hash_aset(h, sym_year, m_real_year(dat));
7436
+ rb_hash_aset(h, sym_month, INT2FIX(m_mon(dat)));
7437
+ rb_hash_aset(h, sym_day, INT2FIX(m_mday(dat)));
7438
+ rb_hash_aset(h, sym_yday, INT2FIX(m_yday(dat)));
7439
+ rb_hash_aset(h, sym_wday, INT2FIX(m_wday(dat)));
7440
+ if (is_datetime) {
7441
+ rb_hash_aset(h, sym_hour, INT2FIX(m_hour(dat)));
7442
+ rb_hash_aset(h, sym_min, INT2FIX(m_min(dat)));
7443
+ rb_hash_aset(h, sym_sec, INT2FIX(m_sec(dat)));
7444
+ rb_hash_aset(h, sym_sec_fraction, m_sf_in_sec(dat));
7445
+ rb_hash_aset(h, sym_zone, m_zone(dat));
7446
+ }
7447
+
7448
+ return h;
7449
+ }
7450
+ if (!RB_TYPE_P(keys, T_ARRAY)) {
7451
+ rb_raise(rb_eTypeError,
7452
+ "wrong argument type %"PRIsVALUE" (expected Array or nil)",
7453
+ rb_obj_class(keys));
7454
+
7455
+ }
7456
+
7457
+ for (i=0; i<RARRAY_LEN(keys); i++) {
7458
+ VALUE key = RARRAY_AREF(keys, i);
7459
+
7460
+ if (sym_year == key) rb_hash_aset(h, key, m_real_year(dat));
7461
+ if (sym_month == key) rb_hash_aset(h, key, INT2FIX(m_mon(dat)));
7462
+ if (sym_day == key) rb_hash_aset(h, key, INT2FIX(m_mday(dat)));
7463
+ if (sym_yday == key) rb_hash_aset(h, key, INT2FIX(m_yday(dat)));
7464
+ if (sym_wday == key) rb_hash_aset(h, key, INT2FIX(m_wday(dat)));
7465
+ if (is_datetime) {
7466
+ if (sym_hour == key) rb_hash_aset(h, key, INT2FIX(m_hour(dat)));
7467
+ if (sym_min == key) rb_hash_aset(h, key, INT2FIX(m_min(dat)));
7468
+ if (sym_sec == key) rb_hash_aset(h, key, INT2FIX(m_sec(dat)));
7469
+ if (sym_sec_fraction == key) rb_hash_aset(h, key, m_sf_in_sec(dat));
7470
+ if (sym_zone == key) rb_hash_aset(h, key, m_zone(dat));
7471
+ }
7472
+ }
7473
+ return h;
7474
+ }
7475
+
7476
+ /*
7477
+ * call-seq:
7478
+ * deconstruct_keys(array_of_names_or_nil) -> hash
7479
+ *
7480
+ * Returns a hash of the name/value pairs, to use in pattern matching.
7481
+ * Possible keys are: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
7482
+ * <tt>:wday</tt>, <tt>:yday</tt>.
7483
+ *
7484
+ * Possible usages:
7485
+ *
7486
+ * d = Date.new(2022, 10, 5)
7487
+ *
7488
+ * if d in wday: 3, day: ..7 # uses deconstruct_keys underneath
7489
+ * puts "first Wednesday of the month"
7490
+ * end
7491
+ * #=> prints "first Wednesday of the month"
7492
+ *
7493
+ * case d
7494
+ * in year: ...2022
7495
+ * puts "too old"
7496
+ * in month: ..9
7497
+ * puts "quarter 1-3"
7498
+ * in wday: 1..5, month:
7499
+ * puts "working day in month #{month}"
7500
+ * end
7501
+ * #=> prints "working day in month 10"
7502
+ *
7503
+ * Note that deconstruction by pattern can also be combined with class check:
7504
+ *
7505
+ * if d in Date(wday: 3, day: ..7)
7506
+ * puts "first Wednesday of the month"
7507
+ * end
7508
+ *
7509
+ */
7510
+ static VALUE
7511
+ d_lite_deconstruct_keys(VALUE self, VALUE keys)
7512
+ {
7513
+ return deconstruct_keys(self, keys, /* is_datetime=false */ 0);
7514
+ }
7515
+
7260
7516
  #ifndef NDEBUG
7517
+ /* :nodoc: */
7261
7518
  static VALUE
7262
7519
  d_lite_marshal_dump_old(VALUE self)
7263
7520
  {
@@ -7270,10 +7527,7 @@ d_lite_marshal_dump_old(VALUE self)
7270
7527
  m_of_in_day(dat),
7271
7528
  DBL2NUM(m_sg(dat)));
7272
7529
 
7273
- if (FL_TEST(self, FL_EXIVAR)) {
7274
- rb_copy_generic_ivar(a, self);
7275
- FL_SET(a, FL_EXIVAR);
7276
- }
7530
+ rb_copy_generic_ivar(a, self);
7277
7531
 
7278
7532
  return a;
7279
7533
  }
@@ -7295,10 +7549,8 @@ d_lite_marshal_dump(VALUE self)
7295
7549
  INT2FIX(m_of(dat)),
7296
7550
  DBL2NUM(m_sg(dat)));
7297
7551
 
7298
- if (FL_TEST(self, FL_EXIVAR)) {
7299
- rb_copy_generic_ivar(a, self);
7300
- FL_SET(a, FL_EXIVAR);
7301
- }
7552
+
7553
+ rb_copy_generic_ivar(a, self);
7302
7554
 
7303
7555
  return a;
7304
7556
  }
@@ -7371,10 +7623,7 @@ d_lite_marshal_load(VALUE self, VALUE a)
7371
7623
  HAVE_JD | HAVE_DF);
7372
7624
  }
7373
7625
 
7374
- if (FL_TEST(a, FL_EXIVAR)) {
7375
- rb_copy_generic_ivar(self, a);
7376
- FL_SET(self, FL_EXIVAR);
7377
- }
7626
+ rb_copy_generic_ivar(self, a);
7378
7627
 
7379
7628
  return self;
7380
7629
  }
@@ -7545,17 +7794,7 @@ datetime_s_ordinal(int argc, VALUE *argv, VALUE klass)
7545
7794
  }
7546
7795
 
7547
7796
  /*
7548
- * call-seq:
7549
- * DateTime.civil([year=-4712[, month=1[, mday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) -> datetime
7550
- * DateTime.new([year=-4712[, month=1[, mday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) -> datetime
7551
- *
7552
- * Creates a DateTime object denoting the given calendar date.
7553
- *
7554
- * DateTime.new(2001,2,3) #=> #<DateTime: 2001-02-03T00:00:00+00:00 ...>
7555
- * DateTime.new(2001,2,3,4,5,6,'+7')
7556
- * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
7557
- * DateTime.new(2001,-11,-26,-20,-55,-54,'+7')
7558
- * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
7797
+ * Same as DateTime.new.
7559
7798
  */
7560
7799
  static VALUE
7561
7800
  datetime_s_civil(int argc, VALUE *argv, VALUE klass)
@@ -7745,6 +7984,7 @@ datetime_s_commercial(int argc, VALUE *argv, VALUE klass)
7745
7984
  }
7746
7985
 
7747
7986
  #ifndef NDEBUG
7987
+ /* :nodoc: */
7748
7988
  static VALUE
7749
7989
  datetime_s_weeknum(int argc, VALUE *argv, VALUE klass)
7750
7990
  {
@@ -7814,6 +8054,7 @@ datetime_s_weeknum(int argc, VALUE *argv, VALUE klass)
7814
8054
  return ret;
7815
8055
  }
7816
8056
 
8057
+ /* :nodoc: */
7817
8058
  static VALUE
7818
8059
  datetime_s_nth_kday(int argc, VALUE *argv, VALUE klass)
7819
8060
  {
@@ -8135,7 +8376,7 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
8135
8376
 
8136
8377
  switch (argc) {
8137
8378
  case 0:
8138
- str = rb_str_new2("-4712-01-01T00:00:00+00:00");
8379
+ str = rb_str_new2(JULIAN_EPOCH_DATETIME);
8139
8380
  case 1:
8140
8381
  fmt = rb_str_new2("%FT%T%z");
8141
8382
  case 2:
@@ -8159,9 +8400,9 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
8159
8400
  * Parses the given representation of date and time, and creates a
8160
8401
  * DateTime object.
8161
8402
  *
8162
- * This method *does not* function as a validator. If the input
8403
+ * This method *does* *not* function as a validator. If the input
8163
8404
  * string does not match valid formats strictly, you may get a cryptic
8164
- * result. Should consider to use `DateTime.strptime` instead of this
8405
+ * result. Should consider to use DateTime.strptime instead of this
8165
8406
  * method as possible.
8166
8407
  *
8167
8408
  * If the optional second argument is true and the detected year is in
@@ -8175,20 +8416,19 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
8175
8416
  * #=> #<DateTime: 2001-02-03T16:05:06+00:00 ...>
8176
8417
  *
8177
8418
  * Raise an ArgumentError when the string length is longer than _limit_.
8178
- * You can stop this check by passing `limit: nil`, but note that
8179
- * it may take a long time to parse.
8419
+ * You can stop this check by passing <code>limit: nil</code>, but note
8420
+ * that it may take a long time to parse.
8180
8421
  */
8181
8422
  static VALUE
8182
8423
  datetime_s_parse(int argc, VALUE *argv, VALUE klass)
8183
8424
  {
8184
8425
  VALUE str, comp, sg, opt;
8185
8426
 
8186
- rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
8187
- if (!NIL_P(opt)) argc--;
8427
+ argc = rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
8188
8428
 
8189
8429
  switch (argc) {
8190
8430
  case 0:
8191
- str = rb_str_new2("-4712-01-01T00:00:00+00:00");
8431
+ str = rb_str_new2(JULIAN_EPOCH_DATETIME);
8192
8432
  case 1:
8193
8433
  comp = Qtrue;
8194
8434
  case 2:
@@ -8197,12 +8437,12 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
8197
8437
 
8198
8438
  {
8199
8439
  int argc2 = 2;
8200
- VALUE argv2[3];
8440
+ VALUE argv2[3], hash;
8201
8441
  argv2[0] = str;
8202
8442
  argv2[1] = comp;
8203
8443
  argv2[2] = opt;
8204
8444
  if (!NIL_P(opt)) argc2++;
8205
- VALUE hash = date_s__parse(argc2, argv2, klass);
8445
+ hash = date_s__parse(argc2, argv2, klass);
8206
8446
  return dt_new_by_frags(klass, hash, sg);
8207
8447
  }
8208
8448
  }
@@ -8222,31 +8462,30 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
8222
8462
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8223
8463
  *
8224
8464
  * Raise an ArgumentError when the string length is longer than _limit_.
8225
- * You can stop this check by passing `limit: nil`, but note that
8226
- * it may take a long time to parse.
8465
+ * You can stop this check by passing <code>limit: nil</code>, but note
8466
+ * that it may take a long time to parse.
8227
8467
  */
8228
8468
  static VALUE
8229
8469
  datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
8230
8470
  {
8231
8471
  VALUE str, sg, opt;
8232
8472
 
8233
- rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8234
- if (!NIL_P(opt)) argc--;
8473
+ argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8235
8474
 
8236
8475
  switch (argc) {
8237
8476
  case 0:
8238
- str = rb_str_new2("-4712-01-01T00:00:00+00:00");
8477
+ str = rb_str_new2(JULIAN_EPOCH_DATETIME);
8239
8478
  case 1:
8240
8479
  sg = INT2FIX(DEFAULT_SG);
8241
8480
  }
8242
8481
 
8243
8482
  {
8244
8483
  int argc2 = 1;
8245
- VALUE argv2[2];
8484
+ VALUE argv2[2], hash;
8246
8485
  argv2[0] = str;
8247
8486
  argv2[1] = opt;
8248
- if (!NIL_P(opt)) argc2--;
8249
- VALUE hash = date_s__iso8601(argc2, argv2, klass);
8487
+ if (!NIL_P(opt)) argc2++;
8488
+ hash = date_s__iso8601(argc2, argv2, klass);
8250
8489
  return dt_new_by_frags(klass, hash, sg);
8251
8490
  }
8252
8491
  }
@@ -8262,31 +8501,30 @@ datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
8262
8501
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8263
8502
  *
8264
8503
  * Raise an ArgumentError when the string length is longer than _limit_.
8265
- * You can stop this check by passing `limit: nil`, but note that
8266
- * it may take a long time to parse.
8504
+ * You can stop this check by passing <code>limit: nil</code>, but note
8505
+ * that it may take a long time to parse.
8267
8506
  */
8268
8507
  static VALUE
8269
8508
  datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
8270
8509
  {
8271
8510
  VALUE str, sg, opt;
8272
8511
 
8273
- rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8274
- if (!NIL_P(opt)) argc--;
8512
+ argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8275
8513
 
8276
8514
  switch (argc) {
8277
8515
  case 0:
8278
- str = rb_str_new2("-4712-01-01T00:00:00+00:00");
8516
+ str = rb_str_new2(JULIAN_EPOCH_DATETIME);
8279
8517
  case 1:
8280
8518
  sg = INT2FIX(DEFAULT_SG);
8281
8519
  }
8282
8520
 
8283
8521
  {
8284
8522
  int argc2 = 1;
8285
- VALUE argv2[2];
8523
+ VALUE argv2[2], hash;
8286
8524
  argv2[0] = str;
8287
8525
  argv2[1] = opt;
8288
8526
  if (!NIL_P(opt)) argc2++;
8289
- VALUE hash = date_s__rfc3339(argc2, argv2, klass);
8527
+ hash = date_s__rfc3339(argc2, argv2, klass);
8290
8528
  return dt_new_by_frags(klass, hash, sg);
8291
8529
  }
8292
8530
  }
@@ -8302,31 +8540,30 @@ datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
8302
8540
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8303
8541
  *
8304
8542
  * Raise an ArgumentError when the string length is longer than _limit_.
8305
- * You can stop this check by passing `limit: nil`, but note that
8306
- * it may take a long time to parse.
8543
+ * You can stop this check by passing <code>limit: nil</code>, but note
8544
+ * that it may take a long time to parse.
8307
8545
  */
8308
8546
  static VALUE
8309
8547
  datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
8310
8548
  {
8311
8549
  VALUE str, sg, opt;
8312
8550
 
8313
- rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8314
- if (!NIL_P(opt)) argc--;
8551
+ argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8315
8552
 
8316
8553
  switch (argc) {
8317
8554
  case 0:
8318
- str = rb_str_new2("-4712-01-01T00:00:00+00:00");
8555
+ str = rb_str_new2(JULIAN_EPOCH_DATETIME);
8319
8556
  case 1:
8320
8557
  sg = INT2FIX(DEFAULT_SG);
8321
8558
  }
8322
8559
 
8323
8560
  {
8324
8561
  int argc2 = 1;
8325
- VALUE argv2[2];
8562
+ VALUE argv2[2], hash;
8326
8563
  argv2[0] = str;
8327
8564
  argv2[1] = opt;
8328
8565
  if (!NIL_P(opt)) argc2++;
8329
- VALUE hash = date_s__xmlschema(argc2, argv2, klass);
8566
+ hash = date_s__xmlschema(argc2, argv2, klass);
8330
8567
  return dt_new_by_frags(klass, hash, sg);
8331
8568
  }
8332
8569
  }
@@ -8343,31 +8580,30 @@ datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
8343
8580
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8344
8581
  *
8345
8582
  * Raise an ArgumentError when the string length is longer than _limit_.
8346
- * You can stop this check by passing `limit: nil`, but note that
8347
- * it may take a long time to parse.
8583
+ * You can stop this check by passing <code>limit: nil</code>, but note
8584
+ * that it may take a long time to parse.
8348
8585
  */
8349
8586
  static VALUE
8350
8587
  datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
8351
8588
  {
8352
8589
  VALUE str, sg, opt;
8353
8590
 
8354
- rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8355
- if (!NIL_P(opt)) argc--;
8591
+ argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8356
8592
 
8357
8593
  switch (argc) {
8358
8594
  case 0:
8359
- str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000");
8595
+ str = rb_str_new2(JULIAN_EPOCH_DATETIME_RFC3339);
8360
8596
  case 1:
8361
8597
  sg = INT2FIX(DEFAULT_SG);
8362
8598
  }
8363
8599
 
8364
8600
  {
8365
8601
  int argc2 = 1;
8366
- VALUE argv2[2];
8602
+ VALUE argv2[2], hash;
8367
8603
  argv2[0] = str;
8368
8604
  argv2[1] = opt;
8369
8605
  if (!NIL_P(opt)) argc2++;
8370
- VALUE hash = date_s__rfc2822(argc2, argv2, klass);
8606
+ hash = date_s__rfc2822(argc2, argv2, klass);
8371
8607
  return dt_new_by_frags(klass, hash, sg);
8372
8608
  }
8373
8609
  }
@@ -8383,31 +8619,30 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
8383
8619
  * #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>
8384
8620
  *
8385
8621
  * Raise an ArgumentError when the string length is longer than _limit_.
8386
- * You can stop this check by passing `limit: nil`, but note that
8387
- * it may take a long time to parse.
8622
+ * You can stop this check by passing <code>limit: nil</code>, but note
8623
+ * that it may take a long time to parse.
8388
8624
  */
8389
8625
  static VALUE
8390
8626
  datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
8391
8627
  {
8392
8628
  VALUE str, sg, opt;
8393
8629
 
8394
- rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8395
- if (!NIL_P(opt)) argc--;
8630
+ argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8396
8631
 
8397
8632
  switch (argc) {
8398
8633
  case 0:
8399
- str = rb_str_new2("Mon, 01 Jan -4712 00:00:00 GMT");
8634
+ str = rb_str_new2(JULIAN_EPOCH_DATETIME_HTTPDATE);
8400
8635
  case 1:
8401
8636
  sg = INT2FIX(DEFAULT_SG);
8402
8637
  }
8403
8638
 
8404
8639
  {
8405
8640
  int argc2 = 1;
8406
- VALUE argv2[2];
8641
+ VALUE argv2[2], hash;
8407
8642
  argv2[0] = str;
8408
8643
  argv2[1] = opt;
8409
8644
  if (!NIL_P(opt)) argc2++;
8410
- VALUE hash = date_s__httpdate(argc2, argv2, klass);
8645
+ hash = date_s__httpdate(argc2, argv2, klass);
8411
8646
  return dt_new_by_frags(klass, hash, sg);
8412
8647
  }
8413
8648
  }
@@ -8428,31 +8663,30 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
8428
8663
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8429
8664
  *
8430
8665
  * Raise an ArgumentError when the string length is longer than _limit_.
8431
- * You can stop this check by passing `limit: nil`, but note that
8432
- * it may take a long time to parse.
8666
+ * You can stop this check by passing <code>limit: nil</code>, but note
8667
+ * that it may take a long time to parse.
8433
8668
  */
8434
8669
  static VALUE
8435
8670
  datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
8436
8671
  {
8437
8672
  VALUE str, sg, opt;
8438
8673
 
8439
- rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8440
- if (!NIL_P(opt)) argc--;
8674
+ argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8441
8675
 
8442
8676
  switch (argc) {
8443
8677
  case 0:
8444
- str = rb_str_new2("-4712-01-01T00:00:00+00:00");
8678
+ str = rb_str_new2(JULIAN_EPOCH_DATETIME);
8445
8679
  case 1:
8446
8680
  sg = INT2FIX(DEFAULT_SG);
8447
8681
  }
8448
8682
 
8449
8683
  {
8450
8684
  int argc2 = 1;
8451
- VALUE argv2[2];
8685
+ VALUE argv2[2], hash;
8452
8686
  argv2[0] = str;
8453
8687
  argv2[1] = opt;
8454
8688
  if (!NIL_P(opt)) argc2++;
8455
- VALUE hash = date_s__jisx0301(argc2, argv2, klass);
8689
+ hash = date_s__jisx0301(argc2, argv2, klass);
8456
8690
  return dt_new_by_frags(klass, hash, sg);
8457
8691
  }
8458
8692
  }
@@ -8475,181 +8709,16 @@ dt_lite_to_s(VALUE self)
8475
8709
 
8476
8710
  /*
8477
8711
  * call-seq:
8478
- * dt.strftime([format='%FT%T%:z']) -> string
8479
- *
8480
- * Formats date according to the directives in the given format
8481
- * string.
8482
- * The directives begin with a percent (%) character.
8483
- * Any text not listed as a directive will be passed through to the
8484
- * output string.
8485
- *
8486
- * A directive consists of a percent (%) character,
8487
- * zero or more flags, an optional minimum field width,
8488
- * an optional modifier, and a conversion specifier
8489
- * as follows.
8490
- *
8491
- * %<flags><width><modifier><conversion>
8492
- *
8493
- * Flags:
8494
- * - don't pad a numerical output.
8495
- * _ use spaces for padding.
8496
- * 0 use zeros for padding.
8497
- * ^ upcase the result string.
8498
- * # change case.
8499
- * : use colons for %z.
8500
- *
8501
- * The minimum field width specifies the minimum width.
8502
- *
8503
- * The modifiers are "E" and "O".
8504
- * They are ignored.
8505
- *
8506
- * Format directives:
8507
- *
8508
- * Date (Year, Month, Day):
8509
- * %Y - Year with century (can be negative, 4 digits at least)
8510
- * -0001, 0000, 1995, 2009, 14292, etc.
8511
- * %C - year / 100 (round down. 20 in 2009)
8512
- * %y - year % 100 (00..99)
8513
- *
8514
- * %m - Month of the year, zero-padded (01..12)
8515
- * %_m blank-padded ( 1..12)
8516
- * %-m no-padded (1..12)
8517
- * %B - The full month name (``January'')
8518
- * %^B uppercased (``JANUARY'')
8519
- * %b - The abbreviated month name (``Jan'')
8520
- * %^b uppercased (``JAN'')
8521
- * %h - Equivalent to %b
8522
- *
8523
- * %d - Day of the month, zero-padded (01..31)
8524
- * %-d no-padded (1..31)
8525
- * %e - Day of the month, blank-padded ( 1..31)
8526
- *
8527
- * %j - Day of the year (001..366)
8528
- *
8529
- * Time (Hour, Minute, Second, Subsecond):
8530
- * %H - Hour of the day, 24-hour clock, zero-padded (00..23)
8531
- * %k - Hour of the day, 24-hour clock, blank-padded ( 0..23)
8532
- * %I - Hour of the day, 12-hour clock, zero-padded (01..12)
8533
- * %l - Hour of the day, 12-hour clock, blank-padded ( 1..12)
8534
- * %P - Meridian indicator, lowercase (``am'' or ``pm'')
8535
- * %p - Meridian indicator, uppercase (``AM'' or ``PM'')
8536
- *
8537
- * %M - Minute of the hour (00..59)
8538
- *
8539
- * %S - Second of the minute (00..60)
8540
- *
8541
- * %L - Millisecond of the second (000..999)
8542
- * %N - Fractional seconds digits, default is 9 digits (nanosecond)
8543
- * %3N millisecond (3 digits) %15N femtosecond (15 digits)
8544
- * %6N microsecond (6 digits) %18N attosecond (18 digits)
8545
- * %9N nanosecond (9 digits) %21N zeptosecond (21 digits)
8546
- * %12N picosecond (12 digits) %24N yoctosecond (24 digits)
8547
- *
8548
- * Time zone:
8549
- * %z - Time zone as hour and minute offset from UTC (e.g. +0900)
8550
- * %:z - hour and minute offset from UTC with a colon (e.g. +09:00)
8551
- * %::z - hour, minute and second offset from UTC (e.g. +09:00:00)
8552
- * %:::z - hour, minute and second offset from UTC
8553
- * (e.g. +09, +09:30, +09:30:30)
8554
- * %Z - Equivalent to %:z (e.g. +09:00)
8555
- *
8556
- * Weekday:
8557
- * %A - The full weekday name (``Sunday'')
8558
- * %^A uppercased (``SUNDAY'')
8559
- * %a - The abbreviated name (``Sun'')
8560
- * %^a uppercased (``SUN'')
8561
- * %u - Day of the week (Monday is 1, 1..7)
8562
- * %w - Day of the week (Sunday is 0, 0..6)
8563
- *
8564
- * ISO 8601 week-based year and week number:
8565
- * The week 1 of YYYY starts with a Monday and includes YYYY-01-04.
8566
- * The days in the year before the first week are in the last week of
8567
- * the previous year.
8568
- * %G - The week-based year
8569
- * %g - The last 2 digits of the week-based year (00..99)
8570
- * %V - Week number of the week-based year (01..53)
8571
- *
8572
- * Week number:
8573
- * The week 1 of YYYY starts with a Sunday or Monday (according to %U
8574
- * or %W). The days in the year before the first week are in week 0.
8575
- * %U - Week number of the year. The week starts with Sunday. (00..53)
8576
- * %W - Week number of the year. The week starts with Monday. (00..53)
8577
- *
8578
- * Seconds since the Unix Epoch:
8579
- * %s - Number of seconds since 1970-01-01 00:00:00 UTC.
8580
- * %Q - Number of milliseconds since 1970-01-01 00:00:00 UTC.
8581
- *
8582
- * Literal string:
8583
- * %n - Newline character (\n)
8584
- * %t - Tab character (\t)
8585
- * %% - Literal ``%'' character
8586
- *
8587
- * Combination:
8588
- * %c - date and time (%a %b %e %T %Y)
8589
- * %D - Date (%m/%d/%y)
8590
- * %F - The ISO 8601 date format (%Y-%m-%d)
8591
- * %v - VMS date (%e-%^b-%Y)
8592
- * %x - Same as %D
8593
- * %X - Same as %T
8594
- * %r - 12-hour time (%I:%M:%S %p)
8595
- * %R - 24-hour time (%H:%M)
8596
- * %T - 24-hour time (%H:%M:%S)
8597
- * %+ - date(1) (%a %b %e %H:%M:%S %Z %Y)
8598
- *
8599
- * This method is similar to the strftime() function defined in ISO C
8600
- * and POSIX.
8601
- * Several directives (%a, %A, %b, %B, %c, %p, %r, %x, %X, %E*, %O* and %Z)
8602
- * are locale dependent in the function.
8603
- * However, this method is locale independent.
8604
- * So, the result may differ even if the same format string is used in other
8605
- * systems such as C.
8606
- * It is good practice to avoid %x and %X because there are corresponding
8607
- * locale independent representations, %D and %T.
8608
- *
8609
- * Examples:
8610
- *
8611
- * d = DateTime.new(2007,11,19,8,37,48,"-06:00")
8612
- * #=> #<DateTime: 2007-11-19T08:37:48-0600 ...>
8613
- * d.strftime("Printed on %m/%d/%Y") #=> "Printed on 11/19/2007"
8614
- * d.strftime("at %I:%M%p") #=> "at 08:37AM"
8615
- *
8616
- * Various ISO 8601 formats:
8617
- * %Y%m%d => 20071119 Calendar date (basic)
8618
- * %F => 2007-11-19 Calendar date (extended)
8619
- * %Y-%m => 2007-11 Calendar date, reduced accuracy, specific month
8620
- * %Y => 2007 Calendar date, reduced accuracy, specific year
8621
- * %C => 20 Calendar date, reduced accuracy, specific century
8622
- * %Y%j => 2007323 Ordinal date (basic)
8623
- * %Y-%j => 2007-323 Ordinal date (extended)
8624
- * %GW%V%u => 2007W471 Week date (basic)
8625
- * %G-W%V-%u => 2007-W47-1 Week date (extended)
8626
- * %GW%V => 2007W47 Week date, reduced accuracy, specific week (basic)
8627
- * %G-W%V => 2007-W47 Week date, reduced accuracy, specific week (extended)
8628
- * %H%M%S => 083748 Local time (basic)
8629
- * %T => 08:37:48 Local time (extended)
8630
- * %H%M => 0837 Local time, reduced accuracy, specific minute (basic)
8631
- * %H:%M => 08:37 Local time, reduced accuracy, specific minute (extended)
8632
- * %H => 08 Local time, reduced accuracy, specific hour
8633
- * %H%M%S,%L => 083748,000 Local time with decimal fraction, comma as decimal sign (basic)
8634
- * %T,%L => 08:37:48,000 Local time with decimal fraction, comma as decimal sign (extended)
8635
- * %H%M%S.%L => 083748.000 Local time with decimal fraction, full stop as decimal sign (basic)
8636
- * %T.%L => 08:37:48.000 Local time with decimal fraction, full stop as decimal sign (extended)
8637
- * %H%M%S%z => 083748-0600 Local time and the difference from UTC (basic)
8638
- * %T%:z => 08:37:48-06:00 Local time and the difference from UTC (extended)
8639
- * %Y%m%dT%H%M%S%z => 20071119T083748-0600 Date and time of day for calendar date (basic)
8640
- * %FT%T%:z => 2007-11-19T08:37:48-06:00 Date and time of day for calendar date (extended)
8641
- * %Y%jT%H%M%S%z => 2007323T083748-0600 Date and time of day for ordinal date (basic)
8642
- * %Y-%jT%T%:z => 2007-323T08:37:48-06:00 Date and time of day for ordinal date (extended)
8643
- * %GW%V%uT%H%M%S%z => 2007W471T083748-0600 Date and time of day for week date (basic)
8644
- * %G-W%V-%uT%T%:z => 2007-W47-1T08:37:48-06:00 Date and time of day for week date (extended)
8645
- * %Y%m%dT%H%M => 20071119T0837 Calendar date and local time (basic)
8646
- * %FT%R => 2007-11-19T08:37 Calendar date and local time (extended)
8647
- * %Y%jT%H%MZ => 2007323T0837Z Ordinal date and UTC of day (basic)
8648
- * %Y-%jT%RZ => 2007-323T08:37Z Ordinal date and UTC of day (extended)
8649
- * %GW%V%uT%H%M%z => 2007W471T0837-0600 Week date and local time and difference from UTC (basic)
8650
- * %G-W%V-%uT%R%:z => 2007-W47-1T08:37-06:00 Week date and local time and difference from UTC (extended)
8651
- *
8652
- * See also strftime(3) and ::strptime.
8712
+ * strftime(format = '%FT%T%:z') -> string
8713
+ *
8714
+ * Returns a string representation of +self+,
8715
+ * formatted according the given +format:
8716
+ *
8717
+ * DateTime.now.strftime # => "2022-07-01T11:03:19-05:00"
8718
+ *
8719
+ * For other formats,
8720
+ * see {Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc]:
8721
+ *
8653
8722
  */
8654
8723
  static VALUE
8655
8724
  dt_lite_strftime(int argc, VALUE *argv, VALUE self)
@@ -8737,6 +8806,47 @@ dt_lite_jisx0301(int argc, VALUE *argv, VALUE self)
8737
8806
  iso8601_timediv(self, n));
8738
8807
  }
8739
8808
 
8809
+ /*
8810
+ * call-seq:
8811
+ * deconstruct_keys(array_of_names_or_nil) -> hash
8812
+ *
8813
+ * Returns a hash of the name/value pairs, to use in pattern matching.
8814
+ * Possible keys are: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
8815
+ * <tt>:wday</tt>, <tt>:yday</tt>, <tt>:hour</tt>, <tt>:min</tt>,
8816
+ * <tt>:sec</tt>, <tt>:sec_fraction</tt>, <tt>:zone</tt>.
8817
+ *
8818
+ * Possible usages:
8819
+ *
8820
+ * dt = DateTime.new(2022, 10, 5, 13, 30)
8821
+ *
8822
+ * if d in wday: 1..5, hour: 10..18 # uses deconstruct_keys underneath
8823
+ * puts "Working time"
8824
+ * end
8825
+ * #=> prints "Working time"
8826
+ *
8827
+ * case dt
8828
+ * in year: ...2022
8829
+ * puts "too old"
8830
+ * in month: ..9
8831
+ * puts "quarter 1-3"
8832
+ * in wday: 1..5, month:
8833
+ * puts "working day in month #{month}"
8834
+ * end
8835
+ * #=> prints "working day in month 10"
8836
+ *
8837
+ * Note that deconstruction by pattern can also be combined with class check:
8838
+ *
8839
+ * if d in DateTime(wday: 1..5, hour: 10..18, day: ..7)
8840
+ * puts "Working time, first week of the month"
8841
+ * end
8842
+ *
8843
+ */
8844
+ static VALUE
8845
+ dt_lite_deconstruct_keys(VALUE self, VALUE keys)
8846
+ {
8847
+ return deconstruct_keys(self, keys, /* is_datetime=true */ 1);
8848
+ }
8849
+
8740
8850
  /* conversions */
8741
8851
 
8742
8852
  #define f_subsec(x) rb_funcall(x, rb_intern("subsec"), 0)
@@ -8815,7 +8925,7 @@ time_to_datetime(VALUE self)
8815
8925
  ret = d_complex_new_internal(cDateTime,
8816
8926
  nth, 0,
8817
8927
  0, sf,
8818
- of, DEFAULT_SG,
8928
+ of, GREGORIAN,
8819
8929
  ry, m, d,
8820
8930
  h, min, s,
8821
8931
  HAVE_CIVIL | HAVE_TIME);
@@ -8828,33 +8938,43 @@ time_to_datetime(VALUE self)
8828
8938
 
8829
8939
  /*
8830
8940
  * call-seq:
8831
- * d.to_time -> time
8941
+ * to_time -> time
8942
+ *
8943
+ * Returns a new Time object with the same value as +self+;
8944
+ * if +self+ is a Julian date, derives its Gregorian date
8945
+ * for conversion to the \Time object:
8946
+ *
8947
+ * Date.new(2001, 2, 3).to_time # => 2001-02-03 00:00:00 -0600
8948
+ * Date.new(2001, 2, 3, Date::JULIAN).to_time # => 2001-02-16 00:00:00 -0600
8832
8949
  *
8833
- * Returns a Time object which denotes self. If self is a julian date,
8834
- * convert it to a gregorian date before converting it to Time.
8835
8950
  */
8836
8951
  static VALUE
8837
8952
  date_to_time(VALUE self)
8838
8953
  {
8954
+ VALUE t;
8955
+
8839
8956
  get_d1a(self);
8840
8957
 
8841
8958
  if (m_julian_p(adat)) {
8842
- VALUE tmp = d_lite_gregorian(self);
8843
- get_d1b(tmp);
8959
+ VALUE g = d_lite_gregorian(self);
8960
+ get_d1b(g);
8844
8961
  adat = bdat;
8962
+ self = g;
8845
8963
  }
8846
8964
 
8847
- return f_local3(rb_cTime,
8965
+ t = f_local3(rb_cTime,
8848
8966
  m_real_year(adat),
8849
8967
  INT2FIX(m_mon(adat)),
8850
8968
  INT2FIX(m_mday(adat)));
8969
+ RB_GC_GUARD(self); /* may be the converted gregorian */
8970
+ return t;
8851
8971
  }
8852
8972
 
8853
8973
  /*
8854
8974
  * call-seq:
8855
- * d.to_date -> self
8975
+ * to_date -> self
8856
8976
  *
8857
- * Returns self.
8977
+ * Returns +self+.
8858
8978
  */
8859
8979
  static VALUE
8860
8980
  date_to_date(VALUE self)
@@ -8866,7 +8986,10 @@ date_to_date(VALUE self)
8866
8986
  * call-seq:
8867
8987
  * d.to_datetime -> datetime
8868
8988
  *
8869
- * Returns a DateTime object which denotes self.
8989
+ * Returns a DateTime whose value is the same as +self+:
8990
+ *
8991
+ * Date.new(2001, 2, 3).to_datetime # => #<DateTime: 2001-02-03T00:00:00+00:00>
8992
+ *
8870
8993
  */
8871
8994
  static VALUE
8872
8995
  date_to_datetime(VALUE self)
@@ -8911,12 +9034,18 @@ date_to_datetime(VALUE self)
8911
9034
  static VALUE
8912
9035
  datetime_to_time(VALUE self)
8913
9036
  {
8914
- volatile VALUE dup = dup_obj(self);
9037
+ get_d1(self);
9038
+
9039
+ if (m_julian_p(dat)) {
9040
+ VALUE g = d_lite_gregorian(self);
9041
+ get_d1a(g);
9042
+ dat = adat;
9043
+ self = g;
9044
+ }
9045
+
8915
9046
  {
8916
9047
  VALUE t;
8917
9048
 
8918
- get_d1(dup);
8919
-
8920
9049
  t = rb_funcall(rb_cTime,
8921
9050
  rb_intern("new"),
8922
9051
  7,
@@ -8928,6 +9057,7 @@ datetime_to_time(VALUE self)
8928
9057
  f_add(INT2FIX(m_sec(dat)),
8929
9058
  m_sf_in_sec(dat)),
8930
9059
  INT2FIX(m_of(dat)));
9060
+ RB_GC_GUARD(self); /* may be the converted gregorian */
8931
9061
  return t;
8932
9062
  }
8933
9063
  }
@@ -8984,6 +9114,7 @@ datetime_to_datetime(VALUE self)
8984
9114
  #define MIN_JD -327
8985
9115
  #define MAX_JD 366963925
8986
9116
 
9117
+ /* :nodoc: */
8987
9118
  static int
8988
9119
  test_civil(int from, int to, double sg)
8989
9120
  {
@@ -9004,6 +9135,7 @@ test_civil(int from, int to, double sg)
9004
9135
  return 1;
9005
9136
  }
9006
9137
 
9138
+ /* :nodoc: */
9007
9139
  static VALUE
9008
9140
  date_s_test_civil(VALUE klass)
9009
9141
  {
@@ -9024,6 +9156,7 @@ date_s_test_civil(VALUE klass)
9024
9156
  return Qtrue;
9025
9157
  }
9026
9158
 
9159
+ /* :nodoc: */
9027
9160
  static int
9028
9161
  test_ordinal(int from, int to, double sg)
9029
9162
  {
@@ -9044,6 +9177,7 @@ test_ordinal(int from, int to, double sg)
9044
9177
  return 1;
9045
9178
  }
9046
9179
 
9180
+ /* :nodoc: */
9047
9181
  static VALUE
9048
9182
  date_s_test_ordinal(VALUE klass)
9049
9183
  {
@@ -9064,6 +9198,7 @@ date_s_test_ordinal(VALUE klass)
9064
9198
  return Qtrue;
9065
9199
  }
9066
9200
 
9201
+ /* :nodoc: */
9067
9202
  static int
9068
9203
  test_commercial(int from, int to, double sg)
9069
9204
  {
@@ -9084,6 +9219,7 @@ test_commercial(int from, int to, double sg)
9084
9219
  return 1;
9085
9220
  }
9086
9221
 
9222
+ /* :nodoc: */
9087
9223
  static VALUE
9088
9224
  date_s_test_commercial(VALUE klass)
9089
9225
  {
@@ -9104,6 +9240,7 @@ date_s_test_commercial(VALUE klass)
9104
9240
  return Qtrue;
9105
9241
  }
9106
9242
 
9243
+ /* :nodoc: */
9107
9244
  static int
9108
9245
  test_weeknum(int from, int to, int f, double sg)
9109
9246
  {
@@ -9124,6 +9261,7 @@ test_weeknum(int from, int to, int f, double sg)
9124
9261
  return 1;
9125
9262
  }
9126
9263
 
9264
+ /* :nodoc: */
9127
9265
  static VALUE
9128
9266
  date_s_test_weeknum(VALUE klass)
9129
9267
  {
@@ -9148,6 +9286,7 @@ date_s_test_weeknum(VALUE klass)
9148
9286
  return Qtrue;
9149
9287
  }
9150
9288
 
9289
+ /* :nodoc: */
9151
9290
  static int
9152
9291
  test_nth_kday(int from, int to, double sg)
9153
9292
  {
@@ -9168,6 +9307,7 @@ test_nth_kday(int from, int to, double sg)
9168
9307
  return 1;
9169
9308
  }
9170
9309
 
9310
+ /* :nodoc: */
9171
9311
  static VALUE
9172
9312
  date_s_test_nth_kday(VALUE klass)
9173
9313
  {
@@ -9188,6 +9328,7 @@ date_s_test_nth_kday(VALUE klass)
9188
9328
  return Qtrue;
9189
9329
  }
9190
9330
 
9331
+ /* :nodoc: */
9191
9332
  static int
9192
9333
  test_unit_v2v(VALUE i,
9193
9334
  VALUE (* conv1)(VALUE),
@@ -9199,6 +9340,7 @@ test_unit_v2v(VALUE i,
9199
9340
  return f_eqeq_p(o, i);
9200
9341
  }
9201
9342
 
9343
+ /* :nodoc: */
9202
9344
  static int
9203
9345
  test_unit_v2v_iter2(VALUE (* conv1)(VALUE),
9204
9346
  VALUE (* conv2)(VALUE))
@@ -9230,6 +9372,7 @@ test_unit_v2v_iter2(VALUE (* conv1)(VALUE),
9230
9372
  return 1;
9231
9373
  }
9232
9374
 
9375
+ /* :nodoc: */
9233
9376
  static int
9234
9377
  test_unit_v2v_iter(VALUE (* conv1)(VALUE),
9235
9378
  VALUE (* conv2)(VALUE))
@@ -9241,6 +9384,7 @@ test_unit_v2v_iter(VALUE (* conv1)(VALUE),
9241
9384
  return 1;
9242
9385
  }
9243
9386
 
9387
+ /* :nodoc: */
9244
9388
  static VALUE
9245
9389
  date_s_test_unit_conv(VALUE klass)
9246
9390
  {
@@ -9255,6 +9399,7 @@ date_s_test_unit_conv(VALUE klass)
9255
9399
  return Qtrue;
9256
9400
  }
9257
9401
 
9402
+ /* :nodoc: */
9258
9403
  static VALUE
9259
9404
  date_s_test_all(VALUE klass)
9260
9405
  {
@@ -9317,10 +9462,11 @@ mk_ary_of_str(long len, const char *a[])
9317
9462
  }
9318
9463
  rb_ary_push(o, e);
9319
9464
  }
9320
- rb_obj_freeze(o);
9465
+ rb_ary_freeze(o);
9321
9466
  return o;
9322
9467
  }
9323
9468
 
9469
+ /* :nodoc: */
9324
9470
  static VALUE
9325
9471
  d_lite_zero(VALUE x)
9326
9472
  {
@@ -9338,7 +9484,19 @@ Init_date_core(void)
9338
9484
  id_ge_p = rb_intern_const(">=");
9339
9485
  id_eqeq_p = rb_intern_const("==");
9340
9486
 
9487
+ sym_year = ID2SYM(rb_intern_const("year"));
9488
+ sym_month = ID2SYM(rb_intern_const("month"));
9489
+ sym_yday = ID2SYM(rb_intern_const("yday"));
9490
+ sym_wday = ID2SYM(rb_intern_const("wday"));
9491
+ sym_day = ID2SYM(rb_intern_const("day"));
9492
+ sym_hour = ID2SYM(rb_intern_const("hour"));
9493
+ sym_min = ID2SYM(rb_intern_const("min"));
9494
+ sym_sec = ID2SYM(rb_intern_const("sec"));
9495
+ sym_sec_fraction = ID2SYM(rb_intern_const("sec_fraction"));
9496
+ sym_zone = ID2SYM(rb_intern_const("zone"));
9497
+
9341
9498
  half_days_in_day = rb_rational_new2(INT2FIX(1), INT2FIX(2));
9499
+ rb_gc_register_mark_object(half_days_in_day);
9342
9500
 
9343
9501
  #if (LONG_MAX / DAY_IN_SECONDS) > SECOND_IN_NANOSECONDS
9344
9502
  day_in_nanoseconds = LONG2NUM((long)DAY_IN_SECONDS *
@@ -9350,160 +9508,87 @@ Init_date_core(void)
9350
9508
  day_in_nanoseconds = f_mul(INT2FIX(DAY_IN_SECONDS),
9351
9509
  INT2FIX(SECOND_IN_NANOSECONDS));
9352
9510
  #endif
9353
-
9354
- rb_gc_register_mark_object(half_days_in_day);
9355
9511
  rb_gc_register_mark_object(day_in_nanoseconds);
9356
9512
 
9357
9513
  positive_inf = +INFINITY;
9358
9514
  negative_inf = -INFINITY;
9359
9515
 
9360
9516
  /*
9361
- * date and datetime class - Tadayoshi Funaba 1998-2011
9362
- *
9363
- * 'date' provides two classes: Date and DateTime.
9364
- *
9365
- * == Terms and Definitions
9366
- *
9367
- * Some terms and definitions are based on ISO 8601 and JIS X 0301.
9368
- *
9369
- * === Calendar Date
9370
- *
9371
- * The calendar date is a particular day of a calendar year,
9372
- * identified by its ordinal number within a calendar month within
9373
- * that year.
9374
- *
9375
- * In those classes, this is so-called "civil".
9376
- *
9377
- * === Ordinal Date
9517
+ * \Class \Date provides methods for storing and manipulating
9518
+ * calendar dates.
9378
9519
  *
9379
- * The ordinal date is a particular day of a calendar year identified
9380
- * by its ordinal number within the year.
9520
+ * Consider using
9521
+ * {class Time}[rdoc-ref:Time]
9522
+ * instead of class \Date if:
9381
9523
  *
9382
- * In those classes, this is so-called "ordinal".
9524
+ * - You need both dates and times; \Date handles only dates.
9525
+ * - You need only Gregorian dates (and not Julian dates);
9526
+ * see {Julian and Gregorian Calendars}[rdoc-ref:language/calendars.rdoc].
9383
9527
  *
9384
- * === Week Date
9528
+ * A \Date object, once created, is immutable, and cannot be modified.
9385
9529
  *
9386
- * The week date is a date identified by calendar week and day numbers.
9530
+ * == Creating a \Date
9387
9531
  *
9388
- * The calendar week is a seven day period within a calendar year,
9389
- * starting on a Monday and identified by its ordinal number within
9390
- * the year; the first calendar week of the year is the one that
9391
- * includes the first Thursday of that year. In the Gregorian
9392
- * calendar, this is equivalent to the week which includes January 4.
9532
+ * You can create a date for the current date, using Date.today:
9393
9533
  *
9394
- * In those classes, this is so-called "commercial".
9534
+ * Date.today # => #<Date: 1999-12-31>
9395
9535
  *
9396
- * === Julian Day Number
9536
+ * You can create a specific date from various combinations of arguments:
9397
9537
  *
9398
- * The Julian day number is in elapsed days since noon (Greenwich Mean
9399
- * Time) on January 1, 4713 BCE (in the Julian calendar).
9538
+ * - Date.new takes integer year, month, and day-of-month:
9400
9539
  *
9401
- * In this document, the astronomical Julian day number is the same as
9402
- * the original Julian day number. And the chronological Julian day
9403
- * number is a variation of the Julian day number. Its days begin at
9404
- * midnight on local time.
9540
+ * Date.new(1999, 12, 31) # => #<Date: 1999-12-31>
9405
9541
  *
9406
- * In this document, when the term "Julian day number" simply appears,
9407
- * it just refers to "chronological Julian day number", not the
9408
- * original.
9542
+ * - Date.ordinal takes integer year and day-of-year:
9409
9543
  *
9410
- * In those classes, those are so-called "ajd" and "jd".
9544
+ * Date.ordinal(1999, 365) # => #<Date: 1999-12-31>
9411
9545
  *
9412
- * === Modified Julian Day Number
9546
+ * - Date.jd takes integer Julian day:
9413
9547
  *
9414
- * The modified Julian day number is in elapsed days since midnight
9415
- * (Coordinated Universal Time) on November 17, 1858 CE (in the
9416
- * Gregorian calendar).
9548
+ * Date.jd(2451544) # => #<Date: 1999-12-31>
9417
9549
  *
9418
- * In this document, the astronomical modified Julian day number is
9419
- * the same as the original modified Julian day number. And the
9420
- * chronological modified Julian day number is a variation of the
9421
- * modified Julian day number. Its days begin at midnight on local
9422
- * time.
9550
+ * - Date.commercial takes integer commercial data (year, week, day-of-week):
9423
9551
  *
9424
- * In this document, when the term "modified Julian day number" simply
9425
- * appears, it just refers to "chronological modified Julian day
9426
- * number", not the original.
9552
+ * Date.commercial(1999, 52, 5) # => #<Date: 1999-12-31>
9427
9553
  *
9428
- * In those classes, those are so-called "amjd" and "mjd".
9554
+ * - Date.parse takes a string, which it parses heuristically:
9429
9555
  *
9430
- * == Date
9556
+ * Date.parse('1999-12-31') # => #<Date: 1999-12-31>
9557
+ * Date.parse('31-12-1999') # => #<Date: 1999-12-31>
9558
+ * Date.parse('1999-365') # => #<Date: 1999-12-31>
9559
+ * Date.parse('1999-W52-5') # => #<Date: 1999-12-31>
9431
9560
  *
9432
- * A subclass of Object that includes the Comparable module and
9433
- * easily handles date.
9561
+ * - Date.strptime takes a date string and a format string,
9562
+ * then parses the date string according to the format string:
9434
9563
  *
9435
- * A Date object is created with Date::new, Date::jd, Date::ordinal,
9436
- * Date::commercial, Date::parse, Date::strptime, Date::today,
9437
- * Time#to_date, etc.
9564
+ * Date.strptime('1999-12-31', '%Y-%m-%d') # => #<Date: 1999-12-31>
9565
+ * Date.strptime('31-12-1999', '%d-%m-%Y') # => #<Date: 1999-12-31>
9566
+ * Date.strptime('1999-365', '%Y-%j') # => #<Date: 1999-12-31>
9567
+ * Date.strptime('1999-W52-5', '%G-W%V-%u') # => #<Date: 1999-12-31>
9568
+ * Date.strptime('1999 52 5', '%Y %U %w') # => #<Date: 1999-12-31>
9569
+ * Date.strptime('1999 52 5', '%Y %W %u') # => #<Date: 1999-12-31>
9570
+ * Date.strptime('fri31dec99', '%a%d%b%y') # => #<Date: 1999-12-31>
9438
9571
  *
9439
- * require 'date'
9440
- *
9441
- * Date.new(2001,2,3)
9442
- * #=> #<Date: 2001-02-03 ...>
9443
- * Date.jd(2451944)
9444
- * #=> #<Date: 2001-02-03 ...>
9445
- * Date.ordinal(2001,34)
9446
- * #=> #<Date: 2001-02-03 ...>
9447
- * Date.commercial(2001,5,6)
9448
- * #=> #<Date: 2001-02-03 ...>
9449
- * Date.parse('2001-02-03')
9450
- * #=> #<Date: 2001-02-03 ...>
9451
- * Date.strptime('03-02-2001', '%d-%m-%Y')
9452
- * #=> #<Date: 2001-02-03 ...>
9453
- * Time.new(2001,2,3).to_date
9454
- * #=> #<Date: 2001-02-03 ...>
9455
- *
9456
- * All date objects are immutable; hence cannot modify themselves.
9572
+ * See also the specialized methods in
9573
+ * {"Specialized Format Strings" in Formats for Dates and Times}[rdoc-ref:language/strftime_formatting.rdoc@Specialized+Format+Strings]
9457
9574
  *
9458
- * The concept of a date object can be represented as a tuple
9459
- * of the day count, the offset and the day of calendar reform.
9575
+ * == Argument +limit+
9460
9576
  *
9461
- * The day count denotes the absolute position of a temporal
9462
- * dimension. The offset is relative adjustment, which determines
9463
- * decoded local time with the day count. The day of calendar
9464
- * reform denotes the start day of the new style. The old style
9465
- * of the West is the Julian calendar which was adopted by
9466
- * Caesar. The new style is the Gregorian calendar, which is the
9467
- * current civil calendar of many countries.
9468
- *
9469
- * The day count is virtually the astronomical Julian day number.
9470
- * The offset in this class is usually zero, and cannot be
9471
- * specified directly.
9472
- *
9473
- * A Date object can be created with an optional argument,
9474
- * the day of calendar reform as a Julian day number, which
9475
- * should be 2298874 to 2426355 or negative/positive infinity.
9476
- * The default value is +Date::ITALY+ (2299161=1582-10-15).
9477
- * See also sample/cal.rb.
9577
+ * Certain singleton methods in \Date that parse string arguments
9578
+ * also take optional keyword argument +limit+,
9579
+ * which can limit the length of the string argument.
9478
9580
  *
9479
- * $ ruby sample/cal.rb -c it 10 1582
9480
- * October 1582
9481
- * S M Tu W Th F S
9482
- * 1 2 3 4 15 16
9483
- * 17 18 19 20 21 22 23
9484
- * 24 25 26 27 28 29 30
9485
- * 31
9581
+ * When +limit+ is:
9486
9582
  *
9487
- * $ ruby sample/cal.rb -c gb 9 1752
9488
- * September 1752
9489
- * S M Tu W Th F S
9490
- * 1 2 14 15 16
9491
- * 17 18 19 20 21 22 23
9492
- * 24 25 26 27 28 29 30
9493
- *
9494
- * A Date object has various methods. See each reference.
9495
- *
9496
- * d = Date.parse('3rd Feb 2001')
9497
- * #=> #<Date: 2001-02-03 ...>
9498
- * d.year #=> 2001
9499
- * d.mon #=> 2
9500
- * d.mday #=> 3
9501
- * d.wday #=> 6
9502
- * d += 1 #=> #<Date: 2001-02-04 ...>
9503
- * d.strftime('%a %d %b %Y') #=> "Sun 04 Feb 2001"
9583
+ * - Non-negative:
9584
+ * raises ArgumentError if the string length is greater than _limit_.
9585
+ * - Other numeric or +nil+: ignores +limit+.
9586
+ * - Other non-numeric: raises TypeError.
9504
9587
  *
9505
9588
  */
9506
9589
  cDate = rb_define_class("Date", rb_cObject);
9590
+
9591
+ /* Exception for invalid date/time */
9507
9592
  eDateError = rb_define_class_under(cDate, "Error", rb_eArgError);
9508
9593
 
9509
9594
  rb_include_module(cDate, rb_mComparable);
@@ -9730,6 +9815,8 @@ Init_date_core(void)
9730
9815
  rb_define_method(cDate, "httpdate", d_lite_httpdate, 0);
9731
9816
  rb_define_method(cDate, "jisx0301", d_lite_jisx0301, 0);
9732
9817
 
9818
+ rb_define_method(cDate, "deconstruct_keys", d_lite_deconstruct_keys, 1);
9819
+
9733
9820
  #ifndef NDEBUG
9734
9821
  rb_define_method(cDate, "marshal_dump_old", d_lite_marshal_dump_old, 0);
9735
9822
  #endif
@@ -9940,6 +10027,8 @@ Init_date_core(void)
9940
10027
  rb_define_method(cDateTime, "rfc3339", dt_lite_rfc3339, -1);
9941
10028
  rb_define_method(cDateTime, "jisx0301", dt_lite_jisx0301, -1);
9942
10029
 
10030
+ rb_define_method(cDateTime, "deconstruct_keys", dt_lite_deconstruct_keys, 1);
10031
+
9943
10032
  /* conversions */
9944
10033
 
9945
10034
  rb_define_method(rb_cTime, "to_time", time_to_time, 0);