date 3.2.0 → 3.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/date/date_core.c CHANGED
@@ -27,6 +27,10 @@ static VALUE eDateError;
27
27
  static VALUE half_days_in_day, day_in_nanoseconds;
28
28
  static double positive_inf, negative_inf;
29
29
 
30
+ // used by deconstruct_keys
31
+ static VALUE sym_year, sym_month, sym_day, sym_yday, sym_wday;
32
+ static VALUE sym_hour, sym_min, sym_sec, sym_sec_fraction, sym_zone;
33
+
30
34
  #define f_boolcast(x) ((x) ? Qtrue : Qfalse)
31
35
 
32
36
  #define f_abs(x) rb_funcall(x, rb_intern("abs"), 0)
@@ -60,7 +64,8 @@ static VALUE datetime_initialize(int argc, VALUE *argv, VALUE self);
60
64
 
61
65
  #define RETURN_FALSE_UNLESS_NUMERIC(obj) if(!RTEST(rb_obj_is_kind_of((obj), rb_cNumeric))) return Qfalse
62
66
  inline static void
63
- check_numeric(VALUE obj, const char* field) {
67
+ check_numeric(VALUE obj, const char* field)
68
+ {
64
69
  if(!RTEST(rb_obj_is_kind_of(obj, rb_cNumeric))) {
65
70
  rb_raise(rb_eTypeError, "invalid %s (not numeric)", field);
66
71
  }
@@ -465,6 +470,7 @@ c_find_ldoy(int y, double sg, int *rjd, int *ns)
465
470
  }
466
471
 
467
472
  #ifndef NDEBUG
473
+ /* :nodoc: */
468
474
  static int
469
475
  c_find_fdom(int y, int m, double sg, int *rjd, int *ns)
470
476
  {
@@ -621,6 +627,7 @@ c_jd_to_weeknum(int jd, int f, double sg, int *ry, int *rw, int *rd)
621
627
  }
622
628
 
623
629
  #ifndef NDEBUG
630
+ /* :nodoc: */
624
631
  static void
625
632
  c_nth_kday_to_jd(int y, int m, int n, int k, double sg, int *rjd, int *ns)
626
633
  {
@@ -646,6 +653,7 @@ c_jd_to_wday(int jd)
646
653
  }
647
654
 
648
655
  #ifndef NDEBUG
656
+ /* :nodoc: */
649
657
  static void
650
658
  c_jd_to_nth_kday(int jd, double sg, int *ry, int *rm, int *rn, int *rk)
651
659
  {
@@ -758,6 +766,8 @@ c_valid_civil_p(int y, int m, int d, double sg,
758
766
 
759
767
  if (m < 0)
760
768
  m += 13;
769
+ if (m < 1 || m > 12)
770
+ return 0;
761
771
  if (d < 0) {
762
772
  if (!c_find_ldom(y, m, sg, rjd, ns))
763
773
  return 0;
@@ -822,6 +832,7 @@ c_valid_weeknum_p(int y, int w, int d, int f, double sg,
822
832
  }
823
833
 
824
834
  #ifndef NDEBUG
835
+ /* :nodoc: */
825
836
  static int
826
837
  c_valid_nth_kday_p(int y, int m, int n, int k, double sg,
827
838
  int *rm, int *rn, int *rk, int *rjd, int *ns)
@@ -963,6 +974,7 @@ ns_to_day(VALUE n)
963
974
  }
964
975
 
965
976
  #ifndef NDEBUG
977
+ /* :nodoc: */
966
978
  static VALUE
967
979
  ms_to_sec(VALUE m)
968
980
  {
@@ -981,6 +993,7 @@ ns_to_sec(VALUE n)
981
993
  }
982
994
 
983
995
  #ifndef NDEBUG
996
+ /* :nodoc: */
984
997
  inline static VALUE
985
998
  ins_to_day(int n)
986
999
  {
@@ -1016,6 +1029,7 @@ day_to_sec(VALUE d)
1016
1029
  }
1017
1030
 
1018
1031
  #ifndef NDEBUG
1032
+ /* :nodoc: */
1019
1033
  static VALUE
1020
1034
  day_to_ns(VALUE d)
1021
1035
  {
@@ -1040,6 +1054,7 @@ sec_to_ns(VALUE s)
1040
1054
  }
1041
1055
 
1042
1056
  #ifndef NDEBUG
1057
+ /* :nodoc: */
1043
1058
  static VALUE
1044
1059
  isec_to_ns(int s)
1045
1060
  {
@@ -1066,6 +1081,7 @@ div_df(VALUE d, VALUE *f)
1066
1081
  }
1067
1082
 
1068
1083
  #ifndef NDEBUG
1084
+ /* :nodoc: */
1069
1085
  static VALUE
1070
1086
  div_sf(VALUE s, VALUE *f)
1071
1087
  {
@@ -1500,6 +1516,7 @@ m_df(union DateData *x)
1500
1516
  }
1501
1517
 
1502
1518
  #ifndef NDEBUG
1519
+ /* :nodoc: */
1503
1520
  static VALUE
1504
1521
  m_df_in_day(union DateData *x)
1505
1522
  {
@@ -1997,6 +2014,7 @@ expect_numeric(VALUE x)
1997
2014
  }
1998
2015
 
1999
2016
  #ifndef NDEBUG
2017
+ /* :nodoc: */
2000
2018
  static void
2001
2019
  civil_to_jd(VALUE y, int m, int d, double sg,
2002
2020
  VALUE *nth, int *ry,
@@ -2309,6 +2327,7 @@ valid_weeknum_p(VALUE y, int w, int d, int f, double sg,
2309
2327
  }
2310
2328
 
2311
2329
  #ifndef NDEBUG
2330
+ /* :nodoc: */
2312
2331
  static int
2313
2332
  valid_nth_kday_p(VALUE y, int m, int n, int k, double sg,
2314
2333
  VALUE *nth, int *ry,
@@ -2446,6 +2465,7 @@ valid_jd_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2446
2465
  }
2447
2466
 
2448
2467
  #ifndef NDEBUG
2468
+ /* :nodoc: */
2449
2469
  static VALUE
2450
2470
  date_s__valid_jd_p(int argc, VALUE *argv, VALUE klass)
2451
2471
  {
@@ -2466,13 +2486,16 @@ date_s__valid_jd_p(int argc, VALUE *argv, VALUE klass)
2466
2486
 
2467
2487
  /*
2468
2488
  * call-seq:
2469
- * Date.valid_jd?(jd[, start=Date::ITALY]) -> bool
2489
+ * Date.valid_jd?(jd, start = Date::ITALY) -> true
2490
+ *
2491
+ * Implemented for compatibility;
2492
+ * returns +true+ unless +jd+ is invalid (i.e., not a Numeric).
2470
2493
  *
2471
- * Just returns true. It's nonsense, but is for symmetry.
2494
+ * Date.valid_jd?(2451944) # => true
2472
2495
  *
2473
- * Date.valid_jd?(2451944) #=> true
2496
+ * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
2474
2497
  *
2475
- * See also ::jd.
2498
+ * Related: Date.jd.
2476
2499
  */
2477
2500
  static VALUE
2478
2501
  date_s_valid_jd_p(int argc, VALUE *argv, VALUE klass)
@@ -2532,6 +2555,7 @@ valid_civil_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2532
2555
  }
2533
2556
 
2534
2557
  #ifndef NDEBUG
2558
+ /* :nodoc: */
2535
2559
  static VALUE
2536
2560
  date_s__valid_civil_p(int argc, VALUE *argv, VALUE klass)
2537
2561
  {
@@ -2554,18 +2578,20 @@ date_s__valid_civil_p(int argc, VALUE *argv, VALUE klass)
2554
2578
 
2555
2579
  /*
2556
2580
  * call-seq:
2557
- * Date.valid_civil?(year, month, mday[, start=Date::ITALY]) -> bool
2558
- * Date.valid_date?(year, month, mday[, start=Date::ITALY]) -> bool
2581
+ * Date.valid_civil?(year, month, mday, start = Date::ITALY) -> true or false
2582
+ *
2583
+ * Returns +true+ if the arguments define a valid ordinal date,
2584
+ * +false+ otherwise:
2585
+ *
2586
+ * Date.valid_date?(2001, 2, 3) # => true
2587
+ * Date.valid_date?(2001, 2, 29) # => false
2588
+ * Date.valid_date?(2001, 2, -1) # => true
2559
2589
  *
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.
2590
+ * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
2563
2591
  *
2564
- * Date.valid_date?(2001,2,3) #=> true
2565
- * Date.valid_date?(2001,2,29) #=> false
2566
- * Date.valid_date?(2001,2,-1) #=> true
2592
+ * Date.valid_date? is an alias for Date.valid_civil?.
2567
2593
  *
2568
- * See also ::jd and ::civil.
2594
+ * Related: Date.jd, Date.new.
2569
2595
  */
2570
2596
  static VALUE
2571
2597
  date_s_valid_civil_p(int argc, VALUE *argv, VALUE klass)
@@ -2621,6 +2647,7 @@ valid_ordinal_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2621
2647
  }
2622
2648
 
2623
2649
  #ifndef NDEBUG
2650
+ /* :nodoc: */
2624
2651
  static VALUE
2625
2652
  date_s__valid_ordinal_p(int argc, VALUE *argv, VALUE klass)
2626
2653
  {
@@ -2642,14 +2669,17 @@ date_s__valid_ordinal_p(int argc, VALUE *argv, VALUE klass)
2642
2669
 
2643
2670
  /*
2644
2671
  * call-seq:
2645
- * Date.valid_ordinal?(year, yday[, start=Date::ITALY]) -> bool
2672
+ * Date.valid_ordinal?(year, yday, start = Date::ITALY) -> true or false
2673
+ *
2674
+ * Returns +true+ if the arguments define a valid ordinal date,
2675
+ * +false+ otherwise:
2646
2676
  *
2647
- * Returns true if the given ordinal date is valid, and false if not.
2677
+ * Date.valid_ordinal?(2001, 34) # => true
2678
+ * Date.valid_ordinal?(2001, 366) # => false
2648
2679
  *
2649
- * Date.valid_ordinal?(2001,34) #=> true
2650
- * Date.valid_ordinal?(2001,366) #=> false
2680
+ * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
2651
2681
  *
2652
- * See also ::jd and ::ordinal.
2682
+ * Related: Date.jd, Date.ordinal.
2653
2683
  */
2654
2684
  static VALUE
2655
2685
  date_s_valid_ordinal_p(int argc, VALUE *argv, VALUE klass)
@@ -2704,6 +2734,7 @@ valid_commercial_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2704
2734
  }
2705
2735
 
2706
2736
  #ifndef NDEBUG
2737
+ /* :nodoc: */
2707
2738
  static VALUE
2708
2739
  date_s__valid_commercial_p(int argc, VALUE *argv, VALUE klass)
2709
2740
  {
@@ -2726,14 +2757,19 @@ date_s__valid_commercial_p(int argc, VALUE *argv, VALUE klass)
2726
2757
 
2727
2758
  /*
2728
2759
  * call-seq:
2729
- * Date.valid_commercial?(cwyear, cweek, cwday[, start=Date::ITALY]) -> bool
2760
+ * Date.valid_commercial?(cwyear, cweek, cwday, start = Date::ITALY) -> true or false
2730
2761
  *
2731
- * Returns true if the given week date is valid, and false if not.
2762
+ * Returns +true+ if the arguments define a valid commercial date,
2763
+ * +false+ otherwise:
2732
2764
  *
2733
- * Date.valid_commercial?(2001,5,6) #=> true
2734
- * Date.valid_commercial?(2001,5,8) #=> false
2765
+ * Date.valid_commercial?(2001, 5, 6) # => true
2766
+ * Date.valid_commercial?(2001, 5, 8) # => false
2735
2767
  *
2736
- * See also ::jd and ::commercial.
2768
+ * See Date.commercial.
2769
+ *
2770
+ * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
2771
+ *
2772
+ * Related: Date.jd, Date.commercial.
2737
2773
  */
2738
2774
  static VALUE
2739
2775
  date_s_valid_commercial_p(int argc, VALUE *argv, VALUE klass)
@@ -2760,6 +2796,7 @@ date_s_valid_commercial_p(int argc, VALUE *argv, VALUE klass)
2760
2796
  }
2761
2797
 
2762
2798
  #ifndef NDEBUG
2799
+ /* :nodoc: */
2763
2800
  static VALUE
2764
2801
  valid_weeknum_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2765
2802
  {
@@ -2791,6 +2828,7 @@ valid_weeknum_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2791
2828
  }
2792
2829
  }
2793
2830
 
2831
+ /* :nodoc: */
2794
2832
  static VALUE
2795
2833
  date_s__valid_weeknum_p(int argc, VALUE *argv, VALUE klass)
2796
2834
  {
@@ -2811,6 +2849,7 @@ date_s__valid_weeknum_p(int argc, VALUE *argv, VALUE klass)
2811
2849
  return valid_weeknum_sub(5, argv2, klass, 1);
2812
2850
  }
2813
2851
 
2852
+ /* :nodoc: */
2814
2853
  static VALUE
2815
2854
  date_s_valid_weeknum_p(int argc, VALUE *argv, VALUE klass)
2816
2855
  {
@@ -2862,6 +2901,7 @@ valid_nth_kday_sub(int argc, VALUE *argv, VALUE klass, int need_jd)
2862
2901
  }
2863
2902
  }
2864
2903
 
2904
+ /* :nodoc: */
2865
2905
  static VALUE
2866
2906
  date_s__valid_nth_kday_p(int argc, VALUE *argv, VALUE klass)
2867
2907
  {
@@ -2882,6 +2922,7 @@ date_s__valid_nth_kday_p(int argc, VALUE *argv, VALUE klass)
2882
2922
  return valid_nth_kday_sub(5, argv2, klass, 1);
2883
2923
  }
2884
2924
 
2925
+ /* :nodoc: */
2885
2926
  static VALUE
2886
2927
  date_s_valid_nth_kday_p(int argc, VALUE *argv, VALUE klass)
2887
2928
  {
@@ -2904,6 +2945,7 @@ date_s_valid_nth_kday_p(int argc, VALUE *argv, VALUE klass)
2904
2945
  return Qtrue;
2905
2946
  }
2906
2947
 
2948
+ /* :nodoc: */
2907
2949
  static VALUE
2908
2950
  date_s_zone_to_diff(VALUE klass, VALUE str)
2909
2951
  {
@@ -2913,13 +2955,15 @@ date_s_zone_to_diff(VALUE klass, VALUE str)
2913
2955
 
2914
2956
  /*
2915
2957
  * call-seq:
2916
- * Date.julian_leap?(year) -> bool
2958
+ * Date.julian_leap?(year) -> true or false
2959
+ *
2960
+ * Returns +true+ if the given year is a leap year
2961
+ * in the {proleptic Julian calendar}[https://en.wikipedia.org/wiki/Proleptic_Julian_calendar], +false+ otherwise:
2917
2962
  *
2918
- * Returns true if the given year is a leap year of the proleptic
2919
- * Julian calendar.
2963
+ * Date.julian_leap?(1900) # => true
2964
+ * Date.julian_leap?(1901) # => false
2920
2965
  *
2921
- * Date.julian_leap?(1900) #=> true
2922
- * Date.julian_leap?(1901) #=> false
2966
+ * Related: Date.gregorian_leap?.
2923
2967
  */
2924
2968
  static VALUE
2925
2969
  date_s_julian_leap_p(VALUE klass, VALUE y)
@@ -2934,14 +2978,17 @@ date_s_julian_leap_p(VALUE klass, VALUE y)
2934
2978
 
2935
2979
  /*
2936
2980
  * call-seq:
2937
- * Date.gregorian_leap?(year) -> bool
2938
- * Date.leap?(year) -> bool
2981
+ * Date.gregorian_leap?(year) -> true or false
2939
2982
  *
2940
- * Returns true if the given year is a leap year of the proleptic
2941
- * Gregorian calendar.
2983
+ * Returns +true+ if the given year is a leap year
2984
+ * in the {proleptic Gregorian calendar}[https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar], +false+ otherwise:
2942
2985
  *
2943
- * Date.gregorian_leap?(1900) #=> false
2944
- * Date.gregorian_leap?(2000) #=> true
2986
+ * Date.gregorian_leap?(2000) # => true
2987
+ * Date.gregorian_leap?(2001) # => false
2988
+ *
2989
+ * Date.leap? is an alias for Date.gregorian_leap?.
2990
+ *
2991
+ * Related: Date.julian_leap?.
2945
2992
  */
2946
2993
  static VALUE
2947
2994
  date_s_gregorian_leap_p(VALUE klass, VALUE y)
@@ -3094,6 +3141,7 @@ old_to_new(VALUE ajd, VALUE of, VALUE sg,
3094
3141
  }
3095
3142
 
3096
3143
  #ifndef NDEBUG
3144
+ /* :nodoc: */
3097
3145
  static VALUE
3098
3146
  date_s_new_bang(int argc, VALUE *argv, VALUE klass)
3099
3147
  {
@@ -3281,16 +3329,29 @@ static VALUE d_lite_plus(VALUE, VALUE);
3281
3329
 
3282
3330
  /*
3283
3331
  * call-seq:
3284
- * Date.jd([jd=0[, start=Date::ITALY]]) -> date
3332
+ * Date.jd(jd = 0, start = Date::ITALY) -> date
3285
3333
  *
3286
- * Creates a date object denoting the given chronological Julian day
3287
- * number.
3334
+ * Returns a new \Date object formed from the arguments:
3288
3335
  *
3289
- * Date.jd(2451944) #=> #<Date: 2001-02-03 ...>
3290
- * Date.jd(2451945) #=> #<Date: 2001-02-04 ...>
3291
- * Date.jd(0) #=> #<Date: -4712-01-01 ...>
3336
+ * Date.jd(2451944).to_s # => "2001-02-03"
3337
+ * Date.jd(2451945).to_s # => "2001-02-04"
3338
+ * Date.jd(0).to_s # => "-4712-01-01"
3292
3339
  *
3293
- * See also ::new.
3340
+ * The returned date is:
3341
+ *
3342
+ * - Gregorian, if the argument is greater than or equal to +start+:
3343
+ *
3344
+ * Date::ITALY # => 2299161
3345
+ * Date.jd(Date::ITALY).gregorian? # => true
3346
+ * Date.jd(Date::ITALY + 1).gregorian? # => true
3347
+ *
3348
+ * - Julian, otherwise
3349
+ *
3350
+ * Date.jd(Date::ITALY - 1).julian? # => true
3351
+ *
3352
+ * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
3353
+ *
3354
+ * Related: Date.new.
3294
3355
  */
3295
3356
  static VALUE
3296
3357
  date_s_jd(int argc, VALUE *argv, VALUE klass)
@@ -3329,19 +3390,33 @@ date_s_jd(int argc, VALUE *argv, VALUE klass)
3329
3390
 
3330
3391
  /*
3331
3392
  * call-seq:
3332
- * Date.ordinal([year=-4712[, yday=1[, start=Date::ITALY]]]) -> date
3393
+ * Date.ordinal(year = -4712, yday = 1, start = Date::ITALY) -> date
3394
+ *
3395
+ * Returns a new \Date object formed fom the arguments.
3396
+ *
3397
+ * With no arguments, returns the date for January 1, -4712:
3398
+ *
3399
+ * Date.ordinal.to_s # => "-4712-01-01"
3400
+ *
3401
+ * With argument +year+, returns the date for January 1 of that year:
3402
+ *
3403
+ * Date.ordinal(2001).to_s # => "2001-01-01"
3404
+ * Date.ordinal(-2001).to_s # => "-2001-01-01"
3405
+ *
3406
+ * With positive argument +yday+ == +n+,
3407
+ * returns the date for the +nth+ day of the given year:
3333
3408
  *
3334
- * Creates a date object denoting the given ordinal date.
3409
+ * Date.ordinal(2001, 14).to_s # => "2001-01-14"
3335
3410
  *
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.
3411
+ * With negative argument +yday+, counts backward from the end of the year:
3339
3412
  *
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 ...>
3413
+ * Date.ordinal(2001, -14).to_s # => "2001-12-18"
3343
3414
  *
3344
- * See also ::jd and ::new.
3415
+ * Raises an exception if +yday+ is zero or out of range.
3416
+ *
3417
+ * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
3418
+ *
3419
+ * Related: Date.jd, Date.new.
3345
3420
  */
3346
3421
  static VALUE
3347
3422
  date_s_ordinal(int argc, VALUE *argv, VALUE klass)
@@ -3389,29 +3464,7 @@ date_s_ordinal(int argc, VALUE *argv, VALUE klass)
3389
3464
  }
3390
3465
 
3391
3466
  /*
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.
3467
+ * Same as Date.new.
3415
3468
  */
3416
3469
  static VALUE
3417
3470
  date_s_civil(int argc, VALUE *argv, VALUE klass)
@@ -3419,6 +3472,31 @@ date_s_civil(int argc, VALUE *argv, VALUE klass)
3419
3472
  return date_initialize(argc, argv, d_lite_s_alloc_simple(klass));
3420
3473
  }
3421
3474
 
3475
+ /*
3476
+ * call-seq:
3477
+ * Date.new(year = -4712, month = 1, mday = 1, start = Date::ITALY) -> date
3478
+ *
3479
+ * Returns a new \Date object constructed from the given arguments:
3480
+ *
3481
+ * Date.new(2022).to_s # => "2022-01-01"
3482
+ * Date.new(2022, 2).to_s # => "2022-02-01"
3483
+ * Date.new(2022, 2, 4).to_s # => "2022-02-04"
3484
+ *
3485
+ * Argument +month+ should be in range (1..12) or range (-12..-1);
3486
+ * when the argument is negative, counts backward from the end of the year:
3487
+ *
3488
+ * Date.new(2022, -11, 4).to_s # => "2022-02-04"
3489
+ *
3490
+ * Argument +mday+ should be in range (1..n) or range (-n..-1)
3491
+ * where +n+ is the number of days in the month;
3492
+ * when the argument is negative, counts backward from the end of the month.
3493
+ *
3494
+ * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
3495
+ *
3496
+ * Date.civil is an alias for Date.new.
3497
+ *
3498
+ * Related: Date.jd.
3499
+ */
3422
3500
  static VALUE
3423
3501
  date_initialize(int argc, VALUE *argv, VALUE self)
3424
3502
  {
@@ -3483,19 +3561,47 @@ date_initialize(int argc, VALUE *argv, VALUE self)
3483
3561
 
3484
3562
  /*
3485
3563
  * call-seq:
3486
- * Date.commercial([cwyear=-4712[, cweek=1[, cwday=1[, start=Date::ITALY]]]]) -> date
3564
+ * Date.commercial(cwyear = -4712, cweek = 1, cwday = 1, start = Date::ITALY) -> date
3565
+ *
3566
+ * Returns a new \Date object constructed from the arguments.
3567
+ *
3568
+ * Argument +cwyear+ gives the year, and should be an integer.
3569
+ *
3570
+ * Argument +cweek+ gives the index of the week within the year,
3571
+ * and should be in range (1..53) or (-53..-1);
3572
+ * in some years, 53 or -53 will be out-of-range;
3573
+ * if negative, counts backward from the end of the year:
3574
+ *
3575
+ * Date.commercial(2022, 1, 1).to_s # => "2022-01-03"
3576
+ * Date.commercial(2022, 52, 1).to_s # => "2022-12-26"
3577
+ *
3578
+ * Argument +cwday+ gives the indes of the weekday within the week,
3579
+ * and should be in range (1..7) or (-7..-1);
3580
+ * 1 or -7 is Monday;
3581
+ * if negative, counts backward from the end of the week:
3487
3582
  *
3488
- * Creates a date object denoting the given week date.
3583
+ * Date.commercial(2022, 1, 1).to_s # => "2022-01-03"
3584
+ * Date.commercial(2022, 1, -7).to_s # => "2022-01-03"
3489
3585
  *
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.
3586
+ * When +cweek+ is 1:
3493
3587
  *
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 ...>
3588
+ * - If January 1 is a Friday, Saturday, or Sunday,
3589
+ * the first week begins in the week after:
3497
3590
  *
3498
- * See also ::jd and ::new.
3591
+ * Date::ABBR_DAYNAMES[Date.new(2023, 1, 1).wday] # => "Sun"
3592
+ * Date.commercial(2023, 1, 1).to_s # => "2023-01-02"
3593
+ Date.commercial(2023, 1, 7).to_s # => "2023-01-08"
3594
+ *
3595
+ * - Otherwise, the first week is the week of January 1,
3596
+ * which may mean some of the days fall on the year before:
3597
+ *
3598
+ * Date::ABBR_DAYNAMES[Date.new(2020, 1, 1).wday] # => "Wed"
3599
+ * Date.commercial(2020, 1, 1).to_s # => "2019-12-30"
3600
+ Date.commercial(2020, 1, 7).to_s # => "2020-01-05"
3601
+ *
3602
+ * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
3603
+ *
3604
+ * Related: Date.jd, Date.new, Date.ordinal.
3499
3605
  */
3500
3606
  static VALUE
3501
3607
  date_s_commercial(int argc, VALUE *argv, VALUE klass)
@@ -3547,6 +3653,7 @@ date_s_commercial(int argc, VALUE *argv, VALUE klass)
3547
3653
  }
3548
3654
 
3549
3655
  #ifndef NDEBUG
3656
+ /* :nodoc: */
3550
3657
  static VALUE
3551
3658
  date_s_weeknum(int argc, VALUE *argv, VALUE klass)
3552
3659
  {
@@ -3596,6 +3703,7 @@ date_s_weeknum(int argc, VALUE *argv, VALUE klass)
3596
3703
  return ret;
3597
3704
  }
3598
3705
 
3706
+ /* :nodoc: */
3599
3707
  static VALUE
3600
3708
  date_s_nth_kday(int argc, VALUE *argv, VALUE klass)
3601
3709
  {
@@ -3670,11 +3778,14 @@ static void set_sg(union DateData *, double);
3670
3778
 
3671
3779
  /*
3672
3780
  * call-seq:
3673
- * Date.today([start=Date::ITALY]) -> date
3781
+ * Date.today(start = Date::ITALY) -> date
3674
3782
  *
3675
- * Creates a date object denoting the present day.
3783
+ * Returns a new \Date object constructed from the present date:
3784
+ *
3785
+ * Date.today.to_s # => "2022-07-06"
3786
+ *
3787
+ * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
3676
3788
  *
3677
- * Date.today #=> #<Date: 2011-06-11 ...>
3678
3789
  */
3679
3790
  static VALUE
3680
3791
  date_s_today(int argc, VALUE *argv, VALUE klass)
@@ -4265,16 +4376,20 @@ date_s__strptime_internal(int argc, VALUE *argv, VALUE klass,
4265
4376
 
4266
4377
  /*
4267
4378
  * call-seq:
4268
- * Date._strptime(string[, format='%F']) -> hash
4379
+ * Date._strptime(string, format = '%F') -> hash
4269
4380
  *
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.
4381
+ * Returns a hash of values parsed from +string+
4382
+ * according to the given +format+:
4273
4383
  *
4274
- * Date._strptime('2001-02-03', '%Y-%m-%d')
4275
- * #=> {:year=>2001, :mon=>2, :mday=>3}
4384
+ * Date._strptime('2001-02-03', '%Y-%m-%d') # => {:year=>2001, :mon=>2, :mday=>3}
4276
4385
  *
4277
- * See also strptime(3) and #strftime.
4386
+ * For other formats, see
4387
+ * {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html].
4388
+ * (Unlike Date.strftime, does not support flags and width.)
4389
+ *
4390
+ * See also {strptime(3)}[https://man7.org/linux/man-pages/man3/strptime.3.html].
4391
+ *
4392
+ * Related: Date.strptime (returns a \Date object).
4278
4393
  */
4279
4394
  static VALUE
4280
4395
  date_s__strptime(int argc, VALUE *argv, VALUE klass)
@@ -4284,21 +4399,28 @@ date_s__strptime(int argc, VALUE *argv, VALUE klass)
4284
4399
 
4285
4400
  /*
4286
4401
  * call-seq:
4287
- * Date.strptime([string='-4712-01-01'[, format='%F'[, start=Date::ITALY]]]) -> date
4402
+ * Date.strptime(string = '-4712-01-01', format = '%F', start = Date::ITALY) -> date
4288
4403
  *
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.
4404
+ * Returns a new \Date object with values parsed from +string+,
4405
+ * according to the given +format+:
4292
4406
  *
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 ...>
4407
+ * Date.strptime('2001-02-03', '%Y-%m-%d') # => #<Date: 2001-02-03>
4408
+ * Date.strptime('03-02-2001', '%d-%m-%Y') # => #<Date: 2001-02-03>
4409
+ * Date.strptime('2001-034', '%Y-%j') # => #<Date: 2001-02-03>
4410
+ * Date.strptime('2001-W05-6', '%G-W%V-%u') # => #<Date: 2001-02-03>
4411
+ * Date.strptime('2001 04 6', '%Y %U %w') # => #<Date: 2001-02-03>
4412
+ * Date.strptime('2001 05 6', '%Y %W %u') # => #<Date: 2001-02-03>
4413
+ * Date.strptime('sat3feb01', '%a%d%b%y') # => #<Date: 2001-02-03>
4300
4414
  *
4301
- * See also strptime(3) and #strftime.
4415
+ * For other formats, see
4416
+ * {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html].
4417
+ * (Unlike Date.strftime, does not support flags and width.)
4418
+ *
4419
+ * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
4420
+ *
4421
+ * See also {strptime(3)}[https://man7.org/linux/man-pages/man3/strptime.3.html].
4422
+ *
4423
+ * Related: Date._strptime (returns a hash).
4302
4424
  */
4303
4425
  static VALUE
4304
4426
  date_s_strptime(int argc, VALUE *argv, VALUE klass)
@@ -4328,12 +4450,49 @@ date_s_strptime(int argc, VALUE *argv, VALUE klass)
4328
4450
 
4329
4451
  VALUE date__parse(VALUE str, VALUE comp);
4330
4452
 
4453
+ static size_t
4454
+ get_limit(VALUE opt)
4455
+ {
4456
+ if (!NIL_P(opt)) {
4457
+ VALUE limit = rb_hash_aref(opt, ID2SYM(rb_intern("limit")));
4458
+ if (NIL_P(limit)) return SIZE_MAX;
4459
+ return NUM2SIZET(limit);
4460
+ }
4461
+ return 128;
4462
+ }
4463
+
4464
+ #ifndef HAVE_RB_CATEGORY_WARN
4465
+ #define rb_category_warn(category, fmt) rb_warn(fmt)
4466
+ #endif
4467
+
4468
+ static void
4469
+ check_limit(VALUE str, VALUE opt)
4470
+ {
4471
+ size_t slen, limit;
4472
+ if (NIL_P(str)) return;
4473
+ if (SYMBOL_P(str)) {
4474
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED,
4475
+ "The ability to parse Symbol is an unintentional bug and is deprecated");
4476
+ str = rb_sym2str(str);
4477
+ }
4478
+
4479
+ StringValue(str);
4480
+ slen = RSTRING_LEN(str);
4481
+ limit = get_limit(opt);
4482
+ if (slen > limit) {
4483
+ rb_raise(rb_eArgError,
4484
+ "string length (%"PRI_SIZE_PREFIX"u) exceeds the limit %"PRI_SIZE_PREFIX"u", slen, limit);
4485
+ }
4486
+ }
4487
+
4331
4488
  static VALUE
4332
4489
  date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
4333
4490
  {
4334
- VALUE vstr, vcomp, hash;
4491
+ VALUE vstr, vcomp, hash, opt;
4335
4492
 
4336
- rb_scan_args(argc, argv, "11", &vstr, &vcomp);
4493
+ rb_scan_args(argc, argv, "11:", &vstr, &vcomp, &opt);
4494
+ if (!NIL_P(opt)) argc--;
4495
+ check_limit(vstr, opt);
4337
4496
  StringValue(vstr);
4338
4497
  if (!rb_enc_str_asciicompat_p(vstr))
4339
4498
  rb_raise(rb_eArgError,
@@ -4348,21 +4507,32 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
4348
4507
 
4349
4508
  /*
4350
4509
  * call-seq:
4351
- * Date._parse(string[, comp=true]) -> hash
4510
+ * Date._parse(string, comp = true, limit: 128) -> hash
4352
4511
  *
4353
- * Parses the given representation of date and time, and returns a
4354
- * hash of parsed elements.
4512
+ * <b>Note</b>:
4513
+ * This method recognizes many forms in +string+,
4514
+ * but it is not a validator.
4515
+ * For formats, see
4516
+ * {"Specialized Format Strings" in Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Specialized+Format+Strings]
4355
4517
  *
4356
- * This method *does not* function as a validator. If the input
4357
- * string does not match valid formats strictly, you may get a cryptic
4358
- * result. Should consider to use `Date._strptime` or
4359
- * `DateTime._strptime` instead of this method as possible.
4518
+ * If +string+ does not specify a valid date,
4519
+ * the result is unpredictable;
4520
+ * consider using Date._strptime instead.
4360
4521
  *
4361
- * If the optional second argument is true and the detected year is in
4362
- * the range "00" to "99", considers the year a 2-digit form and makes
4363
- * it full.
4522
+ * Returns a hash of values parsed from +string+:
4523
+ *
4524
+ * Date._parse('2001-02-03') # => {:year=>2001, :mon=>2, :mday=>3}
4525
+ *
4526
+ * If +comp+ is +true+ and the given year is in the range <tt>(0..99)</tt>,
4527
+ * the current century is supplied;
4528
+ * otherwise, the year is taken as given:
4529
+ *
4530
+ * Date._parse('01-02-03', true) # => {:year=>2001, :mon=>2, :mday=>3}
4531
+ * Date._parse('01-02-03', false) # => {:year=>1, :mon=>2, :mday=>3}
4532
+ *
4533
+ * See argument {limit}[rdoc-ref:Date@Argument+limit].
4364
4534
  *
4365
- * Date._parse('2001-02-03') #=> {:year=>2001, :mon=>2, :mday=>3}
4535
+ * Related: Date.parse(returns a \Date object).
4366
4536
  */
4367
4537
  static VALUE
4368
4538
  date_s__parse(int argc, VALUE *argv, VALUE klass)
@@ -4372,30 +4542,44 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
4372
4542
 
4373
4543
  /*
4374
4544
  * call-seq:
4375
- * Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]]) -> date
4545
+ * Date.parse(string = '-4712-01-01', comp = true, start = Date::ITALY, limit: 128) -> date
4376
4546
  *
4377
- * Parses the given representation of date and time, and creates a
4378
- * date object.
4547
+ * <b>Note</b>:
4548
+ * This method recognizes many forms in +string+,
4549
+ * but it is not a validator.
4550
+ * For formats, see
4551
+ * {"Specialized Format Strings" in Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Specialized+Format+Strings]
4552
+ * If +string+ does not specify a valid date,
4553
+ * the result is unpredictable;
4554
+ * consider using Date._strptime instead.
4379
4555
  *
4380
- * This method *does not* function as a validator. If the input
4381
- * string does not match valid formats strictly, you may get a cryptic
4382
- * result. Should consider to use `Date.strptime` instead of this
4383
- * method as possible.
4556
+ * Returns a new \Date object with values parsed from +string+:
4384
4557
  *
4385
- * If the optional second argument is true and the detected year is in
4386
- * the range "00" to "99", considers the year a 2-digit form and makes
4387
- * it full.
4558
+ * Date.parse('2001-02-03') # => #<Date: 2001-02-03>
4559
+ * Date.parse('20010203') # => #<Date: 2001-02-03>
4560
+ * Date.parse('3rd Feb 2001') # => #<Date: 2001-02-03>
4561
+ *
4562
+ * If +comp+ is +true+ and the given year is in the range <tt>(0..99)</tt>,
4563
+ * the current century is supplied;
4564
+ * otherwise, the year is taken as given:
4565
+ *
4566
+ * Date.parse('01-02-03', true) # => #<Date: 2001-02-03>
4567
+ * Date.parse('01-02-03', false) # => #<Date: 0001-02-03>
4388
4568
  *
4389
- * Date.parse('2001-02-03') #=> #<Date: 2001-02-03 ...>
4390
- * Date.parse('20010203') #=> #<Date: 2001-02-03 ...>
4391
- * Date.parse('3rd Feb 2001') #=> #<Date: 2001-02-03 ...>
4569
+ * See:
4570
+ *
4571
+ * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
4572
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
4573
+ *
4574
+ * Related: Date._parse (returns a hash).
4392
4575
  */
4393
4576
  static VALUE
4394
4577
  date_s_parse(int argc, VALUE *argv, VALUE klass)
4395
4578
  {
4396
- VALUE str, comp, sg;
4579
+ VALUE str, comp, sg, opt;
4397
4580
 
4398
- rb_scan_args(argc, argv, "03", &str, &comp, &sg);
4581
+ rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
4582
+ if (!NIL_P(opt)) argc--;
4399
4583
 
4400
4584
  switch (argc) {
4401
4585
  case 0:
@@ -4407,11 +4591,12 @@ date_s_parse(int argc, VALUE *argv, VALUE klass)
4407
4591
  }
4408
4592
 
4409
4593
  {
4410
- VALUE argv2[2], hash;
4411
-
4412
- argv2[0] = str;
4413
- argv2[1] = comp;
4414
- hash = date_s__parse(2, argv2, klass);
4594
+ int argc2 = 2;
4595
+ VALUE argv2[3], hash;
4596
+ argv2[0] = str;
4597
+ argv2[1] = comp;
4598
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
4599
+ hash = date_s__parse(argc2, argv2, klass);
4415
4600
  return d_new_by_frags(klass, hash, sg);
4416
4601
  }
4417
4602
  }
@@ -4425,33 +4610,56 @@ VALUE date__jisx0301(VALUE);
4425
4610
 
4426
4611
  /*
4427
4612
  * call-seq:
4428
- * Date._iso8601(string) -> hash
4613
+ * Date._iso8601(string, limit: 128) -> hash
4614
+ *
4615
+ * Returns a hash of values parsed from +string+, which should contain
4616
+ * an {ISO 8601 formatted date}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-ISO+8601+Format+Specifications]:
4429
4617
  *
4430
- * Returns a hash of parsed elements.
4618
+ * d = Date.new(2001, 2, 3)
4619
+ * s = d.iso8601 # => "2001-02-03"
4620
+ * Date._iso8601(s) # => {:mday=>3, :year=>2001, :mon=>2}
4621
+ *
4622
+ * See argument {limit}[rdoc-ref:Date@Argument+limit].
4623
+ *
4624
+ * Related: Date.iso8601 (returns a \Date object).
4431
4625
  */
4432
4626
  static VALUE
4433
- date_s__iso8601(VALUE klass, VALUE str)
4627
+ date_s__iso8601(int argc, VALUE *argv, VALUE klass)
4434
4628
  {
4629
+ VALUE str, opt;
4630
+
4631
+ rb_scan_args(argc, argv, "1:", &str, &opt);
4632
+ check_limit(str, opt);
4633
+
4435
4634
  return date__iso8601(str);
4436
4635
  }
4437
4636
 
4438
4637
  /*
4439
4638
  * call-seq:
4440
- * Date.iso8601(string='-4712-01-01'[, start=Date::ITALY]) -> date
4639
+ * Date.iso8601(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date
4441
4640
  *
4442
- * Creates a new Date object by parsing from a string according to
4443
- * some typical ISO 8601 formats.
4641
+ * Returns a new \Date object with values parsed from +string+,
4642
+ * which should contain
4643
+ * an {ISO 8601 formatted date}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-ISO+8601+Format+Specifications]:
4644
+ *
4645
+ * d = Date.new(2001, 2, 3)
4646
+ * s = d.iso8601 # => "2001-02-03"
4647
+ * Date.iso8601(s) # => #<Date: 2001-02-03>
4444
4648
  *
4445
- * Date.iso8601('2001-02-03') #=> #<Date: 2001-02-03 ...>
4446
- * Date.iso8601('20010203') #=> #<Date: 2001-02-03 ...>
4447
- * Date.iso8601('2001-W05-6') #=> #<Date: 2001-02-03 ...>
4649
+ * See:
4650
+ *
4651
+ * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
4652
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
4653
+ *
4654
+ * Related: Date._iso8601 (returns a hash).
4448
4655
  */
4449
4656
  static VALUE
4450
4657
  date_s_iso8601(int argc, VALUE *argv, VALUE klass)
4451
4658
  {
4452
- VALUE str, sg;
4659
+ VALUE str, sg, opt;
4453
4660
 
4454
- rb_scan_args(argc, argv, "02", &str, &sg);
4661
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4662
+ if (!NIL_P(opt)) argc--;
4455
4663
 
4456
4664
  switch (argc) {
4457
4665
  case 0:
@@ -4461,38 +4669,68 @@ date_s_iso8601(int argc, VALUE *argv, VALUE klass)
4461
4669
  }
4462
4670
 
4463
4671
  {
4464
- VALUE hash = date_s__iso8601(klass, str);
4672
+ int argc2 = 1;
4673
+ VALUE argv2[2], hash;
4674
+ argv2[0] = str;
4675
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
4676
+ hash = date_s__iso8601(argc2, argv2, klass);
4465
4677
  return d_new_by_frags(klass, hash, sg);
4466
4678
  }
4467
4679
  }
4468
4680
 
4469
4681
  /*
4470
4682
  * call-seq:
4471
- * Date._rfc3339(string) -> hash
4683
+ * Date._rfc3339(string, limit: 128) -> hash
4684
+ *
4685
+ * Returns a hash of values parsed from +string+, which should be a valid
4686
+ * {RFC 3339 format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-RFC+3339+Format]:
4472
4687
  *
4473
- * Returns a hash of parsed elements.
4688
+ * d = Date.new(2001, 2, 3)
4689
+ * s = d.rfc3339 # => "2001-02-03T00:00:00+00:00"
4690
+ * Date._rfc3339(s)
4691
+ * # => {:year=>2001, :mon=>2, :mday=>3, :hour=>0, :min=>0, :sec=>0, :zone=>"+00:00", :offset=>0}
4692
+ *
4693
+ * See argument {limit}[rdoc-ref:Date@Argument+limit].
4694
+ *
4695
+ * Related: Date.rfc3339 (returns a \Date object).
4474
4696
  */
4475
4697
  static VALUE
4476
- date_s__rfc3339(VALUE klass, VALUE str)
4698
+ date_s__rfc3339(int argc, VALUE *argv, VALUE klass)
4477
4699
  {
4700
+ VALUE str, opt;
4701
+
4702
+ rb_scan_args(argc, argv, "1:", &str, &opt);
4703
+ check_limit(str, opt);
4704
+
4478
4705
  return date__rfc3339(str);
4479
4706
  }
4480
4707
 
4481
4708
  /*
4482
4709
  * call-seq:
4483
- * Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> date
4710
+ * Date.rfc3339(string = '-4712-01-01T00:00:00+00:00', start = Date::ITALY, limit: 128) -> date
4484
4711
  *
4485
- * Creates a new Date object by parsing from a string according to
4486
- * some typical RFC 3339 formats.
4712
+ * Returns a new \Date object with values parsed from +string+,
4713
+ * which should be a valid
4714
+ * {RFC 3339 format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-RFC+3339+Format]:
4715
+ *
4716
+ * d = Date.new(2001, 2, 3)
4717
+ * s = d.rfc3339 # => "2001-02-03T00:00:00+00:00"
4718
+ * Date.rfc3339(s) # => #<Date: 2001-02-03>
4719
+ *
4720
+ * See:
4721
+ *
4722
+ * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
4723
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
4487
4724
  *
4488
- * Date.rfc3339('2001-02-03T04:05:06+07:00') #=> #<Date: 2001-02-03 ...>
4725
+ * Related: Date._rfc3339 (returns a hash).
4489
4726
  */
4490
4727
  static VALUE
4491
4728
  date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
4492
4729
  {
4493
- VALUE str, sg;
4730
+ VALUE str, sg, opt;
4494
4731
 
4495
- rb_scan_args(argc, argv, "02", &str, &sg);
4732
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4733
+ if (!NIL_P(opt)) argc--;
4496
4734
 
4497
4735
  switch (argc) {
4498
4736
  case 0:
@@ -4502,38 +4740,66 @@ date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
4502
4740
  }
4503
4741
 
4504
4742
  {
4505
- VALUE hash = date_s__rfc3339(klass, str);
4743
+ int argc2 = 1;
4744
+ VALUE argv2[2], hash;
4745
+ argv2[0] = str;
4746
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
4747
+ hash = date_s__rfc3339(argc2, argv2, klass);
4506
4748
  return d_new_by_frags(klass, hash, sg);
4507
4749
  }
4508
4750
  }
4509
4751
 
4510
4752
  /*
4511
4753
  * call-seq:
4512
- * Date._xmlschema(string) -> hash
4754
+ * Date._xmlschema(string, limit: 128) -> hash
4513
4755
  *
4514
- * Returns a hash of parsed elements.
4756
+ * Returns a hash of values parsed from +string+, which should be a valid
4757
+ * XML date format:
4758
+ *
4759
+ * d = Date.new(2001, 2, 3)
4760
+ * s = d.xmlschema # => "2001-02-03"
4761
+ * Date._xmlschema(s) # => {:year=>2001, :mon=>2, :mday=>3}
4762
+ *
4763
+ * See argument {limit}[rdoc-ref:Date@Argument+limit].
4764
+ *
4765
+ * Related: Date.xmlschema (returns a \Date object).
4515
4766
  */
4516
4767
  static VALUE
4517
- date_s__xmlschema(VALUE klass, VALUE str)
4768
+ date_s__xmlschema(int argc, VALUE *argv, VALUE klass)
4518
4769
  {
4770
+ VALUE str, opt;
4771
+
4772
+ rb_scan_args(argc, argv, "1:", &str, &opt);
4773
+ check_limit(str, opt);
4774
+
4519
4775
  return date__xmlschema(str);
4520
4776
  }
4521
4777
 
4522
4778
  /*
4523
4779
  * call-seq:
4524
- * Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY]) -> date
4780
+ * Date.xmlschema(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date
4525
4781
  *
4526
- * Creates a new Date object by parsing from a string according to
4527
- * some typical XML Schema formats.
4782
+ * Returns a new \Date object with values parsed from +string+,
4783
+ * which should be a valid XML date format:
4528
4784
  *
4529
- * Date.xmlschema('2001-02-03') #=> #<Date: 2001-02-03 ...>
4785
+ * d = Date.new(2001, 2, 3)
4786
+ * s = d.xmlschema # => "2001-02-03"
4787
+ * Date.xmlschema(s) # => #<Date: 2001-02-03>
4788
+ *
4789
+ * See:
4790
+ *
4791
+ * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
4792
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
4793
+ *
4794
+ * Related: Date._xmlschema (returns a hash).
4530
4795
  */
4531
4796
  static VALUE
4532
4797
  date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
4533
4798
  {
4534
- VALUE str, sg;
4799
+ VALUE str, sg, opt;
4535
4800
 
4536
- rb_scan_args(argc, argv, "02", &str, &sg);
4801
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4802
+ if (!NIL_P(opt)) argc--;
4537
4803
 
4538
4804
  switch (argc) {
4539
4805
  case 0:
@@ -4543,41 +4809,71 @@ date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
4543
4809
  }
4544
4810
 
4545
4811
  {
4546
- VALUE hash = date_s__xmlschema(klass, str);
4812
+ int argc2 = 1;
4813
+ VALUE argv2[2], hash;
4814
+ argv2[0] = str;
4815
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
4816
+ hash = date_s__xmlschema(argc2, argv2, klass);
4547
4817
  return d_new_by_frags(klass, hash, sg);
4548
4818
  }
4549
4819
  }
4550
4820
 
4551
4821
  /*
4552
4822
  * call-seq:
4553
- * Date._rfc2822(string) -> hash
4554
- * Date._rfc822(string) -> hash
4823
+ * Date._rfc2822(string, limit: 128) -> hash
4824
+ *
4825
+ * Returns a hash of values parsed from +string+, which should be a valid
4826
+ * {RFC 2822 date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-RFC+2822+Format]:
4827
+ *
4828
+ * d = Date.new(2001, 2, 3)
4829
+ * s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000"
4830
+ * Date._rfc2822(s)
4831
+ * # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"+0000", :offset=>0}
4832
+ *
4833
+ * See argument {limit}[rdoc-ref:Date@Argument+limit].
4555
4834
  *
4556
- * Returns a hash of parsed elements.
4835
+ * Date._rfc822 is an alias for Date._rfc2822.
4836
+ *
4837
+ * Related: Date.rfc2822 (returns a \Date object).
4557
4838
  */
4558
4839
  static VALUE
4559
- date_s__rfc2822(VALUE klass, VALUE str)
4840
+ date_s__rfc2822(int argc, VALUE *argv, VALUE klass)
4560
4841
  {
4842
+ VALUE str, opt;
4843
+
4844
+ rb_scan_args(argc, argv, "1:", &str, &opt);
4845
+ check_limit(str, opt);
4846
+
4561
4847
  return date__rfc2822(str);
4562
4848
  }
4563
4849
 
4564
4850
  /*
4565
4851
  * call-seq:
4566
- * Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> date
4567
- * Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> date
4852
+ * Date.rfc2822(string = 'Mon, 1 Jan -4712 00:00:00 +0000', start = Date::ITALY, limit: 128) -> date
4568
4853
  *
4569
- * Creates a new Date object by parsing from a string according to
4570
- * some typical RFC 2822 formats.
4854
+ * Returns a new \Date object with values parsed from +string+,
4855
+ * which should be a valid
4856
+ * {RFC 2822 date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-RFC+2822+Format]:
4857
+ *
4858
+ * d = Date.new(2001, 2, 3)
4859
+ * s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000"
4860
+ * Date.rfc2822(s) # => #<Date: 2001-02-03>
4861
+ *
4862
+ * See:
4571
4863
  *
4572
- * Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000')
4573
- * #=> #<Date: 2001-02-03 ...>
4864
+ * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
4865
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
4866
+ *
4867
+ * Date.rfc822 is an alias for Date.rfc2822.
4868
+ *
4869
+ * Related: Date._rfc2822 (returns a hash).
4574
4870
  */
4575
4871
  static VALUE
4576
4872
  date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
4577
4873
  {
4578
- VALUE str, sg;
4874
+ VALUE str, sg, opt;
4579
4875
 
4580
- rb_scan_args(argc, argv, "02", &str, &sg);
4876
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4581
4877
 
4582
4878
  switch (argc) {
4583
4879
  case 0:
@@ -4587,39 +4883,65 @@ date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
4587
4883
  }
4588
4884
 
4589
4885
  {
4590
- VALUE hash = date_s__rfc2822(klass, str);
4886
+ int argc2 = 1;
4887
+ VALUE argv2[2], hash;
4888
+ argv2[0] = str;
4889
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
4890
+ hash = date_s__rfc2822(argc2, argv2, klass);
4591
4891
  return d_new_by_frags(klass, hash, sg);
4592
4892
  }
4593
4893
  }
4594
4894
 
4595
4895
  /*
4596
4896
  * call-seq:
4597
- * Date._httpdate(string) -> hash
4897
+ * Date._httpdate(string, limit: 128) -> hash
4898
+ *
4899
+ * Returns a hash of values parsed from +string+, which should be a valid
4900
+ * {HTTP date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-HTTP+Format]:
4598
4901
  *
4599
- * Returns a hash of parsed elements.
4902
+ * d = Date.new(2001, 2, 3)
4903
+ * s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT"
4904
+ * Date._httpdate(s)
4905
+ * # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"GMT", :offset=>0}
4906
+ *
4907
+ * Related: Date.httpdate (returns a \Date object).
4600
4908
  */
4601
4909
  static VALUE
4602
- date_s__httpdate(VALUE klass, VALUE str)
4910
+ date_s__httpdate(int argc, VALUE *argv, VALUE klass)
4603
4911
  {
4912
+ VALUE str, opt;
4913
+
4914
+ rb_scan_args(argc, argv, "1:", &str, &opt);
4915
+ check_limit(str, opt);
4916
+
4604
4917
  return date__httpdate(str);
4605
4918
  }
4606
4919
 
4607
4920
  /*
4608
4921
  * call-seq:
4609
- * Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY]) -> date
4922
+ * Date.httpdate(string = 'Mon, 01 Jan -4712 00:00:00 GMT', start = Date::ITALY, limit: 128) -> date
4610
4923
  *
4611
- * Creates a new Date object by parsing from a string according to
4612
- * some RFC 2616 format.
4924
+ * Returns a new \Date object with values parsed from +string+,
4925
+ * which should be a valid
4926
+ * {HTTP date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-HTTP+Format]:
4927
+ *
4928
+ * d = Date.new(2001, 2, 3)
4929
+ s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT"
4930
+ Date.httpdate(s) # => #<Date: 2001-02-03>
4931
+ *
4932
+ * See:
4613
4933
  *
4614
- * Date.httpdate('Sat, 03 Feb 2001 00:00:00 GMT')
4615
- * #=> #<Date: 2001-02-03 ...>
4934
+ * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
4935
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
4936
+ *
4937
+ * Related: Date._httpdate (returns a hash).
4616
4938
  */
4617
4939
  static VALUE
4618
4940
  date_s_httpdate(int argc, VALUE *argv, VALUE klass)
4619
4941
  {
4620
- VALUE str, sg;
4942
+ VALUE str, sg, opt;
4621
4943
 
4622
- rb_scan_args(argc, argv, "02", &str, &sg);
4944
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
4623
4945
 
4624
4946
  switch (argc) {
4625
4947
  case 0:
@@ -4629,42 +4951,70 @@ date_s_httpdate(int argc, VALUE *argv, VALUE klass)
4629
4951
  }
4630
4952
 
4631
4953
  {
4632
- VALUE hash = date_s__httpdate(klass, str);
4954
+ int argc2 = 1;
4955
+ VALUE argv2[2], hash;
4956
+ argv2[0] = str;
4957
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
4958
+ hash = date_s__httpdate(argc2, argv2, klass);
4633
4959
  return d_new_by_frags(klass, hash, sg);
4634
4960
  }
4635
4961
  }
4636
4962
 
4637
4963
  /*
4638
4964
  * call-seq:
4639
- * Date._jisx0301(string) -> hash
4965
+ * Date._jisx0301(string, limit: 128) -> hash
4966
+ *
4967
+ * Returns a hash of values parsed from +string+, which should be a valid
4968
+ * {JIS X 0301 date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-JIS+X+0301+Format]:
4969
+ *
4970
+ * d = Date.new(2001, 2, 3)
4971
+ * s = d.jisx0301 # => "H13.02.03"
4972
+ * Date._jisx0301(s) # => {:year=>2001, :mon=>2, :mday=>3}
4640
4973
  *
4641
- * Returns a hash of parsed elements.
4974
+ * See argument {limit}[rdoc-ref:Date@Argument+limit].
4975
+ *
4976
+ * Related: Date.jisx0301 (returns a \Date object).
4642
4977
  */
4643
4978
  static VALUE
4644
- date_s__jisx0301(VALUE klass, VALUE str)
4979
+ date_s__jisx0301(int argc, VALUE *argv, VALUE klass)
4645
4980
  {
4981
+ VALUE str, opt;
4982
+
4983
+ rb_scan_args(argc, argv, "1:", &str, &opt);
4984
+ check_limit(str, opt);
4985
+
4646
4986
  return date__jisx0301(str);
4647
4987
  }
4648
4988
 
4649
4989
  /*
4650
4990
  * call-seq:
4651
- * Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY]) -> date
4991
+ * Date.jisx0301(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date
4652
4992
  *
4653
- * Creates a new Date object by parsing from a string according to
4654
- * some typical JIS X 0301 formats.
4993
+ * Returns a new \Date object with values parsed from +string+,
4994
+ * which should be a valid {JIS X 0301 format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-JIS+X+0301+Format]:
4655
4995
  *
4656
- * Date.jisx0301('H13.02.03') #=> #<Date: 2001-02-03 ...>
4996
+ * d = Date.new(2001, 2, 3)
4997
+ * s = d.jisx0301 # => "H13.02.03"
4998
+ * Date.jisx0301(s) # => #<Date: 2001-02-03>
4657
4999
  *
4658
5000
  * For no-era year, legacy format, Heisei is assumed.
4659
5001
  *
4660
- * Date.jisx0301('13.02.03') #=> #<Date: 2001-02-03 ...>
5002
+ * Date.jisx0301('13.02.03') # => #<Date: 2001-02-03>
5003
+ *
5004
+ * See:
5005
+ *
5006
+ * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
5007
+ * - Argument {limit}[rdoc-ref:Date@Argument+limit].
5008
+ *
5009
+ * Related: Date._jisx0301 (returns a hash).
4661
5010
  */
4662
5011
  static VALUE
4663
5012
  date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
4664
5013
  {
4665
- VALUE str, sg;
5014
+ VALUE str, sg, opt;
4666
5015
 
4667
- rb_scan_args(argc, argv, "02", &str, &sg);
5016
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
5017
+ if (!NIL_P(opt)) argc--;
4668
5018
 
4669
5019
  switch (argc) {
4670
5020
  case 0:
@@ -4674,7 +5024,11 @@ date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
4674
5024
  }
4675
5025
 
4676
5026
  {
4677
- VALUE hash = date_s__jisx0301(klass, str);
5027
+ int argc2 = 1;
5028
+ VALUE argv2[2], hash;
5029
+ argv2[0] = str;
5030
+ if (!NIL_P(opt)) argv2[argc2++] = opt;
5031
+ hash = date_s__jisx0301(argc2, argv2, klass);
4678
5032
  return d_new_by_frags(klass, hash, sg);
4679
5033
  }
4680
5034
  }
@@ -4844,6 +5198,7 @@ d_lite_initialize_copy(VALUE copy, VALUE date)
4844
5198
  }
4845
5199
 
4846
5200
  #ifndef NDEBUG
5201
+ /* :nodoc: */
4847
5202
  static VALUE
4848
5203
  d_lite_fill(VALUE self)
4849
5204
  {
@@ -4933,12 +5288,15 @@ d_lite_mjd(VALUE self)
4933
5288
 
4934
5289
  /*
4935
5290
  * call-seq:
4936
- * d.ld -> integer
5291
+ * ld -> integer
4937
5292
  *
4938
- * Returns the Lilian day number. This is a whole number, which is
4939
- * adjusted by the offset as the local time.
5293
+ * Returns the
5294
+ * {Lilian day number}[https://en.wikipedia.org/wiki/Lilian_date],
5295
+ * which is the number of days since the beginning of the Gregorian
5296
+ * calendar, October 15, 1582.
5297
+ *
5298
+ * Date.new(2001, 2, 3).ld # => 152784
4940
5299
  *
4941
- * Date.new(2001,2,3).ld #=> 152784
4942
5300
  */
4943
5301
  static VALUE
4944
5302
  d_lite_ld(VALUE self)
@@ -4949,12 +5307,13 @@ d_lite_ld(VALUE self)
4949
5307
 
4950
5308
  /*
4951
5309
  * call-seq:
4952
- * d.year -> integer
5310
+ * year -> integer
5311
+ *
5312
+ * Returns the year:
4953
5313
  *
4954
- * Returns the year.
5314
+ * Date.new(2001, 2, 3).year # => 2001
5315
+ * (Date.new(1, 1, 1) - 1).year # => 0
4955
5316
  *
4956
- * Date.new(2001,2,3).year #=> 2001
4957
- * (Date.new(1,1,1) - 1).year #=> 0
4958
5317
  */
4959
5318
  static VALUE
4960
5319
  d_lite_year(VALUE self)
@@ -4965,11 +5324,12 @@ d_lite_year(VALUE self)
4965
5324
 
4966
5325
  /*
4967
5326
  * call-seq:
4968
- * d.yday -> fixnum
5327
+ * yday -> integer
5328
+ *
5329
+ * Returns the day of the year, in range (1..366):
4969
5330
  *
4970
- * Returns the day of the year (1-366).
5331
+ * Date.new(2001, 2, 3).yday # => 34
4971
5332
  *
4972
- * Date.new(2001,2,3).yday #=> 34
4973
5333
  */
4974
5334
  static VALUE
4975
5335
  d_lite_yday(VALUE self)
@@ -4980,12 +5340,13 @@ d_lite_yday(VALUE self)
4980
5340
 
4981
5341
  /*
4982
5342
  * call-seq:
4983
- * d.mon -> fixnum
4984
- * d.month -> fixnum
5343
+ * mon -> integer
4985
5344
  *
4986
- * Returns the month (1-12).
5345
+ * Returns the month in range (1..12):
4987
5346
  *
4988
- * Date.new(2001,2,3).mon #=> 2
5347
+ * Date.new(2001, 2, 3).mon # => 2
5348
+ *
5349
+ * Date#month is an alias for Date#mon.
4989
5350
  */
4990
5351
  static VALUE
4991
5352
  d_lite_mon(VALUE self)
@@ -4996,12 +5357,13 @@ d_lite_mon(VALUE self)
4996
5357
 
4997
5358
  /*
4998
5359
  * call-seq:
4999
- * d.mday -> fixnum
5000
- * d.day -> fixnum
5360
+ * mday -> integer
5361
+ *
5362
+ * Returns the day of the month in range (1..31):
5001
5363
  *
5002
- * Returns the day of the month (1-31).
5364
+ * Date.new(2001, 2, 3).mday # => 3
5003
5365
  *
5004
- * Date.new(2001,2,3).mday #=> 3
5366
+ * Date#day is an alias for Date#mday.
5005
5367
  */
5006
5368
  static VALUE
5007
5369
  d_lite_mday(VALUE self)
@@ -5012,11 +5374,12 @@ d_lite_mday(VALUE self)
5012
5374
 
5013
5375
  /*
5014
5376
  * call-seq:
5015
- * d.day_fraction -> rational
5377
+ * day_fraction -> rational
5378
+ *
5379
+ * Returns the fractional part of the day in range (Rational(0, 1)...Rational(1, 1)):
5016
5380
  *
5017
- * Returns the fractional part of the day.
5381
+ * DateTime.new(2001,2,3,12).day_fraction # => (1/2)
5018
5382
  *
5019
- * DateTime.new(2001,2,3,12).day_fraction #=> (1/2)
5020
5383
  */
5021
5384
  static VALUE
5022
5385
  d_lite_day_fraction(VALUE self)
@@ -5029,12 +5392,14 @@ d_lite_day_fraction(VALUE self)
5029
5392
 
5030
5393
  /*
5031
5394
  * call-seq:
5032
- * d.cwyear -> integer
5395
+ * cwyear -> integer
5033
5396
  *
5034
- * Returns the calendar week based year.
5397
+ * Returns commercial-date year for +self+
5398
+ * (see Date.commercial):
5399
+ *
5400
+ * Date.new(2001, 2, 3).cwyear # => 2001
5401
+ * Date.new(2000, 1, 1).cwyear # => 1999
5035
5402
  *
5036
- * Date.new(2001,2,3).cwyear #=> 2001
5037
- * Date.new(2000,1,1).cwyear #=> 1999
5038
5403
  */
5039
5404
  static VALUE
5040
5405
  d_lite_cwyear(VALUE self)
@@ -5045,11 +5410,13 @@ d_lite_cwyear(VALUE self)
5045
5410
 
5046
5411
  /*
5047
5412
  * call-seq:
5048
- * d.cweek -> fixnum
5413
+ * cweek -> integer
5414
+ *
5415
+ * Returns commercial-date week index for +self+
5416
+ * (see Date.commercial):
5049
5417
  *
5050
- * Returns the calendar week number (1-53).
5418
+ * Date.new(2001, 2, 3).cweek # => 5
5051
5419
  *
5052
- * Date.new(2001,2,3).cweek #=> 5
5053
5420
  */
5054
5421
  static VALUE
5055
5422
  d_lite_cweek(VALUE self)
@@ -5060,11 +5427,14 @@ d_lite_cweek(VALUE self)
5060
5427
 
5061
5428
  /*
5062
5429
  * call-seq:
5063
- * d.cwday -> fixnum
5430
+ * cwday -> integer
5064
5431
  *
5065
- * Returns the day of calendar week (1-7, Monday is 1).
5432
+ * Returns the commercial-date weekday index for +self+
5433
+ * (see Date.commercial);
5434
+ * 1 is Monday:
5435
+ *
5436
+ * Date.new(2001, 2, 3).cwday # => 6
5066
5437
  *
5067
- * Date.new(2001,2,3).cwday #=> 6
5068
5438
  */
5069
5439
  static VALUE
5070
5440
  d_lite_cwday(VALUE self)
@@ -5074,6 +5444,7 @@ d_lite_cwday(VALUE self)
5074
5444
  }
5075
5445
 
5076
5446
  #ifndef NDEBUG
5447
+ /* :nodoc: */
5077
5448
  static VALUE
5078
5449
  d_lite_wnum0(VALUE self)
5079
5450
  {
@@ -5081,6 +5452,7 @@ d_lite_wnum0(VALUE self)
5081
5452
  return INT2FIX(m_wnum0(dat));
5082
5453
  }
5083
5454
 
5455
+ /* :nodoc: */
5084
5456
  static VALUE
5085
5457
  d_lite_wnum1(VALUE self)
5086
5458
  {
@@ -5091,11 +5463,12 @@ d_lite_wnum1(VALUE self)
5091
5463
 
5092
5464
  /*
5093
5465
  * call-seq:
5094
- * d.wday -> fixnum
5466
+ * wday -> integer
5095
5467
  *
5096
- * Returns the day of week (0-6, Sunday is zero).
5468
+ * Returns the day of week in range (0..6); Sunday is 0:
5469
+ *
5470
+ * Date.new(2001, 2, 3).wday # => 6
5097
5471
  *
5098
- * Date.new(2001,2,3).wday #=> 6
5099
5472
  */
5100
5473
  static VALUE
5101
5474
  d_lite_wday(VALUE self)
@@ -5106,9 +5479,9 @@ d_lite_wday(VALUE self)
5106
5479
 
5107
5480
  /*
5108
5481
  * call-seq:
5109
- * d.sunday? -> bool
5482
+ * sunday? -> true or false
5110
5483
  *
5111
- * Returns true if the date is Sunday.
5484
+ * Returns +true+ if +self+ is a Sunday, +false+ otherwise.
5112
5485
  */
5113
5486
  static VALUE
5114
5487
  d_lite_sunday_p(VALUE self)
@@ -5119,9 +5492,9 @@ d_lite_sunday_p(VALUE self)
5119
5492
 
5120
5493
  /*
5121
5494
  * call-seq:
5122
- * d.monday? -> bool
5495
+ * monday? -> true or false
5123
5496
  *
5124
- * Returns true if the date is Monday.
5497
+ * Returns +true+ if +self+ is a Monday, +false+ otherwise.
5125
5498
  */
5126
5499
  static VALUE
5127
5500
  d_lite_monday_p(VALUE self)
@@ -5132,9 +5505,9 @@ d_lite_monday_p(VALUE self)
5132
5505
 
5133
5506
  /*
5134
5507
  * call-seq:
5135
- * d.tuesday? -> bool
5508
+ * tuesday? -> true or false
5136
5509
  *
5137
- * Returns true if the date is Tuesday.
5510
+ * Returns +true+ if +self+ is a Tuesday, +false+ otherwise.
5138
5511
  */
5139
5512
  static VALUE
5140
5513
  d_lite_tuesday_p(VALUE self)
@@ -5145,9 +5518,9 @@ d_lite_tuesday_p(VALUE self)
5145
5518
 
5146
5519
  /*
5147
5520
  * call-seq:
5148
- * d.wednesday? -> bool
5521
+ * wednesday? -> true or false
5149
5522
  *
5150
- * Returns true if the date is Wednesday.
5523
+ * Returns +true+ if +self+ is a Wednesday, +false+ otherwise.
5151
5524
  */
5152
5525
  static VALUE
5153
5526
  d_lite_wednesday_p(VALUE self)
@@ -5158,9 +5531,9 @@ d_lite_wednesday_p(VALUE self)
5158
5531
 
5159
5532
  /*
5160
5533
  * call-seq:
5161
- * d.thursday? -> bool
5534
+ * thursday? -> true or false
5162
5535
  *
5163
- * Returns true if the date is Thursday.
5536
+ * Returns +true+ if +self+ is a Thursday, +false+ otherwise.
5164
5537
  */
5165
5538
  static VALUE
5166
5539
  d_lite_thursday_p(VALUE self)
@@ -5171,9 +5544,9 @@ d_lite_thursday_p(VALUE self)
5171
5544
 
5172
5545
  /*
5173
5546
  * call-seq:
5174
- * d.friday? -> bool
5547
+ * friday? -> true or false
5175
5548
  *
5176
- * Returns true if the date is Friday.
5549
+ * Returns +true+ if +self+ is a Friday, +false+ otherwise.
5177
5550
  */
5178
5551
  static VALUE
5179
5552
  d_lite_friday_p(VALUE self)
@@ -5184,9 +5557,9 @@ d_lite_friday_p(VALUE self)
5184
5557
 
5185
5558
  /*
5186
5559
  * call-seq:
5187
- * d.saturday? -> bool
5560
+ * saturday? -> true or false
5188
5561
  *
5189
- * Returns true if the date is Saturday.
5562
+ * Returns +true+ if +self+ is a Saturday, +false+ otherwise.
5190
5563
  */
5191
5564
  static VALUE
5192
5565
  d_lite_saturday_p(VALUE self)
@@ -5196,6 +5569,7 @@ d_lite_saturday_p(VALUE self)
5196
5569
  }
5197
5570
 
5198
5571
  #ifndef NDEBUG
5572
+ /* :nodoc: */
5199
5573
  static VALUE
5200
5574
  d_lite_nth_kday_p(VALUE self, VALUE n, VALUE k)
5201
5575
  {
@@ -5217,11 +5591,12 @@ d_lite_nth_kday_p(VALUE self, VALUE n, VALUE k)
5217
5591
 
5218
5592
  /*
5219
5593
  * call-seq:
5220
- * d.hour -> fixnum
5594
+ * hour -> integer
5595
+ *
5596
+ * Returns the hour in range (0..23):
5221
5597
  *
5222
- * Returns the hour (0-23).
5598
+ * DateTime.new(2001, 2, 3, 4, 5, 6).hour # => 4
5223
5599
  *
5224
- * DateTime.new(2001,2,3,4,5,6).hour #=> 4
5225
5600
  */
5226
5601
  static VALUE
5227
5602
  d_lite_hour(VALUE self)
@@ -5232,12 +5607,13 @@ d_lite_hour(VALUE self)
5232
5607
 
5233
5608
  /*
5234
5609
  * call-seq:
5235
- * d.min -> fixnum
5236
- * d.minute -> fixnum
5610
+ * min -> integer
5237
5611
  *
5238
- * Returns the minute (0-59).
5612
+ * Returns the minute in range (0..59):
5239
5613
  *
5240
- * DateTime.new(2001,2,3,4,5,6).min #=> 5
5614
+ * DateTime.new(2001, 2, 3, 4, 5, 6).min # => 5
5615
+ *
5616
+ * Date#minute is an alias for Date#min.
5241
5617
  */
5242
5618
  static VALUE
5243
5619
  d_lite_min(VALUE self)
@@ -5248,12 +5624,13 @@ d_lite_min(VALUE self)
5248
5624
 
5249
5625
  /*
5250
5626
  * call-seq:
5251
- * d.sec -> fixnum
5252
- * d.second -> fixnum
5627
+ * sec -> integer
5628
+ *
5629
+ * Returns the second in range (0..59):
5253
5630
  *
5254
- * Returns the second (0-59).
5631
+ * DateTime.new(2001, 2, 3, 4, 5, 6).sec # => 6
5255
5632
  *
5256
- * DateTime.new(2001,2,3,4,5,6).sec #=> 6
5633
+ * Date#second is an alias for Date#sec.
5257
5634
  */
5258
5635
  static VALUE
5259
5636
  d_lite_sec(VALUE self)
@@ -5264,12 +5641,14 @@ d_lite_sec(VALUE self)
5264
5641
 
5265
5642
  /*
5266
5643
  * call-seq:
5267
- * d.sec_fraction -> rational
5268
- * d.second_fraction -> rational
5644
+ * sec_fraction -> rational
5645
+ *
5646
+ * Returns the fractional part of the second in range
5647
+ * (Rational(0, 1)...Rational(1, 1)):
5269
5648
  *
5270
- * Returns the fractional part of the second.
5649
+ * DateTime.new(2001, 2, 3, 4, 5, 6.5).sec_fraction # => (1/2)
5271
5650
  *
5272
- * DateTime.new(2001,2,3,4,5,6.5).sec_fraction #=> (1/2)
5651
+ * Date#second_fraction is an alias for Date#sec_fraction.
5273
5652
  */
5274
5653
  static VALUE
5275
5654
  d_lite_sec_fraction(VALUE self)
@@ -5310,12 +5689,14 @@ d_lite_zone(VALUE self)
5310
5689
 
5311
5690
  /*
5312
5691
  * call-seq:
5313
- * d.julian? -> bool
5692
+ * d.julian? -> true or false
5314
5693
  *
5315
- * Returns true if the date is before the day of calendar reform.
5694
+ * Returns +true+ if the date is before the date of calendar reform,
5695
+ * +false+ otherwise:
5696
+ *
5697
+ * (Date.new(1582, 10, 15) - 1).julian? # => true
5698
+ * Date.new(1582, 10, 15).julian? # => false
5316
5699
  *
5317
- * Date.new(1582,10,15).julian? #=> false
5318
- * (Date.new(1582,10,15) - 1).julian? #=> true
5319
5700
  */
5320
5701
  static VALUE
5321
5702
  d_lite_julian_p(VALUE self)
@@ -5326,12 +5707,14 @@ d_lite_julian_p(VALUE self)
5326
5707
 
5327
5708
  /*
5328
5709
  * call-seq:
5329
- * d.gregorian? -> bool
5710
+ * gregorian? -> true or false
5711
+ *
5712
+ * Returns +true+ if the date is on or after
5713
+ * the date of calendar reform, +false+ otherwise:
5330
5714
  *
5331
- * Returns true if the date is on or after the day of calendar reform.
5715
+ * Date.new(1582, 10, 15).gregorian? # => true
5716
+ * (Date.new(1582, 10, 15) - 1).gregorian? # => false
5332
5717
  *
5333
- * Date.new(1582,10,15).gregorian? #=> true
5334
- * (Date.new(1582,10,15) - 1).gregorian? #=> false
5335
5718
  */
5336
5719
  static VALUE
5337
5720
  d_lite_gregorian_p(VALUE self)
@@ -5342,12 +5725,13 @@ d_lite_gregorian_p(VALUE self)
5342
5725
 
5343
5726
  /*
5344
5727
  * call-seq:
5345
- * d.leap? -> bool
5728
+ * leap? -> true or false
5729
+ *
5730
+ * Returns +true+ if the year is a leap year, +false+ otherwise:
5346
5731
  *
5347
- * Returns true if the year is a leap year.
5732
+ * Date.new(2000).leap? # => true
5733
+ * Date.new(2001).leap? # => false
5348
5734
  *
5349
- * Date.new(2000).leap? #=> true
5350
- * Date.new(2001).leap? #=> false
5351
5735
  */
5352
5736
  static VALUE
5353
5737
  d_lite_leap_p(VALUE self)
@@ -5366,12 +5750,25 @@ d_lite_leap_p(VALUE self)
5366
5750
 
5367
5751
  /*
5368
5752
  * call-seq:
5369
- * d.start -> float
5753
+ * start -> float
5370
5754
  *
5371
- * Returns the Julian day number denoting the day of calendar reform.
5755
+ * Returns the Julian start date for calendar reform;
5756
+ * if not an infinity, the returned value is suitable
5757
+ * for passing to Date#jd:
5758
+ *
5759
+ * d = Date.new(2001, 2, 3, Date::ITALY)
5760
+ * s = d.start # => 2299161.0
5761
+ * Date.jd(s).to_s # => "1582-10-15"
5762
+ *
5763
+ * d = Date.new(2001, 2, 3, Date::ENGLAND)
5764
+ * s = d.start # => 2361222.0
5765
+ * Date.jd(s).to_s # => "1752-09-14"
5766
+ *
5767
+ * Date.new(2001, 2, 3, Date::GREGORIAN).start # => -Infinity
5768
+ * Date.new(2001, 2, 3, Date::JULIAN).start # => Infinity
5769
+ *
5770
+ * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
5372
5771
  *
5373
- * Date.new(2001,2,3).start #=> 2299161.0
5374
- * Date.new(2001,2,3,Date::GREGORIAN).start #=> -Infinity
5375
5772
  */
5376
5773
  static VALUE
5377
5774
  d_lite_start(VALUE self)
@@ -5436,12 +5833,17 @@ dup_obj_with_new_start(VALUE obj, double sg)
5436
5833
 
5437
5834
  /*
5438
5835
  * call-seq:
5439
- * d.new_start([start=Date::ITALY]) -> date
5836
+ * new_start(start = Date::ITALY]) -> new_date
5837
+ *
5838
+ * Returns a copy of +self+ with the given +start+ value:
5839
+ *
5840
+ * d0 = Date.new(2000, 2, 3)
5841
+ * d0.julian? # => false
5842
+ * d1 = d0.new_start(Date::JULIAN)
5843
+ * d1.julian? # => true
5440
5844
  *
5441
- * Duplicates self and resets its day of calendar reform.
5845
+ * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start].
5442
5846
  *
5443
- * d = Date.new(1582,10,15)
5444
- * d.new_start(Date::JULIAN) #=> #<Date: 1582-10-05 ...>
5445
5847
  */
5446
5848
  static VALUE
5447
5849
  d_lite_new_start(int argc, VALUE *argv, VALUE self)
@@ -5460,9 +5862,10 @@ d_lite_new_start(int argc, VALUE *argv, VALUE self)
5460
5862
 
5461
5863
  /*
5462
5864
  * call-seq:
5463
- * d.italy -> date
5865
+ * italy -> new_date
5866
+ *
5867
+ * Equivalent to Date#new_start with argument Date::ITALY.
5464
5868
  *
5465
- * This method is equivalent to new_start(Date::ITALY).
5466
5869
  */
5467
5870
  static VALUE
5468
5871
  d_lite_italy(VALUE self)
@@ -5472,9 +5875,9 @@ d_lite_italy(VALUE self)
5472
5875
 
5473
5876
  /*
5474
5877
  * call-seq:
5475
- * d.england -> date
5878
+ * england -> new_date
5476
5879
  *
5477
- * This method is equivalent to new_start(Date::ENGLAND).
5880
+ * Equivalent to Date#new_start with argument Date::ENGLAND.
5478
5881
  */
5479
5882
  static VALUE
5480
5883
  d_lite_england(VALUE self)
@@ -5484,9 +5887,9 @@ d_lite_england(VALUE self)
5484
5887
 
5485
5888
  /*
5486
5889
  * call-seq:
5487
- * d.julian -> date
5890
+ * julian -> new_date
5488
5891
  *
5489
- * This method is equivalent to new_start(Date::JULIAN).
5892
+ * Equivalent to Date#new_start with argument Date::JULIAN.
5490
5893
  */
5491
5894
  static VALUE
5492
5895
  d_lite_julian(VALUE self)
@@ -5496,9 +5899,9 @@ d_lite_julian(VALUE self)
5496
5899
 
5497
5900
  /*
5498
5901
  * call-seq:
5499
- * d.gregorian -> date
5902
+ * gregorian -> new_date
5500
5903
  *
5501
- * This method is equivalent to new_start(Date::GREGORIAN).
5904
+ * Equivalent to Date#new_start with argument Date::GREGORIAN.
5502
5905
  */
5503
5906
  static VALUE
5504
5907
  d_lite_gregorian(VALUE self)
@@ -5979,9 +6382,9 @@ d_lite_minus(VALUE self, VALUE other)
5979
6382
 
5980
6383
  /*
5981
6384
  * call-seq:
5982
- * d.next_day([n=1]) -> date
6385
+ * next_day(n = 1) -> new_date
5983
6386
  *
5984
- * This method is equivalent to d + n.
6387
+ * Equivalent to Date#+ with argument +n+.
5985
6388
  */
5986
6389
  static VALUE
5987
6390
  d_lite_next_day(int argc, VALUE *argv, VALUE self)
@@ -5996,9 +6399,9 @@ d_lite_next_day(int argc, VALUE *argv, VALUE self)
5996
6399
 
5997
6400
  /*
5998
6401
  * call-seq:
5999
- * d.prev_day([n=1]) -> date
6402
+ * prev_day(n = 1) -> new_date
6000
6403
  *
6001
- * This method is equivalent to d - n.
6404
+ * Equivalent to Date#- with argument +n+.
6002
6405
  */
6003
6406
  static VALUE
6004
6407
  d_lite_prev_day(int argc, VALUE *argv, VALUE self)
@@ -6013,10 +6416,15 @@ d_lite_prev_day(int argc, VALUE *argv, VALUE self)
6013
6416
 
6014
6417
  /*
6015
6418
  * call-seq:
6016
- * d.succ -> date
6017
- * d.next -> date
6419
+ * d.next -> new_date
6420
+ *
6421
+ * Returns a new \Date object representing the following day:
6422
+ *
6423
+ * d = Date.new(2001, 2, 3)
6424
+ * d.to_s # => "2001-02-03"
6425
+ * d.next.to_s # => "2001-02-04"
6018
6426
  *
6019
- * Returns a date object denoting the following day.
6427
+ * Date#succ is an alias for Date#next.
6020
6428
  */
6021
6429
  static VALUE
6022
6430
  d_lite_next(VALUE self)
@@ -6026,26 +6434,30 @@ d_lite_next(VALUE self)
6026
6434
 
6027
6435
  /*
6028
6436
  * call-seq:
6029
- * d >> n -> date
6437
+ * d >> n -> new_date
6030
6438
  *
6031
- * Returns a date object pointing +n+ months after self.
6032
- * The argument +n+ should be a numeric value.
6439
+ * Returns a new \Date object representing the date
6440
+ * +n+ months later; +n+ should be a numeric:
6033
6441
  *
6034
- * Date.new(2001,2,3) >> 1 #=> #<Date: 2001-03-03 ...>
6035
- * Date.new(2001,2,3) >> -2 #=> #<Date: 2000-12-03 ...>
6442
+ * (Date.new(2001, 2, 3) >> 1).to_s # => "2001-03-03"
6443
+ * (Date.new(2001, 2, 3) >> -2).to_s # => "2000-12-03"
6036
6444
  *
6037
- * When the same day does not exist for the corresponding month,
6038
- * the last day of the month is used instead:
6445
+ * When the same day does not exist for the new month,
6446
+ * the last day of that month is used instead:
6039
6447
  *
6040
- * Date.new(2001,1,28) >> 1 #=> #<Date: 2001-02-28 ...>
6041
- * Date.new(2001,1,31) >> 1 #=> #<Date: 2001-02-28 ...>
6448
+ * (Date.new(2001, 1, 31) >> 1).to_s # => "2001-02-28"
6449
+ * (Date.new(2001, 1, 31) >> -4).to_s # => "2000-09-30"
6042
6450
  *
6043
- * This also results in the following, possibly unexpected, behavior:
6451
+ * This results in the following, possibly unexpected, behaviors:
6044
6452
  *
6045
- * Date.new(2001,1,31) >> 2 #=> #<Date: 2001-03-31 ...>
6046
- * Date.new(2001,1,31) >> 1 >> 1 #=> #<Date: 2001-03-28 ...>
6453
+ * d0 = Date.new(2001, 1, 31)
6454
+ * d1 = d0 >> 1 # => #<Date: 2001-02-28>
6455
+ * d2 = d1 >> 1 # => #<Date: 2001-03-28>
6456
+ *
6457
+ * d0 = Date.new(2001, 1, 31)
6458
+ * d1 = d0 >> 1 # => #<Date: 2001-02-28>
6459
+ * d2 = d1 >> -1 # => #<Date: 2001-01-28>
6047
6460
  *
6048
- * Date.new(2001,1,31) >> 1 >> -1 #=> #<Date: 2001-01-28 ...>
6049
6461
  */
6050
6462
  static VALUE
6051
6463
  d_lite_rshift(VALUE self, VALUE other)
@@ -6090,24 +6502,28 @@ d_lite_rshift(VALUE self, VALUE other)
6090
6502
  * call-seq:
6091
6503
  * d << n -> date
6092
6504
  *
6093
- * Returns a date object pointing +n+ months before self.
6094
- * The argument +n+ should be a numeric value.
6505
+ * Returns a new \Date object representing the date
6506
+ * +n+ months earlier; +n+ should be a numeric:
6507
+ *
6508
+ * (Date.new(2001, 2, 3) << 1).to_s # => "2001-01-03"
6509
+ * (Date.new(2001, 2, 3) << -2).to_s # => "2001-04-03"
6095
6510
  *
6096
- * Date.new(2001,2,3) << 1 #=> #<Date: 2001-01-03 ...>
6097
- * Date.new(2001,2,3) << -2 #=> #<Date: 2001-04-03 ...>
6511
+ * When the same day does not exist for the new month,
6512
+ * the last day of that month is used instead:
6098
6513
  *
6099
- * When the same day does not exist for the corresponding month,
6100
- * the last day of the month is used instead:
6514
+ * (Date.new(2001, 3, 31) << 1).to_s # => "2001-02-28"
6515
+ * (Date.new(2001, 3, 31) << -6).to_s # => "2001-09-30"
6101
6516
  *
6102
- * Date.new(2001,3,28) << 1 #=> #<Date: 2001-02-28 ...>
6103
- * Date.new(2001,3,31) << 1 #=> #<Date: 2001-02-28 ...>
6517
+ * This results in the following, possibly unexpected, behaviors:
6104
6518
  *
6105
- * This also results in the following, possibly unexpected, behavior:
6519
+ * d0 = Date.new(2001, 3, 31)
6520
+ * d0 << 2 # => #<Date: 2001-01-31>
6521
+ * d0 << 1 << 1 # => #<Date: 2001-01-28>
6106
6522
  *
6107
- * Date.new(2001,3,31) << 2 #=> #<Date: 2001-01-31 ...>
6108
- * Date.new(2001,3,31) << 1 << 1 #=> #<Date: 2001-01-28 ...>
6523
+ * d0 = Date.new(2001, 3, 31)
6524
+ * d1 = d0 << 1 # => #<Date: 2001-02-28>
6525
+ * d2 = d1 << -1 # => #<Date: 2001-03-28>
6109
6526
  *
6110
- * Date.new(2001,3,31) << 1 << -1 #=> #<Date: 2001-03-28 ...>
6111
6527
  */
6112
6528
  static VALUE
6113
6529
  d_lite_lshift(VALUE self, VALUE other)
@@ -6118,11 +6534,9 @@ d_lite_lshift(VALUE self, VALUE other)
6118
6534
 
6119
6535
  /*
6120
6536
  * call-seq:
6121
- * d.next_month([n=1]) -> date
6122
- *
6123
- * This method is equivalent to d >> n.
6537
+ * next_month(n = 1) -> new_date
6124
6538
  *
6125
- * See Date#>> for examples.
6539
+ * Equivalent to #>> with argument +n+.
6126
6540
  */
6127
6541
  static VALUE
6128
6542
  d_lite_next_month(int argc, VALUE *argv, VALUE self)
@@ -6137,11 +6551,9 @@ d_lite_next_month(int argc, VALUE *argv, VALUE self)
6137
6551
 
6138
6552
  /*
6139
6553
  * call-seq:
6140
- * d.prev_month([n=1]) -> date
6554
+ * prev_month(n = 1) -> new_date
6141
6555
  *
6142
- * This method is equivalent to d << n.
6143
- *
6144
- * See Date#<< for examples.
6556
+ * Equivalent to #<< with argument +n+.
6145
6557
  */
6146
6558
  static VALUE
6147
6559
  d_lite_prev_month(int argc, VALUE *argv, VALUE self)
@@ -6156,15 +6568,9 @@ d_lite_prev_month(int argc, VALUE *argv, VALUE self)
6156
6568
 
6157
6569
  /*
6158
6570
  * call-seq:
6159
- * d.next_year([n=1]) -> date
6160
- *
6161
- * This method is equivalent to d >> (n * 12).
6162
- *
6163
- * Date.new(2001,2,3).next_year #=> #<Date: 2002-02-03 ...>
6164
- * Date.new(2008,2,29).next_year #=> #<Date: 2009-02-28 ...>
6165
- * Date.new(2008,2,29).next_year(4) #=> #<Date: 2012-02-29 ...>
6571
+ * next_year(n = 1) -> new_date
6166
6572
  *
6167
- * See also Date#>>.
6573
+ * Equivalent to #>> with argument <tt>n * 12</tt>.
6168
6574
  */
6169
6575
  static VALUE
6170
6576
  d_lite_next_year(int argc, VALUE *argv, VALUE self)
@@ -6179,15 +6585,9 @@ d_lite_next_year(int argc, VALUE *argv, VALUE self)
6179
6585
 
6180
6586
  /*
6181
6587
  * call-seq:
6182
- * d.prev_year([n=1]) -> date
6588
+ * prev_year(n = 1) -> new_date
6183
6589
  *
6184
- * This method is equivalent to d << (n * 12).
6185
- *
6186
- * Date.new(2001,2,3).prev_year #=> #<Date: 2000-02-03 ...>
6187
- * Date.new(2008,2,29).prev_year #=> #<Date: 2007-02-28 ...>
6188
- * Date.new(2008,2,29).prev_year(4) #=> #<Date: 2004-02-29 ...>
6189
- *
6190
- * See also Date#<<.
6590
+ * Equivalent to #<< with argument <tt>n * 12</tt>.
6191
6591
  */
6192
6592
  static VALUE
6193
6593
  d_lite_prev_year(int argc, VALUE *argv, VALUE self)
@@ -6204,14 +6604,33 @@ static VALUE d_lite_cmp(VALUE, VALUE);
6204
6604
 
6205
6605
  /*
6206
6606
  * call-seq:
6207
- * d.step(limit[, step=1]) -> enumerator
6208
- * d.step(limit[, step=1]){|date| ...} -> self
6607
+ * step(limit, step = 1){|date| ... } -> self
6608
+ *
6609
+ * Calls the block with specified dates;
6610
+ * returns +self+.
6209
6611
  *
6210
- * Iterates evaluation of the given block, which takes a date object.
6211
- * The limit should be a date object.
6612
+ * - The first +date+ is +self+.
6613
+ * - Each successive +date+ is <tt>date + step</tt>,
6614
+ * where +step+ is the numeric step size in days.
6615
+ * - The last date is the last one that is before or equal to +limit+,
6616
+ * which should be a \Date object.
6212
6617
  *
6213
- * Date.new(2001).step(Date.new(2001,-1,-1)).select{|d| d.sunday?}.size
6214
- * #=> 52
6618
+ * Example:
6619
+ *
6620
+ * limit = Date.new(2001, 12, 31)
6621
+ * Date.new(2001).step(limit){|date| p date.to_s if date.mday == 31 }
6622
+ *
6623
+ * Output:
6624
+ *
6625
+ * "2001-01-31"
6626
+ * "2001-03-31"
6627
+ * "2001-05-31"
6628
+ * "2001-07-31"
6629
+ * "2001-08-31"
6630
+ * "2001-10-31"
6631
+ * "2001-12-31"
6632
+ *
6633
+ * Returns an Enumerator if no block is given.
6215
6634
  */
6216
6635
  static VALUE
6217
6636
  d_lite_step(int argc, VALUE *argv, VALUE self)
@@ -6254,10 +6673,9 @@ d_lite_step(int argc, VALUE *argv, VALUE self)
6254
6673
 
6255
6674
  /*
6256
6675
  * call-seq:
6257
- * d.upto(max) -> enumerator
6258
- * d.upto(max){|date| ...} -> self
6676
+ * upto(max){|date| ... } -> self
6259
6677
  *
6260
- * This method is equivalent to step(max, 1){|date| ...}.
6678
+ * Equivalent to #step with arguments +max+ and +1+.
6261
6679
  */
6262
6680
  static VALUE
6263
6681
  d_lite_upto(VALUE self, VALUE max)
@@ -6276,10 +6694,9 @@ d_lite_upto(VALUE self, VALUE max)
6276
6694
 
6277
6695
  /*
6278
6696
  * call-seq:
6279
- * d.downto(min) -> enumerator
6280
- * d.downto(min){|date| ...} -> self
6697
+ * downto(min){|date| ... } -> self
6281
6698
  *
6282
- * This method is equivalent to step(min, -1){|date| ...}.
6699
+ * Equivalent to #step with arguments +min+ and <tt>-1</tt>.
6283
6700
  */
6284
6701
  static VALUE
6285
6702
  d_lite_downto(VALUE self, VALUE min)
@@ -6367,19 +6784,43 @@ cmp_dd(VALUE self, VALUE other)
6367
6784
 
6368
6785
  /*
6369
6786
  * call-seq:
6370
- * d <=> other -> -1, 0, +1 or nil
6787
+ * self <=> other -> -1, 0, 1 or nil
6788
+ *
6789
+ * Compares +self+ and +other+, returning:
6790
+ *
6791
+ * - <tt>-1</tt> if +other+ is larger.
6792
+ * - <tt>0</tt> if the two are equal.
6793
+ * - <tt>1</tt> if +other+ is smaller.
6794
+ * - +nil+ if the two are incomparable.
6371
6795
  *
6372
- * Compares the two dates and returns -1, zero, 1 or nil. The other
6373
- * should be a date object or a numeric value as an astronomical
6374
- * Julian day number.
6796
+ * Argument +other+ may be:
6375
6797
  *
6376
- * Date.new(2001,2,3) <=> Date.new(2001,2,4) #=> -1
6377
- * Date.new(2001,2,3) <=> Date.new(2001,2,3) #=> 0
6378
- * Date.new(2001,2,3) <=> Date.new(2001,2,2) #=> 1
6379
- * Date.new(2001,2,3) <=> Object.new #=> nil
6380
- * Date.new(2001,2,3) <=> Rational(4903887,2) #=> 0
6798
+ * - Another \Date object:
6799
+ *
6800
+ * d = Date.new(2022, 7, 27) # => #<Date: 2022-07-27 ((2459788j,0s,0n),+0s,2299161j)>
6801
+ * prev_date = d.prev_day # => #<Date: 2022-07-26 ((2459787j,0s,0n),+0s,2299161j)>
6802
+ * next_date = d.next_day # => #<Date: 2022-07-28 ((2459789j,0s,0n),+0s,2299161j)>
6803
+ * d <=> next_date # => -1
6804
+ * d <=> d # => 0
6805
+ * d <=> prev_date # => 1
6806
+ *
6807
+ * - A DateTime object:
6808
+ *
6809
+ * d <=> DateTime.new(2022, 7, 26) # => 1
6810
+ * d <=> DateTime.new(2022, 7, 27) # => 0
6811
+ * d <=> DateTime.new(2022, 7, 28) # => -1
6812
+ *
6813
+ * - A numeric (compares <tt>self.ajd</tt> to +other+):
6814
+ *
6815
+ * d <=> 2459788 # => -1
6816
+ * d <=> 2459787 # => 1
6817
+ * d <=> 2459786 # => 1
6818
+ * d <=> d.ajd # => 0
6819
+ *
6820
+ * - Any other object:
6821
+ *
6822
+ * d <=> Object.new # => nil
6381
6823
  *
6382
- * See also Comparable.
6383
6824
  */
6384
6825
  static VALUE
6385
6826
  d_lite_cmp(VALUE self, VALUE other)
@@ -6439,20 +6880,39 @@ equal_gen(VALUE self, VALUE other)
6439
6880
 
6440
6881
  /*
6441
6882
  * call-seq:
6442
- * d === other -> bool
6443
- *
6444
- * Returns true if they are the same day.
6445
- *
6446
- * Date.new(2001,2,3) === Date.new(2001,2,3)
6447
- * #=> true
6448
- * Date.new(2001,2,3) === Date.new(2001,2,4)
6449
- * #=> false
6450
- * DateTime.new(2001,2,3) === DateTime.new(2001,2,3,12)
6451
- * #=> true
6452
- * DateTime.new(2001,2,3) === DateTime.new(2001,2,3,0,0,0,'+24:00')
6453
- * #=> true
6454
- * DateTime.new(2001,2,3) === DateTime.new(2001,2,4,0,0,0,'+24:00')
6455
- * #=> false
6883
+ * self === other -> true, false, or nil.
6884
+ *
6885
+ * Returns +true+ if +self+ and +other+ represent the same date,
6886
+ * +false+ if not, +nil+ if the two are not comparable.
6887
+ *
6888
+ * Argument +other+ may be:
6889
+ *
6890
+ * - Another \Date object:
6891
+ *
6892
+ * d = Date.new(2022, 7, 27) # => #<Date: 2022-07-27 ((2459788j,0s,0n),+0s,2299161j)>
6893
+ * prev_date = d.prev_day # => #<Date: 2022-07-26 ((2459787j,0s,0n),+0s,2299161j)>
6894
+ * next_date = d.next_day # => #<Date: 2022-07-28 ((2459789j,0s,0n),+0s,2299161j)>
6895
+ * d === prev_date # => false
6896
+ * d === d # => true
6897
+ * d === next_date # => false
6898
+ *
6899
+ * - A DateTime object:
6900
+ *
6901
+ * d === DateTime.new(2022, 7, 26) # => false
6902
+ * d === DateTime.new(2022, 7, 27) # => true
6903
+ * d === DateTime.new(2022, 7, 28) # => false
6904
+ *
6905
+ * - A numeric (compares <tt>self.jd</tt> to +other+):
6906
+ *
6907
+ * d === 2459788 # => true
6908
+ * d === 2459787 # => false
6909
+ * d === 2459786 # => false
6910
+ * d === d.jd # => true
6911
+ *
6912
+ * - An object not comparable:
6913
+ *
6914
+ * d === Object.new # => nil
6915
+ *
6456
6916
  */
6457
6917
  static VALUE
6458
6918
  d_lite_equal(VALUE self, VALUE other)
@@ -6515,12 +6975,14 @@ static VALUE strftimev(const char *, VALUE,
6515
6975
 
6516
6976
  /*
6517
6977
  * call-seq:
6518
- * d.to_s -> string
6978
+ * to_s -> string
6519
6979
  *
6520
- * Returns a string in an ISO 8601 format. (This method doesn't use the
6521
- * expanded representations.)
6980
+ * Returns a string representation of the date in +self+
6981
+ * in {ISO 8601 extended date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-ISO+8601+Format+Specifications]
6982
+ * (<tt>'%Y-%m-%d'</tt>):
6983
+ *
6984
+ * Date.new(2001, 2, 3).to_s # => "2001-02-03"
6522
6985
  *
6523
- * Date.new(2001,2,3).to_s #=> "2001-02-03"
6524
6986
  */
6525
6987
  static VALUE
6526
6988
  d_lite_to_s(VALUE self)
@@ -6529,6 +6991,7 @@ d_lite_to_s(VALUE self)
6529
6991
  }
6530
6992
 
6531
6993
  #ifndef NDEBUG
6994
+ /* :nodoc: */
6532
6995
  static VALUE
6533
6996
  mk_inspect_raw(union DateData *x, VALUE klass)
6534
6997
  {
@@ -6578,6 +7041,7 @@ mk_inspect_raw(union DateData *x, VALUE klass)
6578
7041
  }
6579
7042
  }
6580
7043
 
7044
+ /* :nodoc: */
6581
7045
  static VALUE
6582
7046
  d_lite_inspect_raw(VALUE self)
6583
7047
  {
@@ -6599,14 +7063,13 @@ mk_inspect(union DateData *x, VALUE klass, VALUE to_s)
6599
7063
 
6600
7064
  /*
6601
7065
  * call-seq:
6602
- * d.inspect -> string
7066
+ * inspect -> string
7067
+ *
7068
+ * Returns a string representation of +self+:
6603
7069
  *
6604
- * Returns the value as a string for inspection.
7070
+ * Date.new(2001, 2, 3).inspect
7071
+ * # => "#<Date: 2001-02-03 ((2451944j,0s,0n),+0s,2299161j)>"
6605
7072
  *
6606
- * Date.new(2001,2,3).inspect
6607
- * #=> "#<Date: 2001-02-03>"
6608
- * DateTime.new(2001,2,3,4,5,6,'-7').inspect
6609
- * #=> "#<DateTime: 2001-02-03T04:05:06-07:00>"
6610
7073
  */
6611
7074
  static VALUE
6612
7075
  d_lite_inspect(VALUE self)
@@ -6788,180 +7251,16 @@ date_strftime_internal(int argc, VALUE *argv, VALUE self,
6788
7251
 
6789
7252
  /*
6790
7253
  * call-seq:
6791
- * d.strftime([format='%F']) -> string
6792
- *
6793
- * Formats date according to the directives in the given format
6794
- * string.
6795
- * The directives begin with a percent (%) character.
6796
- * Any text not listed as a directive will be passed through to the
6797
- * output string.
6798
- *
6799
- * A directive consists of a percent (%) character,
6800
- * zero or more flags, an optional minimum field width,
6801
- * an optional modifier, and a conversion specifier
6802
- * as follows.
6803
- *
6804
- * %<flags><width><modifier><conversion>
6805
- *
6806
- * Flags:
6807
- * - don't pad a numerical output.
6808
- * _ use spaces for padding.
6809
- * 0 use zeros for padding.
6810
- * ^ upcase the result string.
6811
- * # change case.
6812
- *
6813
- * The minimum field width specifies the minimum width.
6814
- *
6815
- * The modifiers are "E", "O", ":", "::" and ":::".
6816
- * "E" and "O" are ignored. No effect to result currently.
6817
- *
6818
- * Format directives:
6819
- *
6820
- * Date (Year, Month, Day):
6821
- * %Y - Year with century (can be negative, 4 digits at least)
6822
- * -0001, 0000, 1995, 2009, 14292, etc.
6823
- * %C - year / 100 (round down. 20 in 2009)
6824
- * %y - year % 100 (00..99)
6825
- *
6826
- * %m - Month of the year, zero-padded (01..12)
6827
- * %_m blank-padded ( 1..12)
6828
- * %-m no-padded (1..12)
6829
- * %B - The full month name (``January'')
6830
- * %^B uppercased (``JANUARY'')
6831
- * %b - The abbreviated month name (``Jan'')
6832
- * %^b uppercased (``JAN'')
6833
- * %h - Equivalent to %b
6834
- *
6835
- * %d - Day of the month, zero-padded (01..31)
6836
- * %-d no-padded (1..31)
6837
- * %e - Day of the month, blank-padded ( 1..31)
6838
- *
6839
- * %j - Day of the year (001..366)
6840
- *
6841
- * Time (Hour, Minute, Second, Subsecond):
6842
- * %H - Hour of the day, 24-hour clock, zero-padded (00..23)
6843
- * %k - Hour of the day, 24-hour clock, blank-padded ( 0..23)
6844
- * %I - Hour of the day, 12-hour clock, zero-padded (01..12)
6845
- * %l - Hour of the day, 12-hour clock, blank-padded ( 1..12)
6846
- * %P - Meridian indicator, lowercase (``am'' or ``pm'')
6847
- * %p - Meridian indicator, uppercase (``AM'' or ``PM'')
6848
- *
6849
- * %M - Minute of the hour (00..59)
6850
- *
6851
- * %S - Second of the minute (00..60)
6852
- *
6853
- * %L - Millisecond of the second (000..999)
6854
- * %N - Fractional seconds digits, default is 9 digits (nanosecond)
6855
- * %3N millisecond (3 digits) %15N femtosecond (15 digits)
6856
- * %6N microsecond (6 digits) %18N attosecond (18 digits)
6857
- * %9N nanosecond (9 digits) %21N zeptosecond (21 digits)
6858
- * %12N picosecond (12 digits) %24N yoctosecond (24 digits)
6859
- *
6860
- * Time zone:
6861
- * %z - Time zone as hour and minute offset from UTC (e.g. +0900)
6862
- * %:z - hour and minute offset from UTC with a colon (e.g. +09:00)
6863
- * %::z - hour, minute and second offset from UTC (e.g. +09:00:00)
6864
- * %:::z - hour, minute and second offset from UTC
6865
- * (e.g. +09, +09:30, +09:30:30)
6866
- * %Z - Equivalent to %:z (e.g. +09:00)
6867
- *
6868
- * Weekday:
6869
- * %A - The full weekday name (``Sunday'')
6870
- * %^A uppercased (``SUNDAY'')
6871
- * %a - The abbreviated name (``Sun'')
6872
- * %^a uppercased (``SUN'')
6873
- * %u - Day of the week (Monday is 1, 1..7)
6874
- * %w - Day of the week (Sunday is 0, 0..6)
6875
- *
6876
- * ISO 8601 week-based year and week number:
6877
- * The week 1 of YYYY starts with a Monday and includes YYYY-01-04.
6878
- * The days in the year before the first week are in the last week of
6879
- * the previous year.
6880
- * %G - The week-based year
6881
- * %g - The last 2 digits of the week-based year (00..99)
6882
- * %V - Week number of the week-based year (01..53)
6883
- *
6884
- * Week number:
6885
- * The week 1 of YYYY starts with a Sunday or Monday (according to %U
6886
- * or %W). The days in the year before the first week are in week 0.
6887
- * %U - Week number of the year. The week starts with Sunday. (00..53)
6888
- * %W - Week number of the year. The week starts with Monday. (00..53)
6889
- *
6890
- * Seconds since the Unix Epoch:
6891
- * %s - Number of seconds since 1970-01-01 00:00:00 UTC.
6892
- * %Q - Number of milliseconds since 1970-01-01 00:00:00 UTC.
6893
- *
6894
- * Literal string:
6895
- * %n - Newline character (\n)
6896
- * %t - Tab character (\t)
6897
- * %% - Literal ``%'' character
6898
- *
6899
- * Combination:
6900
- * %c - date and time (%a %b %e %T %Y)
6901
- * %D - Date (%m/%d/%y)
6902
- * %F - The ISO 8601 date format (%Y-%m-%d)
6903
- * %v - VMS date (%e-%^b-%Y)
6904
- * %x - Same as %D
6905
- * %X - Same as %T
6906
- * %r - 12-hour time (%I:%M:%S %p)
6907
- * %R - 24-hour time (%H:%M)
6908
- * %T - 24-hour time (%H:%M:%S)
6909
- * %+ - date(1) (%a %b %e %H:%M:%S %Z %Y)
6910
- *
6911
- * This method is similar to the strftime() function defined in ISO C
6912
- * and POSIX.
6913
- * Several directives (%a, %A, %b, %B, %c, %p, %r, %x, %X, %E*, %O* and %Z)
6914
- * are locale dependent in the function.
6915
- * However, this method is locale independent.
6916
- * So, the result may differ even if the same format string is used in other
6917
- * systems such as C.
6918
- * It is good practice to avoid %x and %X because there are corresponding
6919
- * locale independent representations, %D and %T.
6920
- *
6921
- * Examples:
6922
- *
6923
- * d = DateTime.new(2007,11,19,8,37,48,"-06:00")
6924
- * #=> #<DateTime: 2007-11-19T08:37:48-0600 ...>
6925
- * d.strftime("Printed on %m/%d/%Y") #=> "Printed on 11/19/2007"
6926
- * d.strftime("at %I:%M%p") #=> "at 08:37AM"
6927
- *
6928
- * Various ISO 8601 formats:
6929
- * %Y%m%d => 20071119 Calendar date (basic)
6930
- * %F => 2007-11-19 Calendar date (extended)
6931
- * %Y-%m => 2007-11 Calendar date, reduced accuracy, specific month
6932
- * %Y => 2007 Calendar date, reduced accuracy, specific year
6933
- * %C => 20 Calendar date, reduced accuracy, specific century
6934
- * %Y%j => 2007323 Ordinal date (basic)
6935
- * %Y-%j => 2007-323 Ordinal date (extended)
6936
- * %GW%V%u => 2007W471 Week date (basic)
6937
- * %G-W%V-%u => 2007-W47-1 Week date (extended)
6938
- * %GW%V => 2007W47 Week date, reduced accuracy, specific week (basic)
6939
- * %G-W%V => 2007-W47 Week date, reduced accuracy, specific week (extended)
6940
- * %H%M%S => 083748 Local time (basic)
6941
- * %T => 08:37:48 Local time (extended)
6942
- * %H%M => 0837 Local time, reduced accuracy, specific minute (basic)
6943
- * %H:%M => 08:37 Local time, reduced accuracy, specific minute (extended)
6944
- * %H => 08 Local time, reduced accuracy, specific hour
6945
- * %H%M%S,%L => 083748,000 Local time with decimal fraction, comma as decimal sign (basic)
6946
- * %T,%L => 08:37:48,000 Local time with decimal fraction, comma as decimal sign (extended)
6947
- * %H%M%S.%L => 083748.000 Local time with decimal fraction, full stop as decimal sign (basic)
6948
- * %T.%L => 08:37:48.000 Local time with decimal fraction, full stop as decimal sign (extended)
6949
- * %H%M%S%z => 083748-0600 Local time and the difference from UTC (basic)
6950
- * %T%:z => 08:37:48-06:00 Local time and the difference from UTC (extended)
6951
- * %Y%m%dT%H%M%S%z => 20071119T083748-0600 Date and time of day for calendar date (basic)
6952
- * %FT%T%:z => 2007-11-19T08:37:48-06:00 Date and time of day for calendar date (extended)
6953
- * %Y%jT%H%M%S%z => 2007323T083748-0600 Date and time of day for ordinal date (basic)
6954
- * %Y-%jT%T%:z => 2007-323T08:37:48-06:00 Date and time of day for ordinal date (extended)
6955
- * %GW%V%uT%H%M%S%z => 2007W471T083748-0600 Date and time of day for week date (basic)
6956
- * %G-W%V-%uT%T%:z => 2007-W47-1T08:37:48-06:00 Date and time of day for week date (extended)
6957
- * %Y%m%dT%H%M => 20071119T0837 Calendar date and local time (basic)
6958
- * %FT%R => 2007-11-19T08:37 Calendar date and local time (extended)
6959
- * %Y%jT%H%MZ => 2007323T0837Z Ordinal date and UTC of day (basic)
6960
- * %Y-%jT%RZ => 2007-323T08:37Z Ordinal date and UTC of day (extended)
6961
- * %GW%V%uT%H%M%z => 2007W471T0837-0600 Week date and local time and difference from UTC (basic)
6962
- * %G-W%V-%uT%R%:z => 2007-W47-1T08:37-06:00 Week date and local time and difference from UTC (extended)
6963
- *
6964
- * See also strftime(3) and ::strptime.
7254
+ * strftime(format = '%F') -> string
7255
+ *
7256
+ * Returns a string representation of the date in +self+,
7257
+ * formatted according the given +format+:
7258
+ *
7259
+ * Date.new(2001, 2, 3).strftime # => "2001-02-03"
7260
+ *
7261
+ * For other formats, see
7262
+ * {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html].
7263
+ *
6965
7264
  */
6966
7265
  static VALUE
6967
7266
  d_lite_strftime(int argc, VALUE *argv, VALUE self)
@@ -6989,13 +7288,17 @@ strftimev(const char *fmt, VALUE self,
6989
7288
 
6990
7289
  /*
6991
7290
  * call-seq:
6992
- * d.asctime -> string
6993
- * d.ctime -> string
7291
+ * asctime -> string
7292
+ *
7293
+ * Equivalent to #strftime with argument <tt>'%a %b %e %T %Y'</tt>
7294
+ * (or its {shorthand form}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Shorthand+Conversion+Specifiers]
7295
+ * <tt>'%c'</tt>):
7296
+ *
7297
+ * Date.new(2001, 2, 3).asctime # => "Sat Feb 3 00:00:00 2001"
6994
7298
  *
6995
- * Returns a string in asctime(3) format (but without "\n\0" at the
6996
- * end). This method is equivalent to strftime('%c').
7299
+ * See {asctime}[https://linux.die.net/man/3/asctime].
6997
7300
  *
6998
- * See also asctime(3) or ctime(3).
7301
+ * Date#ctime is an alias for Date#asctime.
6999
7302
  */
7000
7303
  static VALUE
7001
7304
  d_lite_asctime(VALUE self)
@@ -7005,10 +7308,15 @@ d_lite_asctime(VALUE self)
7005
7308
 
7006
7309
  /*
7007
7310
  * call-seq:
7008
- * d.iso8601 -> string
7009
- * d.xmlschema -> string
7311
+ * iso8601 -> string
7010
7312
  *
7011
- * This method is equivalent to strftime('%F').
7313
+ * Equivalent to #strftime with argument <tt>'%Y-%m-%d'</tt>
7314
+ * (or its {shorthand form}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Shorthand+Conversion+Specifiers]
7315
+ * <tt>'%F'</tt>);
7316
+ *
7317
+ * Date.new(2001, 2, 3).iso8601 # => "2001-02-03"
7318
+ *
7319
+ * Date#xmlschema is an alias for Date#iso8601.
7012
7320
  */
7013
7321
  static VALUE
7014
7322
  d_lite_iso8601(VALUE self)
@@ -7018,9 +7326,13 @@ d_lite_iso8601(VALUE self)
7018
7326
 
7019
7327
  /*
7020
7328
  * call-seq:
7021
- * d.rfc3339 -> string
7329
+ * rfc3339 -> string
7330
+ *
7331
+ * Equivalent to #strftime with argument <tt>'%FT%T%:z'</tt>;
7332
+ * see {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]:
7333
+ *
7334
+ * Date.new(2001, 2, 3).rfc3339 # => "2001-02-03T00:00:00+00:00"
7022
7335
  *
7023
- * This method is equivalent to strftime('%FT%T%:z').
7024
7336
  */
7025
7337
  static VALUE
7026
7338
  d_lite_rfc3339(VALUE self)
@@ -7030,10 +7342,14 @@ d_lite_rfc3339(VALUE self)
7030
7342
 
7031
7343
  /*
7032
7344
  * call-seq:
7033
- * d.rfc2822 -> string
7034
- * d.rfc822 -> string
7345
+ * rfc2822 -> string
7346
+ *
7347
+ * Equivalent to #strftime with argument <tt>'%a, %-d %b %Y %T %z'</tt>;
7348
+ * see {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]:
7035
7349
  *
7036
- * This method is equivalent to strftime('%a, %-d %b %Y %T %z').
7350
+ * Date.new(2001, 2, 3).rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000"
7351
+ *
7352
+ * Date#rfc822 is an alias for Date#rfc2822.
7037
7353
  */
7038
7354
  static VALUE
7039
7355
  d_lite_rfc2822(VALUE self)
@@ -7043,10 +7359,13 @@ d_lite_rfc2822(VALUE self)
7043
7359
 
7044
7360
  /*
7045
7361
  * call-seq:
7046
- * d.httpdate -> string
7362
+ * httpdate -> string
7363
+ *
7364
+ * Equivalent to #strftime with argument <tt>'%a, %d %b %Y %T GMT'</tt>;
7365
+ * see {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]:
7366
+ *
7367
+ * Date.new(2001, 2, 3).httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT"
7047
7368
  *
7048
- * This method is equivalent to strftime('%a, %d %b %Y %T GMT').
7049
- * See also RFC 2616.
7050
7369
  */
7051
7370
  static VALUE
7052
7371
  d_lite_httpdate(VALUE self)
@@ -7097,11 +7416,13 @@ jisx0301_date_format(char *fmt, size_t size, VALUE jd, VALUE y)
7097
7416
 
7098
7417
  /*
7099
7418
  * call-seq:
7100
- * d.jisx0301 -> string
7419
+ * jisx0301 -> string
7101
7420
  *
7102
- * Returns a string in a JIS X 0301 format.
7421
+ * Returns a string representation of the date in +self+
7422
+ * in JIS X 0301 format.
7423
+ *
7424
+ * Date.new(2001, 2, 3).jisx0301 # => "H13.02.03"
7103
7425
  *
7104
- * Date.new(2001,2,3).jisx0301 #=> "H13.02.03"
7105
7426
  */
7106
7427
  static VALUE
7107
7428
  d_lite_jisx0301(VALUE self)
@@ -7116,7 +7437,98 @@ d_lite_jisx0301(VALUE self)
7116
7437
  return strftimev(fmt, self, set_tmx);
7117
7438
  }
7118
7439
 
7440
+ static VALUE
7441
+ deconstruct_keys(VALUE self, VALUE keys, int is_datetime)
7442
+ {
7443
+ VALUE h = rb_hash_new();
7444
+ long i;
7445
+
7446
+ get_d1(self);
7447
+
7448
+ if (NIL_P(keys)) {
7449
+ rb_hash_aset(h, sym_year, m_real_year(dat));
7450
+ rb_hash_aset(h, sym_month, INT2FIX(m_mon(dat)));
7451
+ rb_hash_aset(h, sym_day, INT2FIX(m_mday(dat)));
7452
+ rb_hash_aset(h, sym_yday, INT2FIX(m_yday(dat)));
7453
+ rb_hash_aset(h, sym_wday, INT2FIX(m_wday(dat)));
7454
+ if (is_datetime) {
7455
+ rb_hash_aset(h, sym_hour, INT2FIX(m_hour(dat)));
7456
+ rb_hash_aset(h, sym_min, INT2FIX(m_min(dat)));
7457
+ rb_hash_aset(h, sym_sec, INT2FIX(m_sec(dat)));
7458
+ rb_hash_aset(h, sym_sec_fraction, m_sf_in_sec(dat));
7459
+ rb_hash_aset(h, sym_zone, m_zone(dat));
7460
+ }
7461
+
7462
+ return h;
7463
+ }
7464
+ if (!RB_TYPE_P(keys, T_ARRAY)) {
7465
+ rb_raise(rb_eTypeError,
7466
+ "wrong argument type %"PRIsVALUE" (expected Array or nil)",
7467
+ rb_obj_class(keys));
7468
+
7469
+ }
7470
+
7471
+ for (i=0; i<RARRAY_LEN(keys); i++) {
7472
+ VALUE key = RARRAY_AREF(keys, i);
7473
+
7474
+ if (sym_year == key) rb_hash_aset(h, key, m_real_year(dat));
7475
+ if (sym_month == key) rb_hash_aset(h, key, INT2FIX(m_mon(dat)));
7476
+ if (sym_day == key) rb_hash_aset(h, key, INT2FIX(m_mday(dat)));
7477
+ if (sym_yday == key) rb_hash_aset(h, key, INT2FIX(m_yday(dat)));
7478
+ if (sym_wday == key) rb_hash_aset(h, key, INT2FIX(m_wday(dat)));
7479
+ if (is_datetime) {
7480
+ if (sym_hour == key) rb_hash_aset(h, key, INT2FIX(m_hour(dat)));
7481
+ if (sym_min == key) rb_hash_aset(h, key, INT2FIX(m_min(dat)));
7482
+ if (sym_sec == key) rb_hash_aset(h, key, INT2FIX(m_sec(dat)));
7483
+ if (sym_sec_fraction == key) rb_hash_aset(h, key, m_sf_in_sec(dat));
7484
+ if (sym_zone == key) rb_hash_aset(h, key, m_zone(dat));
7485
+ }
7486
+ }
7487
+ return h;
7488
+ }
7489
+
7490
+ /*
7491
+ * call-seq:
7492
+ * deconstruct_keys(array_of_names_or_nil) -> hash
7493
+ *
7494
+ * Returns a hash of the name/value pairs, to use in pattern matching.
7495
+ * Possible keys are: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
7496
+ * <tt>:wday</tt>, <tt>:yday</tt>.
7497
+ *
7498
+ * Possible usages:
7499
+ *
7500
+ * d = Date.new(2022, 10, 5)
7501
+ *
7502
+ * if d in wday: 3, day: ..7 # uses deconstruct_keys underneath
7503
+ * puts "first Wednesday of the month"
7504
+ * end
7505
+ * #=> prints "first Wednesday of the month"
7506
+ *
7507
+ * case d
7508
+ * in year: ...2022
7509
+ * puts "too old"
7510
+ * in month: ..9
7511
+ * puts "quarter 1-3"
7512
+ * in wday: 1..5, month:
7513
+ * puts "working day in month #{month}"
7514
+ * end
7515
+ * #=> prints "working day in month 10"
7516
+ *
7517
+ * Note that deconstruction by pattern can also be combined with class check:
7518
+ *
7519
+ * if d in Date(wday: 3, day: ..7)
7520
+ * puts "first Wednesday of the month"
7521
+ * end
7522
+ *
7523
+ */
7524
+ static VALUE
7525
+ d_lite_deconstruct_keys(VALUE self, VALUE keys)
7526
+ {
7527
+ return deconstruct_keys(self, keys, /* is_datetime=false */ 0);
7528
+ }
7529
+
7119
7530
  #ifndef NDEBUG
7531
+ /* :nodoc: */
7120
7532
  static VALUE
7121
7533
  d_lite_marshal_dump_old(VALUE self)
7122
7534
  {
@@ -7404,17 +7816,7 @@ datetime_s_ordinal(int argc, VALUE *argv, VALUE klass)
7404
7816
  }
7405
7817
 
7406
7818
  /*
7407
- * call-seq:
7408
- * DateTime.civil([year=-4712[, month=1[, mday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) -> datetime
7409
- * DateTime.new([year=-4712[, month=1[, mday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) -> datetime
7410
- *
7411
- * Creates a DateTime object denoting the given calendar date.
7412
- *
7413
- * DateTime.new(2001,2,3) #=> #<DateTime: 2001-02-03T00:00:00+00:00 ...>
7414
- * DateTime.new(2001,2,3,4,5,6,'+7')
7415
- * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
7416
- * DateTime.new(2001,-11,-26,-20,-55,-54,'+7')
7417
- * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
7819
+ * Same as DateTime.new.
7418
7820
  */
7419
7821
  static VALUE
7420
7822
  datetime_s_civil(int argc, VALUE *argv, VALUE klass)
@@ -7604,6 +8006,7 @@ datetime_s_commercial(int argc, VALUE *argv, VALUE klass)
7604
8006
  }
7605
8007
 
7606
8008
  #ifndef NDEBUG
8009
+ /* :nodoc: */
7607
8010
  static VALUE
7608
8011
  datetime_s_weeknum(int argc, VALUE *argv, VALUE klass)
7609
8012
  {
@@ -7673,6 +8076,7 @@ datetime_s_weeknum(int argc, VALUE *argv, VALUE klass)
7673
8076
  return ret;
7674
8077
  }
7675
8078
 
8079
+ /* :nodoc: */
7676
8080
  static VALUE
7677
8081
  datetime_s_nth_kday(int argc, VALUE *argv, VALUE klass)
7678
8082
  {
@@ -8013,14 +8417,14 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
8013
8417
 
8014
8418
  /*
8015
8419
  * call-seq:
8016
- * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]]) -> datetime
8420
+ * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]], limit: 128) -> datetime
8017
8421
  *
8018
8422
  * Parses the given representation of date and time, and creates a
8019
8423
  * DateTime object.
8020
8424
  *
8021
- * This method *does not* function as a validator. If the input
8425
+ * This method *does* *not* function as a validator. If the input
8022
8426
  * string does not match valid formats strictly, you may get a cryptic
8023
- * result. Should consider to use `DateTime.strptime` instead of this
8427
+ * result. Should consider to use DateTime.strptime instead of this
8024
8428
  * method as possible.
8025
8429
  *
8026
8430
  * If the optional second argument is true and the detected year is in
@@ -8032,13 +8436,18 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
8032
8436
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8033
8437
  * DateTime.parse('3rd Feb 2001 04:05:06 PM')
8034
8438
  * #=> #<DateTime: 2001-02-03T16:05:06+00:00 ...>
8439
+ *
8440
+ * Raise an ArgumentError when the string length is longer than _limit_.
8441
+ * You can stop this check by passing <code>limit: nil</code>, but note
8442
+ * that it may take a long time to parse.
8035
8443
  */
8036
8444
  static VALUE
8037
8445
  datetime_s_parse(int argc, VALUE *argv, VALUE klass)
8038
8446
  {
8039
- VALUE str, comp, sg;
8447
+ VALUE str, comp, sg, opt;
8040
8448
 
8041
- rb_scan_args(argc, argv, "03", &str, &comp, &sg);
8449
+ rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
8450
+ if (!NIL_P(opt)) argc--;
8042
8451
 
8043
8452
  switch (argc) {
8044
8453
  case 0:
@@ -8050,18 +8459,20 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
8050
8459
  }
8051
8460
 
8052
8461
  {
8053
- VALUE argv2[2], hash;
8054
-
8055
- argv2[0] = str;
8056
- argv2[1] = comp;
8057
- hash = date_s__parse(2, argv2, klass);
8462
+ int argc2 = 2;
8463
+ VALUE argv2[3], hash;
8464
+ argv2[0] = str;
8465
+ argv2[1] = comp;
8466
+ argv2[2] = opt;
8467
+ if (!NIL_P(opt)) argc2++;
8468
+ hash = date_s__parse(argc2, argv2, klass);
8058
8469
  return dt_new_by_frags(klass, hash, sg);
8059
8470
  }
8060
8471
  }
8061
8472
 
8062
8473
  /*
8063
8474
  * call-seq:
8064
- * DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
8475
+ * DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
8065
8476
  *
8066
8477
  * Creates a new DateTime object by parsing from a string according to
8067
8478
  * some typical ISO 8601 formats.
@@ -8072,13 +8483,18 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
8072
8483
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8073
8484
  * DateTime.iso8601('2001-W05-6T04:05:06+07:00')
8074
8485
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8486
+ *
8487
+ * Raise an ArgumentError when the string length is longer than _limit_.
8488
+ * You can stop this check by passing <code>limit: nil</code>, but note
8489
+ * that it may take a long time to parse.
8075
8490
  */
8076
8491
  static VALUE
8077
8492
  datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
8078
8493
  {
8079
- VALUE str, sg;
8494
+ VALUE str, sg, opt;
8080
8495
 
8081
- rb_scan_args(argc, argv, "02", &str, &sg);
8496
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8497
+ if (!NIL_P(opt)) argc--;
8082
8498
 
8083
8499
  switch (argc) {
8084
8500
  case 0:
@@ -8088,27 +8504,37 @@ datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
8088
8504
  }
8089
8505
 
8090
8506
  {
8091
- VALUE hash = date_s__iso8601(klass, str);
8507
+ int argc2 = 1;
8508
+ VALUE argv2[2], hash;
8509
+ argv2[0] = str;
8510
+ argv2[1] = opt;
8511
+ if (!NIL_P(opt)) argc2--;
8512
+ hash = date_s__iso8601(argc2, argv2, klass);
8092
8513
  return dt_new_by_frags(klass, hash, sg);
8093
8514
  }
8094
8515
  }
8095
8516
 
8096
8517
  /*
8097
8518
  * call-seq:
8098
- * DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
8519
+ * DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
8099
8520
  *
8100
8521
  * Creates a new DateTime object by parsing from a string according to
8101
8522
  * some typical RFC 3339 formats.
8102
8523
  *
8103
8524
  * DateTime.rfc3339('2001-02-03T04:05:06+07:00')
8104
8525
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8526
+ *
8527
+ * Raise an ArgumentError when the string length is longer than _limit_.
8528
+ * You can stop this check by passing <code>limit: nil</code>, but note
8529
+ * that it may take a long time to parse.
8105
8530
  */
8106
8531
  static VALUE
8107
8532
  datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
8108
8533
  {
8109
- VALUE str, sg;
8534
+ VALUE str, sg, opt;
8110
8535
 
8111
- rb_scan_args(argc, argv, "02", &str, &sg);
8536
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8537
+ if (!NIL_P(opt)) argc--;
8112
8538
 
8113
8539
  switch (argc) {
8114
8540
  case 0:
@@ -8118,27 +8544,37 @@ datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
8118
8544
  }
8119
8545
 
8120
8546
  {
8121
- VALUE hash = date_s__rfc3339(klass, str);
8547
+ int argc2 = 1;
8548
+ VALUE argv2[2], hash;
8549
+ argv2[0] = str;
8550
+ argv2[1] = opt;
8551
+ if (!NIL_P(opt)) argc2++;
8552
+ hash = date_s__rfc3339(argc2, argv2, klass);
8122
8553
  return dt_new_by_frags(klass, hash, sg);
8123
8554
  }
8124
8555
  }
8125
8556
 
8126
8557
  /*
8127
8558
  * call-seq:
8128
- * DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
8559
+ * DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
8129
8560
  *
8130
8561
  * Creates a new DateTime object by parsing from a string according to
8131
8562
  * some typical XML Schema formats.
8132
8563
  *
8133
8564
  * DateTime.xmlschema('2001-02-03T04:05:06+07:00')
8134
8565
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8566
+ *
8567
+ * Raise an ArgumentError when the string length is longer than _limit_.
8568
+ * You can stop this check by passing <code>limit: nil</code>, but note
8569
+ * that it may take a long time to parse.
8135
8570
  */
8136
8571
  static VALUE
8137
8572
  datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
8138
8573
  {
8139
- VALUE str, sg;
8574
+ VALUE str, sg, opt;
8140
8575
 
8141
- rb_scan_args(argc, argv, "02", &str, &sg);
8576
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8577
+ if (!NIL_P(opt)) argc--;
8142
8578
 
8143
8579
  switch (argc) {
8144
8580
  case 0:
@@ -8148,28 +8584,38 @@ datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
8148
8584
  }
8149
8585
 
8150
8586
  {
8151
- VALUE hash = date_s__xmlschema(klass, str);
8587
+ int argc2 = 1;
8588
+ VALUE argv2[2], hash;
8589
+ argv2[0] = str;
8590
+ argv2[1] = opt;
8591
+ if (!NIL_P(opt)) argc2++;
8592
+ hash = date_s__xmlschema(argc2, argv2, klass);
8152
8593
  return dt_new_by_frags(klass, hash, sg);
8153
8594
  }
8154
8595
  }
8155
8596
 
8156
8597
  /*
8157
8598
  * call-seq:
8158
- * DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> datetime
8159
- * DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY]) -> datetime
8599
+ * DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime
8600
+ * DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime
8160
8601
  *
8161
8602
  * Creates a new DateTime object by parsing from a string according to
8162
8603
  * some typical RFC 2822 formats.
8163
8604
  *
8164
8605
  * DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700')
8165
8606
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8607
+ *
8608
+ * Raise an ArgumentError when the string length is longer than _limit_.
8609
+ * You can stop this check by passing <code>limit: nil</code>, but note
8610
+ * that it may take a long time to parse.
8166
8611
  */
8167
8612
  static VALUE
8168
8613
  datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
8169
8614
  {
8170
- VALUE str, sg;
8615
+ VALUE str, sg, opt;
8171
8616
 
8172
- rb_scan_args(argc, argv, "02", &str, &sg);
8617
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8618
+ if (!NIL_P(opt)) argc--;
8173
8619
 
8174
8620
  switch (argc) {
8175
8621
  case 0:
@@ -8179,7 +8625,12 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
8179
8625
  }
8180
8626
 
8181
8627
  {
8182
- VALUE hash = date_s__rfc2822(klass, str);
8628
+ int argc2 = 1;
8629
+ VALUE argv2[2], hash;
8630
+ argv2[0] = str;
8631
+ argv2[1] = opt;
8632
+ if (!NIL_P(opt)) argc2++;
8633
+ hash = date_s__rfc2822(argc2, argv2, klass);
8183
8634
  return dt_new_by_frags(klass, hash, sg);
8184
8635
  }
8185
8636
  }
@@ -8193,13 +8644,18 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
8193
8644
  *
8194
8645
  * DateTime.httpdate('Sat, 03 Feb 2001 04:05:06 GMT')
8195
8646
  * #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>
8647
+ *
8648
+ * Raise an ArgumentError when the string length is longer than _limit_.
8649
+ * You can stop this check by passing <code>limit: nil</code>, but note
8650
+ * that it may take a long time to parse.
8196
8651
  */
8197
8652
  static VALUE
8198
8653
  datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
8199
8654
  {
8200
- VALUE str, sg;
8655
+ VALUE str, sg, opt;
8201
8656
 
8202
- rb_scan_args(argc, argv, "02", &str, &sg);
8657
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8658
+ if (!NIL_P(opt)) argc--;
8203
8659
 
8204
8660
  switch (argc) {
8205
8661
  case 0:
@@ -8209,14 +8665,19 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
8209
8665
  }
8210
8666
 
8211
8667
  {
8212
- VALUE hash = date_s__httpdate(klass, str);
8668
+ int argc2 = 1;
8669
+ VALUE argv2[2], hash;
8670
+ argv2[0] = str;
8671
+ argv2[1] = opt;
8672
+ if (!NIL_P(opt)) argc2++;
8673
+ hash = date_s__httpdate(argc2, argv2, klass);
8213
8674
  return dt_new_by_frags(klass, hash, sg);
8214
8675
  }
8215
8676
  }
8216
8677
 
8217
8678
  /*
8218
8679
  * call-seq:
8219
- * DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY]) -> datetime
8680
+ * DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime
8220
8681
  *
8221
8682
  * Creates a new DateTime object by parsing from a string according to
8222
8683
  * some typical JIS X 0301 formats.
@@ -8228,13 +8689,18 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
8228
8689
  *
8229
8690
  * DateTime.jisx0301('13.02.03T04:05:06+07:00')
8230
8691
  * #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
8692
+ *
8693
+ * Raise an ArgumentError when the string length is longer than _limit_.
8694
+ * You can stop this check by passing <code>limit: nil</code>, but note
8695
+ * that it may take a long time to parse.
8231
8696
  */
8232
8697
  static VALUE
8233
8698
  datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
8234
8699
  {
8235
- VALUE str, sg;
8700
+ VALUE str, sg, opt;
8236
8701
 
8237
- rb_scan_args(argc, argv, "02", &str, &sg);
8702
+ rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
8703
+ if (!NIL_P(opt)) argc--;
8238
8704
 
8239
8705
  switch (argc) {
8240
8706
  case 0:
@@ -8244,7 +8710,12 @@ datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
8244
8710
  }
8245
8711
 
8246
8712
  {
8247
- VALUE hash = date_s__jisx0301(klass, str);
8713
+ int argc2 = 1;
8714
+ VALUE argv2[2], hash;
8715
+ argv2[0] = str;
8716
+ argv2[1] = opt;
8717
+ if (!NIL_P(opt)) argc2++;
8718
+ hash = date_s__jisx0301(argc2, argv2, klass);
8248
8719
  return dt_new_by_frags(klass, hash, sg);
8249
8720
  }
8250
8721
  }
@@ -8267,181 +8738,16 @@ dt_lite_to_s(VALUE self)
8267
8738
 
8268
8739
  /*
8269
8740
  * call-seq:
8270
- * dt.strftime([format='%FT%T%:z']) -> string
8271
- *
8272
- * Formats date according to the directives in the given format
8273
- * string.
8274
- * The directives begin with a percent (%) character.
8275
- * Any text not listed as a directive will be passed through to the
8276
- * output string.
8277
- *
8278
- * A directive consists of a percent (%) character,
8279
- * zero or more flags, an optional minimum field width,
8280
- * an optional modifier, and a conversion specifier
8281
- * as follows.
8282
- *
8283
- * %<flags><width><modifier><conversion>
8284
- *
8285
- * Flags:
8286
- * - don't pad a numerical output.
8287
- * _ use spaces for padding.
8288
- * 0 use zeros for padding.
8289
- * ^ upcase the result string.
8290
- * # change case.
8291
- * : use colons for %z.
8292
- *
8293
- * The minimum field width specifies the minimum width.
8294
- *
8295
- * The modifiers are "E" and "O".
8296
- * They are ignored.
8297
- *
8298
- * Format directives:
8299
- *
8300
- * Date (Year, Month, Day):
8301
- * %Y - Year with century (can be negative, 4 digits at least)
8302
- * -0001, 0000, 1995, 2009, 14292, etc.
8303
- * %C - year / 100 (round down. 20 in 2009)
8304
- * %y - year % 100 (00..99)
8305
- *
8306
- * %m - Month of the year, zero-padded (01..12)
8307
- * %_m blank-padded ( 1..12)
8308
- * %-m no-padded (1..12)
8309
- * %B - The full month name (``January'')
8310
- * %^B uppercased (``JANUARY'')
8311
- * %b - The abbreviated month name (``Jan'')
8312
- * %^b uppercased (``JAN'')
8313
- * %h - Equivalent to %b
8314
- *
8315
- * %d - Day of the month, zero-padded (01..31)
8316
- * %-d no-padded (1..31)
8317
- * %e - Day of the month, blank-padded ( 1..31)
8318
- *
8319
- * %j - Day of the year (001..366)
8320
- *
8321
- * Time (Hour, Minute, Second, Subsecond):
8322
- * %H - Hour of the day, 24-hour clock, zero-padded (00..23)
8323
- * %k - Hour of the day, 24-hour clock, blank-padded ( 0..23)
8324
- * %I - Hour of the day, 12-hour clock, zero-padded (01..12)
8325
- * %l - Hour of the day, 12-hour clock, blank-padded ( 1..12)
8326
- * %P - Meridian indicator, lowercase (``am'' or ``pm'')
8327
- * %p - Meridian indicator, uppercase (``AM'' or ``PM'')
8328
- *
8329
- * %M - Minute of the hour (00..59)
8330
- *
8331
- * %S - Second of the minute (00..60)
8332
- *
8333
- * %L - Millisecond of the second (000..999)
8334
- * %N - Fractional seconds digits, default is 9 digits (nanosecond)
8335
- * %3N millisecond (3 digits) %15N femtosecond (15 digits)
8336
- * %6N microsecond (6 digits) %18N attosecond (18 digits)
8337
- * %9N nanosecond (9 digits) %21N zeptosecond (21 digits)
8338
- * %12N picosecond (12 digits) %24N yoctosecond (24 digits)
8339
- *
8340
- * Time zone:
8341
- * %z - Time zone as hour and minute offset from UTC (e.g. +0900)
8342
- * %:z - hour and minute offset from UTC with a colon (e.g. +09:00)
8343
- * %::z - hour, minute and second offset from UTC (e.g. +09:00:00)
8344
- * %:::z - hour, minute and second offset from UTC
8345
- * (e.g. +09, +09:30, +09:30:30)
8346
- * %Z - Equivalent to %:z (e.g. +09:00)
8347
- *
8348
- * Weekday:
8349
- * %A - The full weekday name (``Sunday'')
8350
- * %^A uppercased (``SUNDAY'')
8351
- * %a - The abbreviated name (``Sun'')
8352
- * %^a uppercased (``SUN'')
8353
- * %u - Day of the week (Monday is 1, 1..7)
8354
- * %w - Day of the week (Sunday is 0, 0..6)
8355
- *
8356
- * ISO 8601 week-based year and week number:
8357
- * The week 1 of YYYY starts with a Monday and includes YYYY-01-04.
8358
- * The days in the year before the first week are in the last week of
8359
- * the previous year.
8360
- * %G - The week-based year
8361
- * %g - The last 2 digits of the week-based year (00..99)
8362
- * %V - Week number of the week-based year (01..53)
8363
- *
8364
- * Week number:
8365
- * The week 1 of YYYY starts with a Sunday or Monday (according to %U
8366
- * or %W). The days in the year before the first week are in week 0.
8367
- * %U - Week number of the year. The week starts with Sunday. (00..53)
8368
- * %W - Week number of the year. The week starts with Monday. (00..53)
8369
- *
8370
- * Seconds since the Unix Epoch:
8371
- * %s - Number of seconds since 1970-01-01 00:00:00 UTC.
8372
- * %Q - Number of milliseconds since 1970-01-01 00:00:00 UTC.
8373
- *
8374
- * Literal string:
8375
- * %n - Newline character (\n)
8376
- * %t - Tab character (\t)
8377
- * %% - Literal ``%'' character
8378
- *
8379
- * Combination:
8380
- * %c - date and time (%a %b %e %T %Y)
8381
- * %D - Date (%m/%d/%y)
8382
- * %F - The ISO 8601 date format (%Y-%m-%d)
8383
- * %v - VMS date (%e-%^b-%Y)
8384
- * %x - Same as %D
8385
- * %X - Same as %T
8386
- * %r - 12-hour time (%I:%M:%S %p)
8387
- * %R - 24-hour time (%H:%M)
8388
- * %T - 24-hour time (%H:%M:%S)
8389
- * %+ - date(1) (%a %b %e %H:%M:%S %Z %Y)
8390
- *
8391
- * This method is similar to the strftime() function defined in ISO C
8392
- * and POSIX.
8393
- * Several directives (%a, %A, %b, %B, %c, %p, %r, %x, %X, %E*, %O* and %Z)
8394
- * are locale dependent in the function.
8395
- * However, this method is locale independent.
8396
- * So, the result may differ even if the same format string is used in other
8397
- * systems such as C.
8398
- * It is good practice to avoid %x and %X because there are corresponding
8399
- * locale independent representations, %D and %T.
8400
- *
8401
- * Examples:
8402
- *
8403
- * d = DateTime.new(2007,11,19,8,37,48,"-06:00")
8404
- * #=> #<DateTime: 2007-11-19T08:37:48-0600 ...>
8405
- * d.strftime("Printed on %m/%d/%Y") #=> "Printed on 11/19/2007"
8406
- * d.strftime("at %I:%M%p") #=> "at 08:37AM"
8407
- *
8408
- * Various ISO 8601 formats:
8409
- * %Y%m%d => 20071119 Calendar date (basic)
8410
- * %F => 2007-11-19 Calendar date (extended)
8411
- * %Y-%m => 2007-11 Calendar date, reduced accuracy, specific month
8412
- * %Y => 2007 Calendar date, reduced accuracy, specific year
8413
- * %C => 20 Calendar date, reduced accuracy, specific century
8414
- * %Y%j => 2007323 Ordinal date (basic)
8415
- * %Y-%j => 2007-323 Ordinal date (extended)
8416
- * %GW%V%u => 2007W471 Week date (basic)
8417
- * %G-W%V-%u => 2007-W47-1 Week date (extended)
8418
- * %GW%V => 2007W47 Week date, reduced accuracy, specific week (basic)
8419
- * %G-W%V => 2007-W47 Week date, reduced accuracy, specific week (extended)
8420
- * %H%M%S => 083748 Local time (basic)
8421
- * %T => 08:37:48 Local time (extended)
8422
- * %H%M => 0837 Local time, reduced accuracy, specific minute (basic)
8423
- * %H:%M => 08:37 Local time, reduced accuracy, specific minute (extended)
8424
- * %H => 08 Local time, reduced accuracy, specific hour
8425
- * %H%M%S,%L => 083748,000 Local time with decimal fraction, comma as decimal sign (basic)
8426
- * %T,%L => 08:37:48,000 Local time with decimal fraction, comma as decimal sign (extended)
8427
- * %H%M%S.%L => 083748.000 Local time with decimal fraction, full stop as decimal sign (basic)
8428
- * %T.%L => 08:37:48.000 Local time with decimal fraction, full stop as decimal sign (extended)
8429
- * %H%M%S%z => 083748-0600 Local time and the difference from UTC (basic)
8430
- * %T%:z => 08:37:48-06:00 Local time and the difference from UTC (extended)
8431
- * %Y%m%dT%H%M%S%z => 20071119T083748-0600 Date and time of day for calendar date (basic)
8432
- * %FT%T%:z => 2007-11-19T08:37:48-06:00 Date and time of day for calendar date (extended)
8433
- * %Y%jT%H%M%S%z => 2007323T083748-0600 Date and time of day for ordinal date (basic)
8434
- * %Y-%jT%T%:z => 2007-323T08:37:48-06:00 Date and time of day for ordinal date (extended)
8435
- * %GW%V%uT%H%M%S%z => 2007W471T083748-0600 Date and time of day for week date (basic)
8436
- * %G-W%V-%uT%T%:z => 2007-W47-1T08:37:48-06:00 Date and time of day for week date (extended)
8437
- * %Y%m%dT%H%M => 20071119T0837 Calendar date and local time (basic)
8438
- * %FT%R => 2007-11-19T08:37 Calendar date and local time (extended)
8439
- * %Y%jT%H%MZ => 2007323T0837Z Ordinal date and UTC of day (basic)
8440
- * %Y-%jT%RZ => 2007-323T08:37Z Ordinal date and UTC of day (extended)
8441
- * %GW%V%uT%H%M%z => 2007W471T0837-0600 Week date and local time and difference from UTC (basic)
8442
- * %G-W%V-%uT%R%:z => 2007-W47-1T08:37-06:00 Week date and local time and difference from UTC (extended)
8443
- *
8444
- * See also strftime(3) and ::strptime.
8741
+ * strftime(format = '%FT%T%:z') -> string
8742
+ *
8743
+ * Returns a string representation of +self+,
8744
+ * formatted according the given +format:
8745
+ *
8746
+ * DateTime.now.strftime # => "2022-07-01T11:03:19-05:00"
8747
+ *
8748
+ * For other formats, see
8749
+ * {Formats for Dates and Times}[doc/strftime_formatting.rdoc].
8750
+ *
8445
8751
  */
8446
8752
  static VALUE
8447
8753
  dt_lite_strftime(int argc, VALUE *argv, VALUE self)
@@ -8529,6 +8835,47 @@ dt_lite_jisx0301(int argc, VALUE *argv, VALUE self)
8529
8835
  iso8601_timediv(self, n));
8530
8836
  }
8531
8837
 
8838
+ /*
8839
+ * call-seq:
8840
+ * deconstruct_keys(array_of_names_or_nil) -> hash
8841
+ *
8842
+ * Returns a hash of the name/value pairs, to use in pattern matching.
8843
+ * Possible keys are: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
8844
+ * <tt>:wday</tt>, <tt>:yday</tt>, <tt>:hour</tt>, <tt>:min</tt>,
8845
+ * <tt>:sec</tt>, <tt>:sec_fraction</tt>, <tt>:zone</tt>.
8846
+ *
8847
+ * Possible usages:
8848
+ *
8849
+ * dt = DateTime.new(2022, 10, 5, 13, 30)
8850
+ *
8851
+ * if d in wday: 1..5, hour: 10..18 # uses deconstruct_keys underneath
8852
+ * puts "Working time"
8853
+ * end
8854
+ * #=> prints "Working time"
8855
+ *
8856
+ * case dt
8857
+ * in year: ...2022
8858
+ * puts "too old"
8859
+ * in month: ..9
8860
+ * puts "quarter 1-3"
8861
+ * in wday: 1..5, month:
8862
+ * puts "working day in month #{month}"
8863
+ * end
8864
+ * #=> prints "working day in month 10"
8865
+ *
8866
+ * Note that deconstruction by pattern can also be combined with class check:
8867
+ *
8868
+ * if d in DateTime(wday: 1..5, hour: 10..18, day: ..7)
8869
+ * puts "Working time, first week of the month"
8870
+ * end
8871
+ *
8872
+ */
8873
+ static VALUE
8874
+ dt_lite_deconstruct_keys(VALUE self, VALUE keys)
8875
+ {
8876
+ return deconstruct_keys(self, keys, /* is_datetime=true */ 1);
8877
+ }
8878
+
8532
8879
  /* conversions */
8533
8880
 
8534
8881
  #define f_subsec(x) rb_funcall(x, rb_intern("subsec"), 0)
@@ -8607,7 +8954,7 @@ time_to_datetime(VALUE self)
8607
8954
  ret = d_complex_new_internal(cDateTime,
8608
8955
  nth, 0,
8609
8956
  0, sf,
8610
- of, DEFAULT_SG,
8957
+ of, GREGORIAN,
8611
8958
  ry, m, d,
8612
8959
  h, min, s,
8613
8960
  HAVE_CIVIL | HAVE_TIME);
@@ -8620,10 +8967,15 @@ time_to_datetime(VALUE self)
8620
8967
 
8621
8968
  /*
8622
8969
  * call-seq:
8623
- * d.to_time -> time
8970
+ * to_time -> time
8971
+ *
8972
+ * Returns a new Time object with the same value as +self+;
8973
+ * if +self+ is a Julian date, derives its Gregorian date
8974
+ * for conversion to the \Time object:
8975
+ *
8976
+ * Date.new(2001, 2, 3).to_time # => 2001-02-03 00:00:00 -0600
8977
+ * Date.new(2001, 2, 3, Date::JULIAN).to_time # => 2001-02-16 00:00:00 -0600
8624
8978
  *
8625
- * Returns a Time object which denotes self. If self is a julian date,
8626
- * convert it to a gregorian date before converting it to Time.
8627
8979
  */
8628
8980
  static VALUE
8629
8981
  date_to_time(VALUE self)
@@ -8644,9 +8996,9 @@ date_to_time(VALUE self)
8644
8996
 
8645
8997
  /*
8646
8998
  * call-seq:
8647
- * d.to_date -> self
8999
+ * to_date -> self
8648
9000
  *
8649
- * Returns self.
9001
+ * Returns +self+.
8650
9002
  */
8651
9003
  static VALUE
8652
9004
  date_to_date(VALUE self)
@@ -8658,7 +9010,10 @@ date_to_date(VALUE self)
8658
9010
  * call-seq:
8659
9011
  * d.to_datetime -> datetime
8660
9012
  *
8661
- * Returns a DateTime object which denotes self.
9013
+ * Returns a DateTime whose value is the same as +self+:
9014
+ *
9015
+ * Date.new(2001, 2, 3).to_datetime # => #<DateTime: 2001-02-03T00:00:00+00:00>
9016
+ *
8662
9017
  */
8663
9018
  static VALUE
8664
9019
  date_to_datetime(VALUE self)
@@ -8703,12 +9058,17 @@ date_to_datetime(VALUE self)
8703
9058
  static VALUE
8704
9059
  datetime_to_time(VALUE self)
8705
9060
  {
8706
- volatile VALUE dup = dup_obj(self);
9061
+ get_d1(self);
9062
+
9063
+ if (m_julian_p(dat)) {
9064
+ self = d_lite_gregorian(self);
9065
+ get_d1a(self);
9066
+ dat = adat;
9067
+ }
9068
+
8707
9069
  {
8708
9070
  VALUE t;
8709
9071
 
8710
- get_d1(dup);
8711
-
8712
9072
  t = rb_funcall(rb_cTime,
8713
9073
  rb_intern("new"),
8714
9074
  7,
@@ -8776,6 +9136,7 @@ datetime_to_datetime(VALUE self)
8776
9136
  #define MIN_JD -327
8777
9137
  #define MAX_JD 366963925
8778
9138
 
9139
+ /* :nodoc: */
8779
9140
  static int
8780
9141
  test_civil(int from, int to, double sg)
8781
9142
  {
@@ -8796,6 +9157,7 @@ test_civil(int from, int to, double sg)
8796
9157
  return 1;
8797
9158
  }
8798
9159
 
9160
+ /* :nodoc: */
8799
9161
  static VALUE
8800
9162
  date_s_test_civil(VALUE klass)
8801
9163
  {
@@ -8816,6 +9178,7 @@ date_s_test_civil(VALUE klass)
8816
9178
  return Qtrue;
8817
9179
  }
8818
9180
 
9181
+ /* :nodoc: */
8819
9182
  static int
8820
9183
  test_ordinal(int from, int to, double sg)
8821
9184
  {
@@ -8836,6 +9199,7 @@ test_ordinal(int from, int to, double sg)
8836
9199
  return 1;
8837
9200
  }
8838
9201
 
9202
+ /* :nodoc: */
8839
9203
  static VALUE
8840
9204
  date_s_test_ordinal(VALUE klass)
8841
9205
  {
@@ -8856,6 +9220,7 @@ date_s_test_ordinal(VALUE klass)
8856
9220
  return Qtrue;
8857
9221
  }
8858
9222
 
9223
+ /* :nodoc: */
8859
9224
  static int
8860
9225
  test_commercial(int from, int to, double sg)
8861
9226
  {
@@ -8876,6 +9241,7 @@ test_commercial(int from, int to, double sg)
8876
9241
  return 1;
8877
9242
  }
8878
9243
 
9244
+ /* :nodoc: */
8879
9245
  static VALUE
8880
9246
  date_s_test_commercial(VALUE klass)
8881
9247
  {
@@ -8896,6 +9262,7 @@ date_s_test_commercial(VALUE klass)
8896
9262
  return Qtrue;
8897
9263
  }
8898
9264
 
9265
+ /* :nodoc: */
8899
9266
  static int
8900
9267
  test_weeknum(int from, int to, int f, double sg)
8901
9268
  {
@@ -8916,6 +9283,7 @@ test_weeknum(int from, int to, int f, double sg)
8916
9283
  return 1;
8917
9284
  }
8918
9285
 
9286
+ /* :nodoc: */
8919
9287
  static VALUE
8920
9288
  date_s_test_weeknum(VALUE klass)
8921
9289
  {
@@ -8940,6 +9308,7 @@ date_s_test_weeknum(VALUE klass)
8940
9308
  return Qtrue;
8941
9309
  }
8942
9310
 
9311
+ /* :nodoc: */
8943
9312
  static int
8944
9313
  test_nth_kday(int from, int to, double sg)
8945
9314
  {
@@ -8960,6 +9329,7 @@ test_nth_kday(int from, int to, double sg)
8960
9329
  return 1;
8961
9330
  }
8962
9331
 
9332
+ /* :nodoc: */
8963
9333
  static VALUE
8964
9334
  date_s_test_nth_kday(VALUE klass)
8965
9335
  {
@@ -8980,6 +9350,7 @@ date_s_test_nth_kday(VALUE klass)
8980
9350
  return Qtrue;
8981
9351
  }
8982
9352
 
9353
+ /* :nodoc: */
8983
9354
  static int
8984
9355
  test_unit_v2v(VALUE i,
8985
9356
  VALUE (* conv1)(VALUE),
@@ -8991,6 +9362,7 @@ test_unit_v2v(VALUE i,
8991
9362
  return f_eqeq_p(o, i);
8992
9363
  }
8993
9364
 
9365
+ /* :nodoc: */
8994
9366
  static int
8995
9367
  test_unit_v2v_iter2(VALUE (* conv1)(VALUE),
8996
9368
  VALUE (* conv2)(VALUE))
@@ -9022,6 +9394,7 @@ test_unit_v2v_iter2(VALUE (* conv1)(VALUE),
9022
9394
  return 1;
9023
9395
  }
9024
9396
 
9397
+ /* :nodoc: */
9025
9398
  static int
9026
9399
  test_unit_v2v_iter(VALUE (* conv1)(VALUE),
9027
9400
  VALUE (* conv2)(VALUE))
@@ -9033,6 +9406,7 @@ test_unit_v2v_iter(VALUE (* conv1)(VALUE),
9033
9406
  return 1;
9034
9407
  }
9035
9408
 
9409
+ /* :nodoc: */
9036
9410
  static VALUE
9037
9411
  date_s_test_unit_conv(VALUE klass)
9038
9412
  {
@@ -9047,6 +9421,7 @@ date_s_test_unit_conv(VALUE klass)
9047
9421
  return Qtrue;
9048
9422
  }
9049
9423
 
9424
+ /* :nodoc: */
9050
9425
  static VALUE
9051
9426
  date_s_test_all(VALUE klass)
9052
9427
  {
@@ -9113,6 +9488,7 @@ mk_ary_of_str(long len, const char *a[])
9113
9488
  return o;
9114
9489
  }
9115
9490
 
9491
+ /* :nodoc: */
9116
9492
  static VALUE
9117
9493
  d_lite_zero(VALUE x)
9118
9494
  {
@@ -9130,6 +9506,17 @@ Init_date_core(void)
9130
9506
  id_ge_p = rb_intern_const(">=");
9131
9507
  id_eqeq_p = rb_intern_const("==");
9132
9508
 
9509
+ sym_year = ID2SYM(rb_intern_const("year"));
9510
+ sym_month = ID2SYM(rb_intern_const("month"));
9511
+ sym_yday = ID2SYM(rb_intern_const("yday"));
9512
+ sym_wday = ID2SYM(rb_intern_const("wday"));
9513
+ sym_day = ID2SYM(rb_intern_const("day"));
9514
+ sym_hour = ID2SYM(rb_intern_const("hour"));
9515
+ sym_min = ID2SYM(rb_intern_const("min"));
9516
+ sym_sec = ID2SYM(rb_intern_const("sec"));
9517
+ sym_sec_fraction = ID2SYM(rb_intern_const("sec_fraction"));
9518
+ sym_zone = ID2SYM(rb_intern_const("zone"));
9519
+
9133
9520
  half_days_in_day = rb_rational_new2(INT2FIX(1), INT2FIX(2));
9134
9521
 
9135
9522
  #if (LONG_MAX / DAY_IN_SECONDS) > SECOND_IN_NANOSECONDS
@@ -9150,152 +9537,81 @@ Init_date_core(void)
9150
9537
  negative_inf = -INFINITY;
9151
9538
 
9152
9539
  /*
9153
- * date and datetime class - Tadayoshi Funaba 1998-2011
9154
- *
9155
- * 'date' provides two classes: Date and DateTime.
9540
+ * \Class \Date provides methods for storing and manipulating
9541
+ * calendar dates.
9156
9542
  *
9157
- * == Terms and Definitions
9543
+ * Consider using
9544
+ * {class Time}[https://docs.ruby-lang.org/en/master/Time.html]
9545
+ * instead of class \Date if:
9158
9546
  *
9159
- * Some terms and definitions are based on ISO 8601 and JIS X 0301.
9547
+ * - You need both dates and times; \Date handles only dates.
9548
+ * - You need only Gregorian dates (and not Julian dates);
9549
+ * see {Julian and Gregorian Calendars}[rdoc-ref:calendars.rdoc].
9160
9550
  *
9161
- * === Calendar Date
9551
+ * A \Date object, once created, is immutable, and cannot be modified.
9162
9552
  *
9163
- * The calendar date is a particular day of a calendar year,
9164
- * identified by its ordinal number within a calendar month within
9165
- * that year.
9553
+ * == Creating a \Date
9166
9554
  *
9167
- * In those classes, this is so-called "civil".
9555
+ * You can create a date for the current date, using Date.today:
9168
9556
  *
9169
- * === Ordinal Date
9557
+ * Date.today # => #<Date: 1999-12-31>
9170
9558
  *
9171
- * The ordinal date is a particular day of a calendar year identified
9172
- * by its ordinal number within the year.
9559
+ * You can create a specific date from various combinations of arguments:
9173
9560
  *
9174
- * In those classes, this is so-called "ordinal".
9561
+ * - Date.new takes integer year, month, and day-of-month:
9175
9562
  *
9176
- * === Week Date
9563
+ * Date.new(1999, 12, 31) # => #<Date: 1999-12-31>
9177
9564
  *
9178
- * The week date is a date identified by calendar week and day numbers.
9565
+ * - Date.ordinal takes integer year and day-of-year:
9179
9566
  *
9180
- * The calendar week is a seven day period within a calendar year,
9181
- * starting on a Monday and identified by its ordinal number within
9182
- * the year; the first calendar week of the year is the one that
9183
- * includes the first Thursday of that year. In the Gregorian
9184
- * calendar, this is equivalent to the week which includes January 4.
9567
+ * Date.ordinal(1999, 365) # => #<Date: 1999-12-31>
9185
9568
  *
9186
- * In those classes, this is so-called "commercial".
9569
+ * - Date.jd takes integer Julian day:
9187
9570
  *
9188
- * === Julian Day Number
9571
+ * Date.jd(2451544) # => #<Date: 1999-12-31>
9189
9572
  *
9190
- * The Julian day number is in elapsed days since noon (Greenwich Mean
9191
- * Time) on January 1, 4713 BCE (in the Julian calendar).
9573
+ * - Date.commercial takes integer commercial data (year, week, day-of-week):
9192
9574
  *
9193
- * In this document, the astronomical Julian day number is the same as
9194
- * the original Julian day number. And the chronological Julian day
9195
- * number is a variation of the Julian day number. Its days begin at
9196
- * midnight on local time.
9575
+ * Date.commercial(1999, 52, 5) # => #<Date: 1999-12-31>
9197
9576
  *
9198
- * In this document, when the term "Julian day number" simply appears,
9199
- * it just refers to "chronological Julian day number", not the
9200
- * original.
9577
+ * - Date.parse takes a string, which it parses heuristically:
9201
9578
  *
9202
- * In those classes, those are so-called "ajd" and "jd".
9579
+ * Date.parse('1999-12-31') # => #<Date: 1999-12-31>
9580
+ * Date.parse('31-12-1999') # => #<Date: 1999-12-31>
9581
+ * Date.parse('1999-365') # => #<Date: 1999-12-31>
9582
+ * Date.parse('1999-W52-5') # => #<Date: 1999-12-31>
9203
9583
  *
9204
- * === Modified Julian Day Number
9584
+ * - Date.strptime takes a date string and a format string,
9585
+ * then parses the date string according to the format string:
9205
9586
  *
9206
- * The modified Julian day number is in elapsed days since midnight
9207
- * (Coordinated Universal Time) on November 17, 1858 CE (in the
9208
- * Gregorian calendar).
9587
+ * Date.strptime('1999-12-31', '%Y-%m-%d') # => #<Date: 1999-12-31>
9588
+ * Date.strptime('31-12-1999', '%d-%m-%Y') # => #<Date: 1999-12-31>
9589
+ * Date.strptime('1999-365', '%Y-%j') # => #<Date: 1999-12-31>
9590
+ * Date.strptime('1999-W52-5', '%G-W%V-%u') # => #<Date: 1999-12-31>
9591
+ * Date.strptime('1999 52 5', '%Y %U %w') # => #<Date: 1999-12-31>
9592
+ * Date.strptime('1999 52 5', '%Y %W %u') # => #<Date: 1999-12-31>
9593
+ * Date.strptime('fri31dec99', '%a%d%b%y') # => #<Date: 1999-12-31>
9209
9594
  *
9210
- * In this document, the astronomical modified Julian day number is
9211
- * the same as the original modified Julian day number. And the
9212
- * chronological modified Julian day number is a variation of the
9213
- * modified Julian day number. Its days begin at midnight on local
9214
- * time.
9595
+ * See also the specialized methods in
9596
+ * {"Specialized Format Strings" in Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Specialized+Format+Strings]
9215
9597
  *
9216
- * In this document, when the term "modified Julian day number" simply
9217
- * appears, it just refers to "chronological modified Julian day
9218
- * number", not the original.
9219
- *
9220
- * In those classes, those are so-called "amjd" and "mjd".
9221
- *
9222
- * == Date
9223
- *
9224
- * A subclass of Object that includes the Comparable module and
9225
- * easily handles date.
9226
- *
9227
- * A Date object is created with Date::new, Date::jd, Date::ordinal,
9228
- * Date::commercial, Date::parse, Date::strptime, Date::today,
9229
- * Time#to_date, etc.
9230
- *
9231
- * require 'date'
9598
+ * == Argument +limit+
9232
9599
  *
9233
- * Date.new(2001,2,3)
9234
- * #=> #<Date: 2001-02-03 ...>
9235
- * Date.jd(2451944)
9236
- * #=> #<Date: 2001-02-03 ...>
9237
- * Date.ordinal(2001,34)
9238
- * #=> #<Date: 2001-02-03 ...>
9239
- * Date.commercial(2001,5,6)
9240
- * #=> #<Date: 2001-02-03 ...>
9241
- * Date.parse('2001-02-03')
9242
- * #=> #<Date: 2001-02-03 ...>
9243
- * Date.strptime('03-02-2001', '%d-%m-%Y')
9244
- * #=> #<Date: 2001-02-03 ...>
9245
- * Time.new(2001,2,3).to_date
9246
- * #=> #<Date: 2001-02-03 ...>
9600
+ * Certain singleton methods in \Date that parse string arguments
9601
+ * also take optional keyword argument +limit+,
9602
+ * which can limit the length of the string argument.
9247
9603
  *
9248
- * All date objects are immutable; hence cannot modify themselves.
9604
+ * When +limit+ is:
9249
9605
  *
9250
- * The concept of a date object can be represented as a tuple
9251
- * of the day count, the offset and the day of calendar reform.
9252
- *
9253
- * The day count denotes the absolute position of a temporal
9254
- * dimension. The offset is relative adjustment, which determines
9255
- * decoded local time with the day count. The day of calendar
9256
- * reform denotes the start day of the new style. The old style
9257
- * of the West is the Julian calendar which was adopted by
9258
- * Caesar. The new style is the Gregorian calendar, which is the
9259
- * current civil calendar of many countries.
9260
- *
9261
- * The day count is virtually the astronomical Julian day number.
9262
- * The offset in this class is usually zero, and cannot be
9263
- * specified directly.
9264
- *
9265
- * A Date object can be created with an optional argument,
9266
- * the day of calendar reform as a Julian day number, which
9267
- * should be 2298874 to 2426355 or negative/positive infinity.
9268
- * The default value is +Date::ITALY+ (2299161=1582-10-15).
9269
- * See also sample/cal.rb.
9270
- *
9271
- * $ ruby sample/cal.rb -c it 10 1582
9272
- * October 1582
9273
- * S M Tu W Th F S
9274
- * 1 2 3 4 15 16
9275
- * 17 18 19 20 21 22 23
9276
- * 24 25 26 27 28 29 30
9277
- * 31
9278
- *
9279
- * $ ruby sample/cal.rb -c gb 9 1752
9280
- * September 1752
9281
- * S M Tu W Th F S
9282
- * 1 2 14 15 16
9283
- * 17 18 19 20 21 22 23
9284
- * 24 25 26 27 28 29 30
9285
- *
9286
- * A Date object has various methods. See each reference.
9287
- *
9288
- * d = Date.parse('3rd Feb 2001')
9289
- * #=> #<Date: 2001-02-03 ...>
9290
- * d.year #=> 2001
9291
- * d.mon #=> 2
9292
- * d.mday #=> 3
9293
- * d.wday #=> 6
9294
- * d += 1 #=> #<Date: 2001-02-04 ...>
9295
- * d.strftime('%a %d %b %Y') #=> "Sun 04 Feb 2001"
9606
+ * - Non-negative:
9607
+ * raises ArgumentError if the string length is greater than _limit_.
9608
+ * - Other numeric or +nil+: ignores +limit+.
9609
+ * - Other non-numeric: raises TypeError.
9296
9610
  *
9297
9611
  */
9298
9612
  cDate = rb_define_class("Date", rb_cObject);
9613
+
9614
+ /* Exception for invalid date/time */
9299
9615
  eDateError = rb_define_class_under(cDate, "Error", rb_eArgError);
9300
9616
 
9301
9617
  rb_include_module(cDate, rb_mComparable);
@@ -9403,19 +9719,19 @@ Init_date_core(void)
9403
9719
  rb_define_singleton_method(cDate, "strptime", date_s_strptime, -1);
9404
9720
  rb_define_singleton_method(cDate, "_parse", date_s__parse, -1);
9405
9721
  rb_define_singleton_method(cDate, "parse", date_s_parse, -1);
9406
- rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, 1);
9722
+ rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, -1);
9407
9723
  rb_define_singleton_method(cDate, "iso8601", date_s_iso8601, -1);
9408
- rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, 1);
9724
+ rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, -1);
9409
9725
  rb_define_singleton_method(cDate, "rfc3339", date_s_rfc3339, -1);
9410
- rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, 1);
9726
+ rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, -1);
9411
9727
  rb_define_singleton_method(cDate, "xmlschema", date_s_xmlschema, -1);
9412
- rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, 1);
9413
- rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, 1);
9728
+ rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, -1);
9729
+ rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, -1);
9414
9730
  rb_define_singleton_method(cDate, "rfc2822", date_s_rfc2822, -1);
9415
9731
  rb_define_singleton_method(cDate, "rfc822", date_s_rfc2822, -1);
9416
- rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, 1);
9732
+ rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, -1);
9417
9733
  rb_define_singleton_method(cDate, "httpdate", date_s_httpdate, -1);
9418
- rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, 1);
9734
+ rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, -1);
9419
9735
  rb_define_singleton_method(cDate, "jisx0301", date_s_jisx0301, -1);
9420
9736
 
9421
9737
  rb_define_method(cDate, "initialize", date_initialize, -1);
@@ -9522,6 +9838,8 @@ Init_date_core(void)
9522
9838
  rb_define_method(cDate, "httpdate", d_lite_httpdate, 0);
9523
9839
  rb_define_method(cDate, "jisx0301", d_lite_jisx0301, 0);
9524
9840
 
9841
+ rb_define_method(cDate, "deconstruct_keys", d_lite_deconstruct_keys, 1);
9842
+
9525
9843
  #ifndef NDEBUG
9526
9844
  rb_define_method(cDate, "marshal_dump_old", d_lite_marshal_dump_old, 0);
9527
9845
  #endif
@@ -9732,6 +10050,8 @@ Init_date_core(void)
9732
10050
  rb_define_method(cDateTime, "rfc3339", dt_lite_rfc3339, -1);
9733
10051
  rb_define_method(cDateTime, "jisx0301", dt_lite_jisx0301, -1);
9734
10052
 
10053
+ rb_define_method(cDateTime, "deconstruct_keys", dt_lite_deconstruct_keys, 1);
10054
+
9735
10055
  /* conversions */
9736
10056
 
9737
10057
  rb_define_method(rb_cTime, "to_time", time_to_time, 0);