rubysl-date 1.0.1 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,12 @@
1
1
  #
2
2
  # date.rb - date and time library
3
3
  #
4
- # Author: Tadayoshi Funaba 1998-2006
4
+ # Author: Tadayoshi Funaba 1998-2011
5
5
  #
6
6
  # Documentation: William Webber <william@williamwebber.com>
7
7
  #
8
8
  #--
9
- # $Id: date.rb,v 2.30 2006-12-30 21:43:41+09 tadf Exp $
9
+ # $Id: date.rb,v 2.37 2008-01-17 20:16:31+09 tadf Exp $
10
10
  #++
11
11
  #
12
12
  # == Overview
@@ -193,7 +193,6 @@
193
193
  #
194
194
  # puts secs_to_new_year()
195
195
 
196
- require 'rational'
197
196
  require 'date/format'
198
197
 
199
198
  # Class representing a date.
@@ -235,7 +234,7 @@ class Date
235
234
  # month's numerical representation indexed into this array
236
235
  # gives the name of that month (hence the first element is nil).
237
236
  MONTHNAMES = [nil] + %w(January February March April May June July
238
- August September October November December)
237
+ August September October November December)
239
238
 
240
239
  # Full names of days of the week, in English. Days of the week
241
240
  # count from 0 to 6 (except in the commercial week); a day's numerical
@@ -244,13 +243,13 @@ class Date
244
243
 
245
244
  # Abbreviated month names, in English.
246
245
  ABBR_MONTHNAMES = [nil] + %w(Jan Feb Mar Apr May Jun
247
- Jul Aug Sep Oct Nov Dec)
246
+ Jul Aug Sep Oct Nov Dec)
248
247
 
249
248
  # Abbreviated day names, in English.
250
249
  ABBR_DAYNAMES = %w(Sun Mon Tue Wed Thu Fri Sat)
251
250
 
252
251
  [MONTHNAMES, DAYNAMES, ABBR_MONTHNAMES, ABBR_DAYNAMES].each do |xs|
253
- xs.each{|x| x.freeze if x}.freeze
252
+ xs.each{|x| x.freeze unless x.nil?}.freeze
254
253
  end
255
254
 
256
255
  class Infinity < Numeric # :nodoc:
@@ -278,11 +277,11 @@ class Date
278
277
  when Infinity; return d <=> other.d
279
278
  when Numeric; return d
280
279
  else
281
- begin
282
- l, r = other.coerce(self)
283
- return l <=> r
284
- rescue NoMethodError
285
- end
280
+ begin
281
+ l, r = other.coerce(self)
282
+ return l <=> r
283
+ rescue NoMethodError
284
+ end
286
285
  end
287
286
  nil
288
287
  end
@@ -291,7 +290,7 @@ class Date
291
290
  case other
292
291
  when Numeric; return -d, d
293
292
  else
294
- super
293
+ super
295
294
  end
296
295
  end
297
296
 
@@ -328,235 +327,394 @@ class Date
328
327
  UNIX_EPOCH_IN_CJD = 2440588 # :nodoc:
329
328
  LD_EPOCH_IN_CJD = 2299160 # :nodoc:
330
329
 
331
- # Does a given Julian Day Number fall inside the old-style (Julian)
332
- # calendar?
333
- #
334
- # +jd+ is the Julian Day Number in question. +sg+ may be Date::GREGORIAN,
335
- # in which case the answer is false; it may be Date::JULIAN, in which case
336
- # the answer is true; or it may a number representing the Day of
337
- # Calendar Reform. Date::ENGLAND and Date::ITALY are two possible such
338
- # days.
339
-
340
- def self.julian? (jd, sg)
341
- case sg
342
- when Numeric
343
- jd < sg
344
- else
345
- if $VERBOSE
346
- warn("#{caller.shift.sub(/:in .*/, '')}: " \
347
- "warning: do not use non-numerical object as julian day number anymore")
348
- end
349
- not sg
350
- end
351
- end
352
-
353
- # Does a given Julian Day Number fall inside the new-style (Gregorian)
354
- # calendar?
355
- #
356
- # The reverse of self.os? See the documentation for that method for
357
- # more details.
358
- def self.gregorian? (jd, sg) !julian?(jd, sg) end
330
+ t = Module.new do
359
331
 
360
- def self.fix_style(jd, sg) # :nodoc:
361
- if julian?(jd, sg)
362
- then JULIAN
363
- else GREGORIAN end
364
- end
332
+ private
365
333
 
366
- private_class_method :fix_style
334
+ def find_fdoy(y, sg) # :nodoc:
335
+ j = nil
336
+ 1.upto(31) do |d|
337
+ break if j = _valid_civil?(y, 1, d, sg)
338
+ end
339
+ j
340
+ end
367
341
 
368
- # Convert an Ordinal Date to a Julian Day Number.
369
- #
370
- # +y+ and +d+ are the year and day-of-year to convert.
371
- # +sg+ specifies the Day of Calendar Reform.
372
- #
373
- # Returns the corresponding Julian Day Number.
374
- def self.ordinal_to_jd(y, d, sg=GREGORIAN)
375
- civil_to_jd(y, 1, d, sg)
376
- end
342
+ def find_ldoy(y, sg) # :nodoc:
343
+ j = nil
344
+ 31.downto(1) do |d|
345
+ break if j = _valid_civil?(y, 12, d, sg)
346
+ end
347
+ j
348
+ end
377
349
 
378
- # Convert a Julian Day Number to an Ordinal Date.
379
- #
380
- # +jd+ is the Julian Day Number to convert.
381
- # +sg+ specifies the Day of Calendar Reform.
382
- #
383
- # Returns the corresponding Ordinal Date as
384
- # [year, day_of_year]
385
- def self.jd_to_ordinal(jd, sg=GREGORIAN)
386
- y = jd_to_civil(jd, sg)[0]
387
- doy = jd - civil_to_jd(y - 1, 12, 31, fix_style(jd, sg))
388
- return y, doy
389
- end
350
+ def find_fdom(y, m, sg) # :nodoc:
351
+ j = nil
352
+ 1.upto(31) do |d|
353
+ break if j = _valid_civil?(y, m, d, sg)
354
+ end
355
+ j
356
+ end
390
357
 
391
- # Convert a Civil Date to a Julian Day Number.
392
- # +y+, +m+, and +d+ are the year, month, and day of the
393
- # month. +sg+ specifies the Day of Calendar Reform.
394
- #
395
- # Returns the corresponding Julian Day Number.
396
- def self.civil_to_jd(y, m, d, sg=GREGORIAN)
397
- if m <= 2
398
- y -= 1
399
- m += 12
358
+ def find_ldom(y, m, sg) # :nodoc:
359
+ j = nil
360
+ 31.downto(1) do |d|
361
+ break if j = _valid_civil?(y, m, d, sg)
362
+ end
363
+ j
400
364
  end
401
- a = (y / 100.0).floor
402
- b = 2 - a + (a / 4.0).floor
403
- jd = (365.25 * (y + 4716)).floor +
404
- (30.6001 * (m + 1)).floor +
405
- d + b - 1524
406
- if julian?(jd, sg)
407
- jd -= b
365
+
366
+ # Convert an Ordinal Date to a Julian Day Number.
367
+ #
368
+ # +y+ and +d+ are the year and day-of-year to convert.
369
+ # +sg+ specifies the Day of Calendar Reform.
370
+ #
371
+ # Returns the corresponding Julian Day Number.
372
+ def ordinal_to_jd(y, d, sg=GREGORIAN) # :nodoc:
373
+ find_fdoy(y, sg) + d - 1
408
374
  end
409
- jd
410
- end
411
375
 
412
- # Convert a Julian Day Number to a Civil Date. +jd+ is
413
- # the Julian Day Number. +sg+ specifies the Day of
414
- # Calendar Reform.
415
- #
416
- # Returns the corresponding [year, month, day_of_month]
417
- # as a three-element array.
418
- def self.jd_to_civil(jd, sg=GREGORIAN)
419
- if julian?(jd, sg)
420
- a = jd
421
- else
422
- x = ((jd - 1867216.25) / 36524.25).floor
423
- a = jd + 1 + x - (x / 4.0).floor
376
+ # Convert a Julian Day Number to an Ordinal Date.
377
+ #
378
+ # +jd+ is the Julian Day Number to convert.
379
+ # +sg+ specifies the Day of Calendar Reform.
380
+ #
381
+ # Returns the corresponding Ordinal Date as
382
+ # [year, day_of_year]
383
+ def jd_to_ordinal(jd, sg=GREGORIAN) # :nodoc:
384
+ y = jd_to_civil(jd, sg)[0]
385
+ j = find_fdoy(y, sg)
386
+ doy = jd - j + 1
387
+ return y, doy
424
388
  end
425
- b = a + 1524
426
- c = ((b - 122.1) / 365.25).floor
427
- d = (365.25 * c).floor
428
- e = ((b - d) / 30.6001).floor
429
- dom = b - d - (30.6001 * e).floor
430
- if e <= 13
431
- m = e - 1
432
- y = c - 4716
433
- else
434
- m = e - 13
435
- y = c - 4715
389
+
390
+ # Convert a Civil Date to a Julian Day Number.
391
+ # +y+, +m+, and +d+ are the year, month, and day of the
392
+ # month. +sg+ specifies the Day of Calendar Reform.
393
+ #
394
+ # Returns the corresponding Julian Day Number.
395
+ def civil_to_jd(y, m, d, sg=GREGORIAN) # :nodoc:
396
+ if m <= 2
397
+ y -= 1
398
+ m += 12
399
+ end
400
+ a = (y / 100.0).floor
401
+ b = 2 - a + (a / 4.0).floor
402
+ jd = (365.25 * (y + 4716)).floor +
403
+ (30.6001 * (m + 1)).floor +
404
+ d + b - 1524
405
+ if jd < sg
406
+ jd -= b
407
+ end
408
+ jd
436
409
  end
437
- return y, m, dom
438
- end
439
410
 
440
- # Convert a Commercial Date to a Julian Day Number.
441
- #
442
- # +y+, +w+, and +d+ are the (commercial) year, week of the year,
443
- # and day of the week of the Commercial Date to convert.
444
- # +sg+ specifies the Day of Calendar Reform.
445
- def self.commercial_to_jd(y, w, d, ns=GREGORIAN)
446
- jd = civil_to_jd(y, 1, 4, ns)
447
- (jd - (((jd - 1) + 1) % 7)) +
448
- 7 * (w - 1) +
449
- (d - 1)
450
- end
411
+ # Convert a Julian Day Number to a Civil Date. +jd+ is
412
+ # the Julian Day Number. +sg+ specifies the Day of
413
+ # Calendar Reform.
414
+ #
415
+ # Returns the corresponding [year, month, day_of_month]
416
+ # as a three-element array.
417
+ def jd_to_civil(jd, sg=GREGORIAN) # :nodoc:
418
+ if jd < sg
419
+ a = jd
420
+ else
421
+ x = ((jd - 1867216.25) / 36524.25).floor
422
+ a = jd + 1 + x - (x / 4.0).floor
423
+ end
424
+ b = a + 1524
425
+ c = ((b - 122.1) / 365.25).floor
426
+ d = (365.25 * c).floor
427
+ e = ((b - d) / 30.6001).floor
428
+ dom = b - d - (30.6001 * e).floor
429
+ if e <= 13
430
+ m = e - 1
431
+ y = c - 4716
432
+ else
433
+ m = e - 13
434
+ y = c - 4715
435
+ end
436
+ return y, m, dom
437
+ end
451
438
 
452
- # Convert a Julian Day Number to a Commercial Date
453
- #
454
- # +jd+ is the Julian Day Number to convert.
455
- # +sg+ specifies the Day of Calendar Reform.
456
- #
457
- # Returns the corresponding Commercial Date as
458
- # [commercial_year, week_of_year, day_of_week]
459
- def self.jd_to_commercial(jd, sg=GREGORIAN)
460
- ns = fix_style(jd, sg)
461
- a = jd_to_civil(jd - 3, ns)[0]
462
- y = if jd >= commercial_to_jd(a + 1, 1, 1, ns) then a + 1 else a end
463
- w = 1 + ((jd - commercial_to_jd(y, 1, 1, ns)) / 7).floor
464
- d = (jd + 1) % 7
465
- d = 7 if d == 0
466
- return y, w, d
467
- end
439
+ # Convert a Commercial Date to a Julian Day Number.
440
+ #
441
+ # +y+, +w+, and +d+ are the (commercial) year, week of the year,
442
+ # and day of the week of the Commercial Date to convert.
443
+ # +sg+ specifies the Day of Calendar Reform.
444
+ def commercial_to_jd(y, w, d, sg=GREGORIAN) # :nodoc:
445
+ j = find_fdoy(y, sg) + 3
446
+ (j - (((j - 1) + 1) % 7)) +
447
+ 7 * (w - 1) +
448
+ (d - 1)
449
+ end
468
450
 
469
- def self.weeknum_to_jd(y, w, d, f=0, ns=GREGORIAN) # :nodoc:
470
- a = civil_to_jd(y, 1, 1, ns) + 6
471
- (a - ((a - f) + 1) % 7 - 7) + 7 * w + d
472
- end
451
+ # Convert a Julian Day Number to a Commercial Date
452
+ #
453
+ # +jd+ is the Julian Day Number to convert.
454
+ # +sg+ specifies the Day of Calendar Reform.
455
+ #
456
+ # Returns the corresponding Commercial Date as
457
+ # [commercial_year, week_of_year, day_of_week]
458
+ def jd_to_commercial(jd, sg=GREGORIAN) # :nodoc:
459
+ a = jd_to_civil(jd - 3, sg)[0]
460
+ y = if jd >= commercial_to_jd(a + 1, 1, 1, sg) then a + 1 else a end
461
+ w = 1 + ((jd - commercial_to_jd(y, 1, 1, sg)) / 7).floor
462
+ d = (jd + 1) % 7
463
+ d = 7 if d == 0
464
+ return y, w, d
465
+ end
473
466
 
474
- def self.jd_to_weeknum(jd, f=0, sg=GREGORIAN) # :nodoc:
475
- ns = fix_style(jd, sg)
476
- y, m, d = jd_to_civil(jd, ns)
477
- a = civil_to_jd(y, 1, 1, ns) + 6
478
- w, d = (jd - (a - ((a - f) + 1) % 7) + 7).divmod(7)
479
- return y, w, d
480
- end
467
+ def weeknum_to_jd(y, w, d, f=0, sg=GREGORIAN) # :nodoc:
468
+ a = find_fdoy(y, sg) + 6
469
+ (a - ((a - f) + 1) % 7 - 7) + 7 * w + d
470
+ end
481
471
 
482
- private_class_method :weeknum_to_jd, :jd_to_weeknum
472
+ def jd_to_weeknum(jd, f=0, sg=GREGORIAN) # :nodoc:
473
+ y, m, d = jd_to_civil(jd, sg)
474
+ a = find_fdoy(y, sg) + 6
475
+ w, d = (jd - (a - ((a - f) + 1) % 7) + 7).divmod(7)
476
+ return y, w, d
477
+ end
483
478
 
484
- # Convert an Astronomical Julian Day Number to a (civil) Julian
485
- # Day Number.
486
- #
487
- # +ajd+ is the Astronomical Julian Day Number to convert.
488
- # +of+ is the offset from UTC as a fraction of a day (defaults to 0).
489
- #
490
- # Returns the (civil) Julian Day Number as [day_number,
491
- # fraction] where +fraction+ is always 1/2.
492
- def self.ajd_to_jd(ajd, of=0) (ajd + of + HALF_DAYS_IN_DAY).divmod(1) end
479
+ def nth_kday_to_jd(y, m, n, k, sg=GREGORIAN) # :nodoc:
480
+ j = if n > 0
481
+ find_fdom(y, m, sg) - 1
482
+ else
483
+ find_ldom(y, m, sg) + 7
484
+ end
485
+ (j - (((j - k) + 1) % 7)) + 7 * n
486
+ end
493
487
 
494
- # Convert a (civil) Julian Day Number to an Astronomical Julian
495
- # Day Number.
496
- #
497
- # +jd+ is the Julian Day Number to convert, and +fr+ is a
498
- # fractional day.
499
- # +of+ is the offset from UTC as a fraction of a day (defaults to 0).
500
- #
501
- # Returns the Astronomical Julian Day Number as a single
502
- # numeric value.
503
- def self.jd_to_ajd(jd, fr, of=0) jd + fr - of - HALF_DAYS_IN_DAY end
488
+ def jd_to_nth_kday(jd, sg=GREGORIAN) # :nodoc:
489
+ y, m, d = jd_to_civil(jd, sg)
490
+ j = find_fdom(y, m, sg)
491
+ return y, m, ((jd - j) / 7).floor + 1, jd_to_wday(jd)
492
+ end
504
493
 
505
- # Convert a fractional day +fr+ to [hours, minutes, seconds,
506
- # fraction_of_a_second]
507
- def self.day_fraction_to_time(fr)
508
- ss, fr = fr.divmod(SECONDS_IN_DAY) # 4p
509
- h, ss = ss.divmod(3600)
510
- min, s = ss.divmod(60)
511
- return h, min, s, fr
512
- end
494
+ # Convert an Astronomical Julian Day Number to a (civil) Julian
495
+ # Day Number.
496
+ #
497
+ # +ajd+ is the Astronomical Julian Day Number to convert.
498
+ # +of+ is the offset from UTC as a fraction of a day (defaults to 0).
499
+ #
500
+ # Returns the (civil) Julian Day Number as [day_number,
501
+ # fraction] where +fraction+ is always 1/2.
502
+ def ajd_to_jd(ajd, of=0) (ajd + of + HALF_DAYS_IN_DAY).divmod(1) end # :nodoc:
503
+
504
+ # Convert a (civil) Julian Day Number to an Astronomical Julian
505
+ # Day Number.
506
+ #
507
+ # +jd+ is the Julian Day Number to convert, and +fr+ is a
508
+ # fractional day.
509
+ # +of+ is the offset from UTC as a fraction of a day (defaults to 0).
510
+ #
511
+ # Returns the Astronomical Julian Day Number as a single
512
+ # numeric value.
513
+ def jd_to_ajd(jd, fr, of=0) jd + fr - of - HALF_DAYS_IN_DAY end # :nodoc:
514
+
515
+ # Convert a fractional day +fr+ to [hours, minutes, seconds,
516
+ # fraction_of_a_second]
517
+ def day_fraction_to_time(fr) # :nodoc:
518
+ ss, fr = fr.divmod(SECONDS_IN_DAY) # 4p
519
+ h, ss = ss.divmod(3600)
520
+ min, s = ss.divmod(60)
521
+ return h, min, s, fr * 86400
522
+ end
513
523
 
514
- # Convert an +h+ hour, +min+ minutes, +s+ seconds period
515
- # to a fractional day.
516
- begin
517
- Rational(Rational(1, 2), 2) # a challenge
524
+ # Convert an +h+ hour, +min+ minutes, +s+ seconds period
525
+ # to a fractional day.
526
+ begin
527
+ Rational(Rational(1, 2), 2) # a challenge
518
528
 
519
- def self.time_to_day_fraction(h, min, s)
520
- Rational(h * 3600 + min * 60 + s, 86400) # 4p
529
+ def time_to_day_fraction(h, min, s)
530
+ Rational(h * 3600 + min * 60 + s, 86400) # 4p
531
+ end
532
+ rescue
533
+ def time_to_day_fraction(h, min, s)
534
+ if Integer === h && Integer === min && Integer === s
535
+ Rational(h * 3600 + min * 60 + s, 86400) # 4p
536
+ else
537
+ (h * 3600 + min * 60 + s).to_r/86400 # 4p
538
+ end
539
+ end
521
540
  end
522
- rescue
523
- def self.time_to_day_fraction(h, min, s)
524
- if Integer === h && Integer === min && Integer === s
525
- Rational(h * 3600 + min * 60 + s, 86400) # 4p
526
- else
527
- (h * 3600 + min * 60 + s).to_r/86400 # 4p
528
- end
541
+
542
+ # Convert an Astronomical Modified Julian Day Number to an
543
+ # Astronomical Julian Day Number.
544
+ def amjd_to_ajd(amjd) amjd + MJD_EPOCH_IN_AJD end # :nodoc:
545
+
546
+ # Convert an Astronomical Julian Day Number to an
547
+ # Astronomical Modified Julian Day Number.
548
+ def ajd_to_amjd(ajd) ajd - MJD_EPOCH_IN_AJD end # :nodoc:
549
+
550
+ # Convert a Modified Julian Day Number to a Julian
551
+ # Day Number.
552
+ def mjd_to_jd(mjd) mjd + MJD_EPOCH_IN_CJD end # :nodoc:
553
+
554
+ # Convert a Julian Day Number to a Modified Julian Day
555
+ # Number.
556
+ def jd_to_mjd(jd) jd - MJD_EPOCH_IN_CJD end # :nodoc:
557
+
558
+ # Convert a count of the number of days since the adoption
559
+ # of the Gregorian Calendar (in Italy) to a Julian Day Number.
560
+ def ld_to_jd(ld) ld + LD_EPOCH_IN_CJD end # :nodoc:
561
+
562
+ # Convert a Julian Day Number to the number of days since
563
+ # the adoption of the Gregorian Calendar (in Italy).
564
+ def jd_to_ld(jd) jd - LD_EPOCH_IN_CJD end # :nodoc:
565
+
566
+ # Convert a Julian Day Number to the day of the week.
567
+ #
568
+ # Sunday is day-of-week 0; Saturday is day-of-week 6.
569
+ def jd_to_wday(jd) (jd + 1) % 7 end # :nodoc:
570
+
571
+ # Is +jd+ a valid Julian Day Number?
572
+ #
573
+ # If it is, returns it. In fact, any value is treated as a valid
574
+ # Julian Day Number.
575
+ def _valid_jd? (jd, sg=GREGORIAN) jd end # :nodoc:
576
+
577
+ # Do the year +y+ and day-of-year +d+ make a valid Ordinal Date?
578
+ # Returns the corresponding Julian Day Number if they do, or
579
+ # nil if they don't.
580
+ #
581
+ # +d+ can be a negative number, in which case it counts backwards
582
+ # from the end of the year (-1 being the last day of the year).
583
+ # No year wraparound is performed, however, so valid values of
584
+ # +d+ are -365 .. -1, 1 .. 365 on a non-leap-year,
585
+ # -366 .. -1, 1 .. 366 on a leap year.
586
+ # A date falling in the period skipped in the Day of Calendar Reform
587
+ # adjustment is not valid.
588
+ #
589
+ # +sg+ specifies the Day of Calendar Reform.
590
+ def _valid_ordinal? (y, d, sg=GREGORIAN) # :nodoc:
591
+ if d < 0
592
+ return unless j = find_ldoy(y, sg)
593
+ ny, nd = jd_to_ordinal(j + d + 1, sg)
594
+ return unless ny == y
595
+ d = nd
596
+ end
597
+ jd = ordinal_to_jd(y, d, sg)
598
+ return unless [y, d] == jd_to_ordinal(jd, sg)
599
+ jd
529
600
  end
530
- end
531
601
 
532
- # Convert an Astronomical Modified Julian Day Number to an
533
- # Astronomical Julian Day Number.
534
- def self.amjd_to_ajd(amjd) amjd + MJD_EPOCH_IN_AJD end
602
+ # Do year +y+, month +m+, and day-of-month +d+ make a
603
+ # valid Civil Date? Returns the corresponding Julian
604
+ # Day Number if they do, nil if they don't.
605
+ #
606
+ # +m+ and +d+ can be negative, in which case they count
607
+ # backwards from the end of the year and the end of the
608
+ # month respectively. No wraparound is performed, however,
609
+ # and invalid values cause an ArgumentError to be raised.
610
+ # A date falling in the period skipped in the Day of Calendar
611
+ # Reform adjustment is not valid.
612
+ #
613
+ # +sg+ specifies the Day of Calendar Reform.
614
+ def _valid_civil? (y, m, d, sg=GREGORIAN) # :nodoc:
615
+ return unless d.is_a?(Integer)
616
+ if m < 0
617
+ m += 13
618
+ end
619
+ if d < 0
620
+ return unless j = find_ldom(y, m, sg)
621
+ ny, nm, nd = jd_to_civil(j + d + 1, sg)
622
+ return unless [ny, nm] == [y, m]
623
+ d = nd
624
+ end
625
+ jd = civil_to_jd(y, m, d, sg)
626
+ return unless [y, m, d] == jd_to_civil(jd, sg)
627
+ jd
628
+ end
535
629
 
536
- # Convert an Astronomical Julian Day Number to an
537
- # Astronomical Modified Julian Day Number.
538
- def self.ajd_to_amjd(ajd) ajd - MJD_EPOCH_IN_AJD end
630
+ # Do year +y+, week-of-year +w+, and day-of-week +d+ make a
631
+ # valid Commercial Date? Returns the corresponding Julian
632
+ # Day Number if they do, nil if they don't.
633
+ #
634
+ # Monday is day-of-week 1; Sunday is day-of-week 7.
635
+ #
636
+ # +w+ and +d+ can be negative, in which case they count
637
+ # backwards from the end of the year and the end of the
638
+ # week respectively. No wraparound is performed, however,
639
+ # and invalid values cause an ArgumentError to be raised.
640
+ # A date falling in the period skipped in the Day of Calendar
641
+ # Reform adjustment is not valid.
642
+ #
643
+ # +sg+ specifies the Day of Calendar Reform.
644
+ def _valid_commercial? (y, w, d, sg=GREGORIAN) # :nodoc:
645
+ if d < 0
646
+ d += 8
647
+ end
648
+ if w < 0
649
+ ny, nw, nd =
650
+ jd_to_commercial(commercial_to_jd(y + 1, 1, 1, sg) + w * 7, sg)
651
+ return unless ny == y
652
+ w = nw
653
+ end
654
+ jd = commercial_to_jd(y, w, d, sg)
655
+ return unless [y, w, d] == jd_to_commercial(jd, sg)
656
+ jd
657
+ end
539
658
 
540
- # Convert a Modified Julian Day Number to a Julian
541
- # Day Number.
542
- def self.mjd_to_jd(mjd) mjd + MJD_EPOCH_IN_CJD end
659
+ def _valid_weeknum? (y, w, d, f, sg=GREGORIAN) # :nodoc:
660
+ if d < 0
661
+ d += 7
662
+ end
663
+ if w < 0
664
+ ny, nw, nd, nf =
665
+ jd_to_weeknum(weeknum_to_jd(y + 1, 1, f, f, sg) + w * 7, f, sg)
666
+ return unless ny == y
667
+ w = nw
668
+ end
669
+ jd = weeknum_to_jd(y, w, d, f, sg)
670
+ return unless [y, w, d] == jd_to_weeknum(jd, f, sg)
671
+ jd
672
+ end
543
673
 
544
- # Convert a Julian Day Number to a Modified Julian Day
545
- # Number.
546
- def self.jd_to_mjd(jd) jd - MJD_EPOCH_IN_CJD end
674
+ def _valid_nth_kday? (y, m, n, k, sg=GREGORIAN) # :nodoc:
675
+ if k < 0
676
+ k += 7
677
+ end
678
+ if n < 0
679
+ ny, nm = (y * 12 + m).divmod(12)
680
+ nm, = (nm + 1) .divmod(1)
681
+ ny, nm, nn, nk =
682
+ jd_to_nth_kday(nth_kday_to_jd(ny, nm, 1, k, sg) + n * 7, sg)
683
+ return unless [ny, nm] == [y, m]
684
+ n = nn
685
+ end
686
+ jd = nth_kday_to_jd(y, m, n, k, sg)
687
+ return unless [y, m, n, k] == jd_to_nth_kday(jd, sg)
688
+ jd
689
+ end
547
690
 
548
- # Convert a count of the number of days since the adoption
549
- # of the Gregorian Calendar (in Italy) to a Julian Day Number.
550
- def self.ld_to_jd(ld) ld + LD_EPOCH_IN_CJD end
691
+ # Do hour +h+, minute +min+, and second +s+ constitute a valid time?
692
+ #
693
+ # If they do, returns their value as a fraction of a day. If not,
694
+ # returns nil.
695
+ #
696
+ # The 24-hour clock is used. Negative values of +h+, +min+, and
697
+ # +sec+ are treating as counting backwards from the end of the
698
+ # next larger unit (e.g. a +min+ of -2 is treated as 58). No
699
+ # wraparound is performed.
700
+ def _valid_time? (h, min, s) # :nodoc:
701
+ return unless h.is_a?(Integer) && min.is_a?(Integer)
702
+ h += 24 if h < 0
703
+ min += 60 if min < 0
704
+ s += 60 if s < 0
705
+ return unless ((0...24) === h &&
706
+ (0...60) === min &&
707
+ (0...60) === s) ||
708
+ (24 == h &&
709
+ 0 == min &&
710
+ 0 == s)
711
+ time_to_day_fraction(h, min, s)
712
+ end
551
713
 
552
- # Convert a Julian Day Number to the number of days since
553
- # the adoption of the Gregorian Calendar (in Italy).
554
- def self.jd_to_ld(jd) jd - LD_EPOCH_IN_CJD end
714
+ end
555
715
 
556
- # Convert a Julian Day Number to the day of the week.
557
- #
558
- # Sunday is day-of-week 0; Saturday is day-of-week 6.
559
- def self.jd_to_wday(jd) (jd + 1) % 7 end
716
+ extend t
717
+ include t
560
718
 
561
719
  # Is a year a leap year in the Julian calendar?
562
720
  #
@@ -572,145 +730,50 @@ class Date
572
730
  class << self; alias_method :leap?, :gregorian_leap? end
573
731
  class << self; alias_method :new!, :new end
574
732
 
575
- # Is +jd+ a valid Julian Day Number?
576
- #
577
- # If it is, returns it. In fact, any value is treated as a valid
578
- # Julian Day Number.
579
- def self.valid_jd? (jd, sg=ITALY) jd end
733
+ def self.valid_jd? (jd, sg=ITALY)
734
+ return false if jd.nil?
735
+ true
736
+ end
580
737
 
581
- # Do the year +y+ and day-of-year +d+ make a valid Ordinal Date?
582
- # Returns the corresponding Julian Day Number if they do, or
583
- # nil if they don't.
584
- #
585
- # +d+ can be a negative number, in which case it counts backwards
586
- # from the end of the year (-1 being the last day of the year).
587
- # No year wraparound is performed, however, so valid values of
588
- # +d+ are -365 .. -1, 1 .. 365 on a non-leap-year,
589
- # -366 .. -1, 1 .. 366 on a leap year.
590
- # A date falling in the period skipped in the Day of Calendar Reform
591
- # adjustment is not valid.
592
- #
593
- # +sg+ specifies the Day of Calendar Reform.
594
738
  def self.valid_ordinal? (y, d, sg=ITALY)
595
- if d < 0
596
- ny, = (y + 1).divmod(1)
597
- jd = ordinal_to_jd(ny, d + 1, sg)
598
- ns = fix_style(jd, sg)
599
- return unless [y] == jd_to_ordinal(jd, sg)[0..0]
600
- return unless [ny, 1] == jd_to_ordinal(jd - d, ns)
601
- else
602
- jd = ordinal_to_jd(y, d, sg)
603
- return unless [y, d] == jd_to_ordinal(jd, sg)
604
- end
605
- jd
739
+ !!_valid_ordinal?(y, d, sg)
606
740
  end
607
741
 
608
- # Do year +y+, month +m+, and day-of-month +d+ make a
609
- # valid Civil Date? Returns the corresponding Julian
610
- # Day Number if they do, nil if they don't.
611
- #
612
- # +m+ and +d+ can be negative, in which case they count
613
- # backwards from the end of the year and the end of the
614
- # month respectively. No wraparound is performed, however,
615
- # and invalid values cause an ArgumentError to be raised.
616
- # A date falling in the period skipped in the Day of Calendar
617
- # Reform adjustment is not valid.
618
- #
619
- # +sg+ specifies the Day of Calendar Reform.
620
742
  def self.valid_civil? (y, m, d, sg=ITALY)
621
- if m < 0
622
- m += 13
623
- end
624
- if d < 0
625
- ny, nm = (y * 12 + m).divmod(12)
626
- nm, = (nm + 1).divmod(1)
627
- jd = civil_to_jd(ny, nm, d + 1, sg)
628
- ns = fix_style(jd, sg)
629
- return unless [y, m] == jd_to_civil(jd, sg)[0..1]
630
- return unless [ny, nm, 1] == jd_to_civil(jd - d, ns)
631
- else
632
- jd = civil_to_jd(y, m, d, sg)
633
- return unless [y, m, d] == jd_to_civil(jd, sg)
634
- end
635
- jd
743
+ !!_valid_civil?(y, m, d, sg)
636
744
  end
637
745
 
638
746
  class << self; alias_method :valid_date?, :valid_civil? end
639
747
 
640
- # Do year +y+, week-of-year +w+, and day-of-week +d+ make a
641
- # valid Commercial Date? Returns the corresponding Julian
642
- # Day Number if they do, nil if they don't.
643
- #
644
- # Monday is day-of-week 1; Sunday is day-of-week 7.
645
- #
646
- # +w+ and +d+ can be negative, in which case they count
647
- # backwards from the end of the year and the end of the
648
- # week respectively. No wraparound is performed, however,
649
- # and invalid values cause an ArgumentError to be raised.
650
- # A date falling in the period skipped in the Day of Calendar
651
- # Reform adjustment is not valid.
652
- #
653
- # +sg+ specifies the Day of Calendar Reform.
654
748
  def self.valid_commercial? (y, w, d, sg=ITALY)
655
- if d < 0
656
- d += 8
657
- end
658
- if w < 0
659
- ny, nw, nd =
660
- jd_to_commercial(commercial_to_jd(y + 1, 1, 1) + w * 7)
661
- return unless ny == y
662
- w = nw
663
- end
664
- jd = commercial_to_jd(y, w, d)
665
- return unless gregorian?(jd, sg)
666
- return unless [y, w, d] == jd_to_commercial(jd)
667
- jd
749
+ !!_valid_commercial?(y, w, d, sg)
668
750
  end
669
751
 
670
752
  def self.valid_weeknum? (y, w, d, f, sg=ITALY) # :nodoc:
671
- if d < 0
672
- d += 7
673
- end
674
- if w < 0
675
- ny, nw, nd, nf =
676
- jd_to_weeknum(weeknum_to_jd(y + 1, 1, f, f) + w * 7, f)
677
- return unless ny == y
678
- w = nw
679
- end
680
- jd = weeknum_to_jd(y, w, d, f)
681
- return unless gregorian?(jd, sg)
682
- return unless [y, w, d] == jd_to_weeknum(jd, f)
683
- jd
753
+ !!_valid_weeknum?(y, w, d, f, sg)
684
754
  end
685
755
 
686
756
  private_class_method :valid_weeknum?
687
757
 
688
- # Do hour +h+, minute +min+, and second +s+ constitute a valid time?
689
- #
690
- # If they do, returns their value as a fraction of a day. If not,
691
- # returns nil.
692
- #
693
- # The 24-hour clock is used. Negative values of +h+, +min+, and
694
- # +sec+ are treating as counting backwards from the end of the
695
- # next larger unit (e.g. a +min+ of -2 is treated as 58). No
696
- # wraparound is performed.
697
- def self.valid_time? (h, min, s)
698
- h += 24 if h < 0
699
- min += 60 if min < 0
700
- s += 60 if s < 0
701
- return if s < 0 || s >= 60
702
- return if min < 0 || min >= 60
703
- return if h < 0 || h > 24 || (24 == h && (0 != min || 0 != s))
704
- time_to_day_fraction(h, min, s)
758
+ def self.valid_nth_kday? (y, m, n, k, sg=ITALY) # :nodoc:
759
+ !!_valid_nth_kday?(y, m, n, k, sg)
760
+ end
761
+
762
+ private_class_method :valid_nth_kday?
763
+
764
+ def self.valid_time? (h, min, s) # :nodoc:
765
+ !!_valid_time?(h, min, s)
705
766
  end
706
767
 
768
+ private_class_method :valid_time?
769
+
707
770
  # Create a new Date object from a Julian Day Number.
708
771
  #
709
772
  # +jd+ is the Julian Day Number; if not specified, it defaults to
710
773
  # 0.
711
774
  # +sg+ specifies the Day of Calendar Reform.
712
775
  def self.jd(jd=0, sg=ITALY)
713
- jd = valid_jd?(jd, sg)
776
+ jd = _valid_jd?(jd, sg)
714
777
  new!(jd_to_ajd(jd, 0, 0), 0, sg)
715
778
  end
716
779
 
@@ -725,7 +788,7 @@ class Date
725
788
  #
726
789
  # +sg+ specifies the Day of Calendar Reform.
727
790
  def self.ordinal(y=-4712, d=1, sg=ITALY)
728
- unless jd = valid_ordinal?(y, d, sg)
791
+ unless jd = _valid_ordinal?(y, d, sg)
729
792
  raise ArgumentError, 'invalid date'
730
793
  end
731
794
  new!(jd_to_ajd(jd, 0, 0), 0, sg)
@@ -745,7 +808,7 @@ class Date
745
808
  #
746
809
  # +sg+ specifies the Day of Calendar Reform.
747
810
  def self.civil(y=-4712, m=1, d=1, sg=ITALY)
748
- unless jd = valid_civil?(y, m, d, sg)
811
+ unless jd = _valid_civil?(y, m, d, sg)
749
812
  raise ArgumentError, 'invalid date'
750
813
  end
751
814
  new!(jd_to_ajd(jd, 0, 0), 0, sg)
@@ -763,19 +826,19 @@ class Date
763
826
  # week respectively. No wraparound is performed, however,
764
827
  # and invalid values cause an ArgumentError to be raised.
765
828
  #
766
- # +y+ defaults to 1582, +w+ to 41, and +d+ to 5, the Day of
767
- # Calendar Reform for Italy and the Catholic countries.
829
+ # +y+ defaults to -4712, +w+ to 1, and +d+ to 1; this is
830
+ # Julian Day Number day 0.
768
831
  #
769
832
  # +sg+ specifies the Day of Calendar Reform.
770
- def self.commercial(y=1582, w=41, d=5, sg=ITALY)
771
- unless jd = valid_commercial?(y, w, d, sg)
833
+ def self.commercial(y=-4712, w=1, d=1, sg=ITALY)
834
+ unless jd = _valid_commercial?(y, w, d, sg)
772
835
  raise ArgumentError, 'invalid date'
773
836
  end
774
837
  new!(jd_to_ajd(jd, 0, 0), 0, sg)
775
838
  end
776
839
 
777
- def self.weeknum(y=1582, w=41, d=5, f=0, sg=ITALY) # :nodoc:
778
- unless jd = valid_weeknum?(y, w, d, f, sg)
840
+ def self.weeknum(y=-4712, w=0, d=1, f=0, sg=ITALY)
841
+ unless jd = _valid_weeknum?(y, w, d, f, sg)
779
842
  raise ArgumentError, 'invalid date'
780
843
  end
781
844
  new!(jd_to_ajd(jd, 0, 0), 0, sg)
@@ -783,6 +846,15 @@ class Date
783
846
 
784
847
  private_class_method :weeknum
785
848
 
849
+ def self.nth_kday(y=-4712, m=1, n=1, k=1, sg=ITALY)
850
+ unless jd = _valid_nth_kday?(y, m, n, k, sg)
851
+ raise ArgumentError, 'invalid date'
852
+ end
853
+ new!(jd_to_ajd(jd, 0, 0), 0, sg)
854
+ end
855
+
856
+ private_class_method :nth_kday
857
+
786
858
  def self.rewrite_frags(elem) # :nodoc:
787
859
  elem ||= {}
788
860
  if seconds = elem[:seconds]
@@ -806,16 +878,16 @@ class Date
806
878
  def self.complete_frags(elem) # :nodoc:
807
879
  i = 0
808
880
  g = [[:time, [:hour, :min, :sec]],
809
- [nil, [:jd]],
810
- [:ordinal, [:year, :yday, :hour, :min, :sec]],
811
- [:civil, [:year, :mon, :mday, :hour, :min, :sec]],
812
- [:commercial, [:cwyear, :cweek, :cwday, :hour, :min, :sec]],
813
- [:wday, [:wday, :hour, :min, :sec]],
814
- [:wnum0, [:year, :wnum0, :wday, :hour, :min, :sec]],
815
- [:wnum1, [:year, :wnum1, :wday, :hour, :min, :sec]],
816
- [nil, [:cwyear, :cweek, :wday, :hour, :min, :sec]],
817
- [nil, [:year, :wnum0, :cwday, :hour, :min, :sec]],
818
- [nil, [:year, :wnum1, :cwday, :hour, :min, :sec]]].
881
+ [nil, [:jd]],
882
+ [:ordinal, [:year, :yday, :hour, :min, :sec]],
883
+ [:civil, [:year, :mon, :mday, :hour, :min, :sec]],
884
+ [:commercial, [:cwyear, :cweek, :cwday, :hour, :min, :sec]],
885
+ [:wday, [:wday, :hour, :min, :sec]],
886
+ [:wnum0, [:year, :wnum0, :wday, :hour, :min, :sec]],
887
+ [:wnum1, [:year, :wnum1, :wday, :hour, :min, :sec]],
888
+ [nil, [:cwyear, :cweek, :wday, :hour, :min, :sec]],
889
+ [nil, [:year, :wnum0, :cwday, :hour, :min, :sec]],
890
+ [nil, [:year, :wnum1, :cwday, :hour, :min, :sec]]].
819
891
  collect{|k, a| e = elem.values_at(*a).compact; [k, a, e]}.
820
892
  select{|k, a, e| e.size > 0}.
821
893
  sort_by{|k, a, e| [e.size, i -= 1]}.last
@@ -827,52 +899,52 @@ class Date
827
899
 
828
900
  case g[0]
829
901
  when :ordinal
830
- elem[:year] ||= d.year
831
- elem[:yday] ||= 1
902
+ elem[:year] ||= d.year
903
+ elem[:yday] ||= 1
832
904
  when :civil
833
- g[1].each do |e|
834
- break if elem[e]
835
- elem[e] = d.__send__(e)
836
- end
837
- elem[:mon] ||= 1
838
- elem[:mday] ||= 1
905
+ g[1].each do |e|
906
+ break if elem[e]
907
+ elem[e] = d.__send__(e)
908
+ end
909
+ elem[:mon] ||= 1
910
+ elem[:mday] ||= 1
839
911
  when :commercial
840
- g[1].each do |e|
841
- break if elem[e]
842
- elem[e] = d.__send__(e)
843
- end
844
- elem[:cweek] ||= 1
845
- elem[:cwday] ||= 1
912
+ g[1].each do |e|
913
+ break if elem[e]
914
+ elem[e] = d.__send__(e)
915
+ end
916
+ elem[:cweek] ||= 1
917
+ elem[:cwday] ||= 1
846
918
  when :wday
847
- elem[:jd] ||= (d - d.wday + elem[:wday]).jd
919
+ elem[:jd] ||= (d - d.wday + elem[:wday]).jd
848
920
  when :wnum0
849
- g[1].each do |e|
850
- break if elem[e]
851
- elem[e] = d.__send__(e)
852
- end
853
- elem[:wnum0] ||= 0
854
- elem[:wday] ||= 0
921
+ g[1].each do |e|
922
+ break if elem[e]
923
+ elem[e] = d.__send__(e)
924
+ end
925
+ elem[:wnum0] ||= 0
926
+ elem[:wday] ||= 0
855
927
  when :wnum1
856
- g[1].each do |e|
857
- break if elem[e]
858
- elem[e] = d.__send__(e)
859
- end
860
- elem[:wnum1] ||= 0
861
- elem[:wday] ||= 1
928
+ g[1].each do |e|
929
+ break if elem[e]
930
+ elem[e] = d.__send__(e)
931
+ end
932
+ elem[:wnum1] ||= 0
933
+ elem[:wday] ||= 1
862
934
  end
863
935
  end
864
936
 
865
937
  if g && g[0] == :time
866
938
  if self <= DateTime
867
- d ||= Date.today
868
- elem[:jd] ||= d.jd
939
+ d ||= Date.today
940
+ elem[:jd] ||= d.jd
869
941
  end
870
942
  end
871
943
 
872
944
  elem[:hour] ||= 0
873
945
  elem[:min] ||= 0
874
946
  elem[:sec] ||= 0
875
- elem[:sec] = [elem[:sec], 59].min
947
+ elem[:sec] = elem[:sec] == 60 ? 59 : elem[:sec]
876
948
 
877
949
  elem
878
950
  end
@@ -883,56 +955,56 @@ class Date
883
955
  catch :jd do
884
956
  a = elem.values_at(:jd)
885
957
  if a.all?
886
- if jd = valid_jd?(*(a << sg))
887
- throw :jd, jd
888
- end
958
+ if jd = _valid_jd?(*(a << sg))
959
+ throw :jd, jd
960
+ end
889
961
  end
890
962
 
891
963
  a = elem.values_at(:year, :yday)
892
964
  if a.all?
893
- if jd = valid_ordinal?(*(a << sg))
894
- throw :jd, jd
895
- end
965
+ if jd = _valid_ordinal?(*(a << sg))
966
+ throw :jd, jd
967
+ end
896
968
  end
897
969
 
898
970
  a = elem.values_at(:year, :mon, :mday)
899
971
  if a.all?
900
- if jd = valid_civil?(*(a << sg))
901
- throw :jd, jd
902
- end
972
+ if jd = _valid_civil?(*(a << sg))
973
+ throw :jd, jd
974
+ end
903
975
  end
904
976
 
905
977
  a = elem.values_at(:cwyear, :cweek, :cwday)
906
978
  if a[2].nil? && elem[:wday]
907
- a[2] = elem[:wday].nonzero? || 7
979
+ a[2] = elem[:wday].nonzero? || 7
908
980
  end
909
981
  if a.all?
910
- if jd = valid_commercial?(*(a << sg))
911
- throw :jd, jd
912
- end
982
+ if jd = _valid_commercial?(*(a << sg))
983
+ throw :jd, jd
984
+ end
913
985
  end
914
986
 
915
987
  a = elem.values_at(:year, :wnum0, :wday)
916
988
  if a[2].nil? && elem[:cwday]
917
- a[2] = elem[:cwday] % 7
989
+ a[2] = elem[:cwday] % 7
918
990
  end
919
991
  if a.all?
920
- if jd = valid_weeknum?(*(a << 0 << sg))
921
- throw :jd, jd
922
- end
992
+ if jd = _valid_weeknum?(*(a << 0 << sg))
993
+ throw :jd, jd
994
+ end
923
995
  end
924
996
 
925
997
  a = elem.values_at(:year, :wnum1, :wday)
926
998
  if a[2]
927
- a[2] = (a[2] - 1) % 7
999
+ a[2] = (a[2] - 1) % 7
928
1000
  end
929
1001
  if a[2].nil? && elem[:cwday]
930
- a[2] = (elem[:cwday] - 1) % 7
1002
+ a[2] = (elem[:cwday] - 1) % 7
931
1003
  end
932
1004
  if a.all?
933
- if jd = valid_weeknum?(*(a << 1 << sg))
934
- throw :jd, jd
935
- end
1005
+ if jd = _valid_weeknum?(*(a << 1 << sg))
1006
+ throw :jd, jd
1007
+ end
936
1008
  end
937
1009
  end
938
1010
  end
@@ -941,7 +1013,7 @@ class Date
941
1013
 
942
1014
  def self.valid_time_frags? (elem) # :nodoc:
943
1015
  h, min, s = elem.values_at(:hour, :min, :sec)
944
- valid_time?(h, min, s)
1016
+ _valid_time?(h, min, s)
945
1017
  end
946
1018
 
947
1019
  private_class_method :valid_time_frags?
@@ -992,24 +1064,56 @@ class Date
992
1064
  # Day Number day 0.
993
1065
  #
994
1066
  # +sg+ specifies the Day of Calendar Reform.
995
- def self.parse(str='-4712-01-01', comp=false, sg=ITALY)
1067
+ def self.parse(str='-4712-01-01', comp=true, sg=ITALY)
996
1068
  elem = _parse(str, comp)
997
1069
  new_by_frags(elem, sg)
998
1070
  end
999
1071
 
1072
+ def self.iso8601(str='-4712-01-01', sg=ITALY) # :nodoc:
1073
+ elem = _iso8601(str)
1074
+ new_by_frags(elem, sg)
1075
+ end
1076
+
1077
+ def self.rfc3339(str='-4712-01-01T00:00:00+00:00', sg=ITALY) # :nodoc:
1078
+ elem = _rfc3339(str)
1079
+ new_by_frags(elem, sg)
1080
+ end
1081
+
1082
+ def self.xmlschema(str='-4712-01-01', sg=ITALY) # :nodoc:
1083
+ elem = _xmlschema(str)
1084
+ new_by_frags(elem, sg)
1085
+ end
1086
+
1087
+ def self.rfc2822(str='Mon, 1 Jan -4712 00:00:00 +0000', sg=ITALY) # :nodoc:
1088
+ elem = _rfc2822(str)
1089
+ new_by_frags(elem, sg)
1090
+ end
1091
+
1092
+ class << self; alias_method :rfc822, :rfc2822 end
1093
+
1094
+ def self.httpdate(str='Mon, 01 Jan -4712 00:00:00 GMT', sg=ITALY) # :nodoc:
1095
+ elem = _httpdate(str)
1096
+ new_by_frags(elem, sg)
1097
+ end
1098
+
1099
+ def self.jisx0301(str='-4712-01-01', sg=ITALY) # :nodoc:
1100
+ elem = _jisx0301(str)
1101
+ new_by_frags(elem, sg)
1102
+ end
1103
+
1000
1104
  class << self
1001
1105
 
1002
- def once(*ids) # :nodoc:
1106
+ def once(*ids) # :nodoc: -- restricted
1003
1107
  for id in ids
1004
- module_eval <<-"end;"
1005
- alias_method :__#{id.object_id}__, :#{id.to_s}
1006
- private :__#{id.object_id}__
1007
- def #{id.to_s}(*args, &block)
1008
- (@__#{id.object_id}__ ||= [__#{id.object_id}__(*args, &block)])[0]
1009
- end
1010
- end;
1108
+ module_eval <<-"end;"
1109
+ alias_method :__#{id.object_id}__, :#{id.to_s}
1110
+ private :__#{id.object_id}__
1111
+ def #{id.to_s}(*args)
1112
+ @__ca__[#{id.object_id}] ||= __#{id.object_id}__(*args)
1113
+ end
1114
+ end;
1011
1115
  end
1012
- end
1116
+ end # <<dummy
1013
1117
 
1014
1118
  private :once
1015
1119
 
@@ -1034,42 +1138,45 @@ class Date
1034
1138
  #
1035
1139
  # Using one of the factory methods such as Date::civil is
1036
1140
  # generally easier and safer.
1037
- def initialize(ajd=0, of=0, sg=ITALY) @ajd, @of, @sg = ajd, of, sg end
1141
+ def initialize(ajd=0, of=0, sg=ITALY)
1142
+ @ajd, @of, @sg = ajd, of, sg
1143
+ @__ca__ = {}
1144
+ end
1038
1145
 
1039
1146
  # Get the date as an Astronomical Julian Day Number.
1040
1147
  def ajd() @ajd end
1041
1148
 
1042
1149
  # Get the date as an Astronomical Modified Julian Day Number.
1043
- def amjd() self.class.ajd_to_amjd(@ajd) end
1150
+ def amjd() ajd_to_amjd(@ajd) end
1044
1151
 
1045
1152
  once :amjd
1046
1153
 
1047
1154
  # Get the date as a Julian Day Number.
1048
- def jd() self.class.ajd_to_jd(@ajd, @of)[0] end
1155
+ def jd() ajd_to_jd(@ajd, @of)[0] end
1049
1156
 
1050
1157
  # Get any fractional day part of the date.
1051
- def day_fraction() self.class.ajd_to_jd(@ajd, @of)[1] end
1158
+ def day_fraction() ajd_to_jd(@ajd, @of)[1] end
1052
1159
 
1053
1160
  # Get the date as a Modified Julian Day Number.
1054
- def mjd() self.class.jd_to_mjd(jd) end
1161
+ def mjd() jd_to_mjd(jd) end
1055
1162
 
1056
1163
  # Get the date as the number of days since the Day of Calendar
1057
1164
  # Reform (in Italy and the Catholic countries).
1058
- def ld() self.class.jd_to_ld(jd) end
1165
+ def ld() jd_to_ld(jd) end
1059
1166
 
1060
1167
  once :jd, :day_fraction, :mjd, :ld
1061
1168
 
1062
1169
  # Get the date as a Civil Date, [year, month, day_of_month]
1063
- def civil() self.class.jd_to_civil(jd, @sg) end # :nodoc:
1170
+ def civil() jd_to_civil(jd, @sg) end # :nodoc:
1064
1171
 
1065
1172
  # Get the date as an Ordinal Date, [year, day_of_year]
1066
- def ordinal() self.class.jd_to_ordinal(jd, @sg) end # :nodoc:
1173
+ def ordinal() jd_to_ordinal(jd, @sg) end # :nodoc:
1067
1174
 
1068
1175
  # Get the date as a Commercial Date, [year, week_of_year, day_of_week]
1069
- def commercial() self.class.jd_to_commercial(jd, @sg) end # :nodoc:
1176
+ def commercial() jd_to_commercial(jd, @sg) end # :nodoc:
1070
1177
 
1071
- def weeknum0() self.class.__send__(:jd_to_weeknum, jd, 0, @sg) end # :nodoc:
1072
- def weeknum1() self.class.__send__(:jd_to_weeknum, jd, 1, @sg) end # :nodoc:
1178
+ def weeknum0() jd_to_weeknum(jd, 0, @sg) end # :nodoc:
1179
+ def weeknum1() jd_to_weeknum(jd, 1, @sg) end # :nodoc:
1073
1180
 
1074
1181
  once :civil, :ordinal, :commercial, :weeknum0, :weeknum1
1075
1182
  private :civil, :ordinal, :commercial, :weeknum0, :weeknum1
@@ -1100,7 +1207,7 @@ class Date
1100
1207
 
1101
1208
  # Get the time of this date as [hours, minutes, seconds,
1102
1209
  # fraction_of_a_second]
1103
- def time() self.class.day_fraction_to_time(day_fraction) end # :nodoc:
1210
+ def time() day_fraction_to_time(day_fraction) end # :nodoc:
1104
1211
 
1105
1212
  once :time
1106
1213
  private :time
@@ -1114,14 +1221,15 @@ class Date
1114
1221
  # Get the second of this date.
1115
1222
  def sec() time[2] end
1116
1223
 
1224
+ # Get the fraction-of-a-second of this date.
1225
+ def sec_fraction() time[3] end
1226
+
1117
1227
  alias_method :minute, :min
1118
1228
  alias_method :second, :sec
1229
+ alias_method :second_fraction, :sec_fraction
1119
1230
 
1120
- # Get the fraction-of-a-second of this date. The unit is in days.
1121
- # I do NOT recommend you to use this method.
1122
- def sec_fraction() time[3] end
1123
-
1124
- private :hour, :min, :sec, :sec_fraction
1231
+ private :hour, :min, :sec, :sec_fraction,
1232
+ :minute, :second, :second_fraction
1125
1233
 
1126
1234
  def zone() strftime('%:z') end
1127
1235
 
@@ -1140,7 +1248,7 @@ class Date
1140
1248
 
1141
1249
  # Get the week day of this date. Sunday is day-of-week 0;
1142
1250
  # Saturday is day-of-week 6.
1143
- def wday() self.class.jd_to_wday(jd) end
1251
+ def wday() jd_to_wday(jd) end
1144
1252
 
1145
1253
  once :wday
1146
1254
 
@@ -1150,17 +1258,23 @@ class Date
1150
1258
  define_method(n.downcase + '?'){mon == i}
1151
1259
  end
1152
1260
  end
1261
+ =end
1153
1262
 
1154
1263
  DAYNAMES.each_with_index do |n, i|
1155
1264
  define_method(n.downcase + '?'){wday == i}
1156
1265
  end
1157
- =end
1266
+
1267
+ def nth_kday? (n, k)
1268
+ k == wday && jd === nth_kday_to_jd(year, mon, n, k, start)
1269
+ end
1270
+
1271
+ private :nth_kday?
1158
1272
 
1159
1273
  # Is the current date old-style (Julian Calendar)?
1160
- def julian? () self.class.julian?(jd, @sg) end
1274
+ def julian? () jd < @sg end
1161
1275
 
1162
1276
  # Is the current date new-style (Gregorian Calendar)?
1163
- def gregorian? () self.class.gregorian?(jd, @sg) end
1277
+ def gregorian? () !julian? end
1164
1278
 
1165
1279
  once :julian?, :gregorian?
1166
1280
 
@@ -1174,8 +1288,8 @@ class Date
1174
1288
 
1175
1289
  # Is this a leap year?
1176
1290
  def leap?
1177
- self.class.jd_to_civil(self.class.civil_to_jd(year, 3, 1, fix_style) - 1,
1178
- fix_style)[-1] == 29
1291
+ jd_to_civil(civil_to_jd(year, 3, 1, fix_style) - 1,
1292
+ fix_style)[-1] == 29
1179
1293
  end
1180
1294
 
1181
1295
  once :leap?
@@ -1260,6 +1374,12 @@ class Date
1260
1374
  case other
1261
1375
  when Numeric; return @ajd <=> other
1262
1376
  when Date; return @ajd <=> other.ajd
1377
+ else
1378
+ begin
1379
+ l, r = other.coerce(self)
1380
+ return l <=> r
1381
+ rescue NoMethodError
1382
+ end
1263
1383
  end
1264
1384
  nil
1265
1385
  end
@@ -1274,14 +1394,18 @@ class Date
1274
1394
  case other
1275
1395
  when Numeric; return jd == other
1276
1396
  when Date; return jd == other.jd
1397
+ else
1398
+ begin
1399
+ l, r = other.coerce(self)
1400
+ return l === r
1401
+ rescue NoMethodError
1402
+ end
1277
1403
  end
1278
1404
  false
1279
1405
  end
1280
1406
 
1281
1407
  def next_day(n=1) self + n end
1282
- # def prev_day(n=1) self - n end
1283
-
1284
- private :next_day
1408
+ def prev_day(n=1) self - n end
1285
1409
 
1286
1410
  # Return a new Date one day after this one.
1287
1411
  def next() next_day end
@@ -1298,7 +1422,10 @@ class Date
1298
1422
  y, m = (year * 12 + (mon - 1) + n).divmod(12)
1299
1423
  m, = (m + 1) .divmod(1)
1300
1424
  d = mday
1301
- d -= 1 until jd2 = self.class.valid_civil?(y, m, d, fix_style)
1425
+ until jd2 = _valid_civil?(y, m, d, @sg)
1426
+ d -= 1
1427
+ raise ArgumentError, 'invalid date' unless d > 0
1428
+ end
1302
1429
  self + (jd2 - jd)
1303
1430
  end
1304
1431
 
@@ -1310,15 +1437,11 @@ class Date
1310
1437
  # of the returned Date will be the last day of the target month.
1311
1438
  def << (n) self >> -n end
1312
1439
 
1313
- =begin
1314
1440
  def next_month(n=1) self >> n end
1315
1441
  def prev_month(n=1) self << n end
1316
1442
 
1317
1443
  def next_year(n=1) self >> n * 12 end
1318
1444
  def prev_year(n=1) self << n * 12 end
1319
- =end
1320
-
1321
- # require 'enumerator'
1322
1445
 
1323
1446
  # Step the current date forward +step+ days at a
1324
1447
  # time (or backward, if +step+ is negative) until
@@ -1326,10 +1449,13 @@ class Date
1326
1449
  # date at each step.
1327
1450
  def step(limit, step=1) # :yield: date
1328
1451
  =begin
1452
+ if step.zero?
1453
+ raise ArgumentError, "step can't be 0"
1454
+ end
1455
+ =end
1329
1456
  unless block_given?
1330
1457
  return to_enum(:step, limit, step)
1331
1458
  end
1332
- =end
1333
1459
  da = self
1334
1460
  op = %w(- <= >=)[step <=> 0]
1335
1461
  while da.__send__(op, limit)
@@ -1360,29 +1486,22 @@ class Date
1360
1486
  def hash() @ajd.hash end
1361
1487
 
1362
1488
  # Return internal object state as a programmer-readable string.
1363
- def inspect() format('#<%s: %s,%s,%s>', self.class, @ajd, @of, @sg) end
1489
+ def inspect
1490
+ format('#<%s: %s (%s,%s,%s)>', self.class, to_s, @ajd, @of, @sg)
1491
+ end
1364
1492
 
1365
1493
  # Return the date as a human-readable string.
1366
1494
  #
1367
1495
  # The format used is YYYY-MM-DD.
1368
- def to_s() format('%.4d-%02d-%02d', year, mon, mday) end
1496
+ def to_s() format('%.4d-%02d-%02d', year, mon, mday) end # 4p
1369
1497
 
1370
1498
  # Dump to Marshal format.
1371
- def _dump(limit) Marshal.dump([@ajd, @of, @sg], -1) end
1372
-
1373
- # def self._load(str) new!(*Marshal.load(str)) end
1499
+ def marshal_dump() [@ajd, @of, @sg] end
1374
1500
 
1375
- # Load from Marshall format.
1376
- def self._load(str)
1377
- a = Marshal.load(str)
1378
- if a.size == 2
1379
- ajd, sg = a
1380
- of = 0
1381
- ajd -= 1.to_r/2
1382
- else
1383
- ajd, of, sg = a
1384
- end
1385
- new!(ajd, of, sg)
1501
+ # Load from Marshal format.
1502
+ def marshal_load(a)
1503
+ @ajd, @of, @sg, = a
1504
+ @__ca__ = {}
1386
1505
  end
1387
1506
 
1388
1507
  end
@@ -1417,8 +1536,7 @@ end
1417
1536
  # === sec_fraction()
1418
1537
  #
1419
1538
  # Get the fraction of a second of the time. This is returned as
1420
- # a +Rational+. The unit is in days.
1421
- # I do NOT recommend you to use this method.
1539
+ # a +Rational+.
1422
1540
  #
1423
1541
  # === zone()
1424
1542
  #
@@ -1452,8 +1570,8 @@ class DateTime < Date
1452
1570
  #
1453
1571
  # All day/time values default to 0.
1454
1572
  def self.jd(jd=0, h=0, min=0, s=0, of=0, sg=ITALY)
1455
- unless (jd = valid_jd?(jd, sg)) &&
1456
- (fr = valid_time?(h, min, s))
1573
+ unless (jd = _valid_jd?(jd, sg)) &&
1574
+ (fr = _valid_time?(h, min, s))
1457
1575
  raise ArgumentError, 'invalid date'
1458
1576
  end
1459
1577
  if String === of
@@ -1477,8 +1595,8 @@ class DateTime < Date
1477
1595
  # +y+ defaults to -4712, and +d+ to 1; this is Julian Day Number
1478
1596
  # day 0. The time values default to 0.
1479
1597
  def self.ordinal(y=-4712, d=1, h=0, min=0, s=0, of=0, sg=ITALY)
1480
- unless (jd = valid_ordinal?(y, d, sg)) &&
1481
- (fr = valid_time?(h, min, s))
1598
+ unless (jd = _valid_ordinal?(y, d, sg)) &&
1599
+ (fr = _valid_time?(h, min, s))
1482
1600
  raise ArgumentError, 'invalid date'
1483
1601
  end
1484
1602
  if String === of
@@ -1502,8 +1620,8 @@ class DateTime < Date
1502
1620
  # +y+ defaults to -4712, +m+ to 1, and +d+ to 1; this is Julian Day
1503
1621
  # Number day 0. The time values default to 0.
1504
1622
  def self.civil(y=-4712, m=1, d=1, h=0, min=0, s=0, of=0, sg=ITALY)
1505
- unless (jd = valid_civil?(y, m, d, sg)) &&
1506
- (fr = valid_time?(h, min, s))
1623
+ unless (jd = _valid_civil?(y, m, d, sg)) &&
1624
+ (fr = _valid_time?(h, min, s))
1507
1625
  raise ArgumentError, 'invalid date'
1508
1626
  end
1509
1627
  if String === of
@@ -1526,12 +1644,12 @@ class DateTime < Date
1526
1644
  # +of+ is the offset from UTC as a fraction of a day (defaults to 0).
1527
1645
  # +sg+ specifies the Day of Calendar Reform.
1528
1646
  #
1529
- # +y+ defaults to 1582, +w+ to 41, and +d+ to 5; this is the Day of
1530
- # Calendar Reform for Italy and the Catholic countries.
1647
+ # +y+ defaults to -4712, +w+ to 1, and +d+ to 1; this is
1648
+ # Julian Day Number day 0.
1531
1649
  # The time values default to 0.
1532
- def self.commercial(y=1582, w=41, d=5, h=0, min=0, s=0, of=0, sg=ITALY)
1533
- unless (jd = valid_commercial?(y, w, d, sg)) &&
1534
- (fr = valid_time?(h, min, s))
1650
+ def self.commercial(y=-4712, w=1, d=1, h=0, min=0, s=0, of=0, sg=ITALY)
1651
+ unless (jd = _valid_commercial?(y, w, d, sg)) &&
1652
+ (fr = _valid_time?(h, min, s))
1535
1653
  raise ArgumentError, 'invalid date'
1536
1654
  end
1537
1655
  if String === of
@@ -1540,9 +1658,9 @@ class DateTime < Date
1540
1658
  new!(jd_to_ajd(jd, fr, of), of, sg)
1541
1659
  end
1542
1660
 
1543
- def self.weeknum(y=1582, w=41, d=5, f=0, h=0, min=0, s=0, of=0, sg=ITALY) # :nodoc:
1544
- unless (jd = valid_weeknum?(y, w, d, f, sg)) &&
1545
- (fr = valid_time?(h, min, s))
1661
+ def self.weeknum(y=-4712, w=0, d=1, f=0, h=0, min=0, s=0, of=0, sg=ITALY) # :nodoc:
1662
+ unless (jd = _valid_weeknum?(y, w, d, f, sg)) &&
1663
+ (fr = _valid_time?(h, min, s))
1546
1664
  raise ArgumentError, 'invalid date'
1547
1665
  end
1548
1666
  if String === of
@@ -1553,11 +1671,24 @@ class DateTime < Date
1553
1671
 
1554
1672
  private_class_method :weeknum
1555
1673
 
1674
+ def self.nth_kday(y=-4712, m=1, n=1, k=1, h=0, min=0, s=0, of=0, sg=ITALY) # :nodoc:
1675
+ unless (jd = _valid_nth_kday?(y, m, n, k, sg)) &&
1676
+ (fr = _valid_time?(h, min, s))
1677
+ raise ArgumentError, 'invalid date'
1678
+ end
1679
+ if String === of
1680
+ of = Rational(zone_to_diff(of) || 0, 86400)
1681
+ end
1682
+ new!(jd_to_ajd(jd, fr, of), of, sg)
1683
+ end
1684
+
1685
+ private_class_method :nth_kday
1686
+
1556
1687
  def self.new_by_frags(elem, sg) # :nodoc:
1557
1688
  elem = rewrite_frags(elem)
1558
1689
  elem = complete_frags(elem)
1559
1690
  unless (jd = valid_date_frags?(elem, sg)) &&
1560
- (fr = valid_time_frags?(elem))
1691
+ (fr = valid_time_frags?(elem))
1561
1692
  raise ArgumentError, 'invalid date'
1562
1693
  end
1563
1694
  fr += (elem[:sec_fraction] || 0) / 86400
@@ -1601,48 +1732,78 @@ class DateTime < Date
1601
1732
  # Day Number day 0.
1602
1733
  #
1603
1734
  # +sg+ specifies the Day of Calendar Reform.
1604
- def self.parse(str='-4712-01-01T00:00:00+00:00', comp=false, sg=ITALY)
1735
+ def self.parse(str='-4712-01-01T00:00:00+00:00', comp=true, sg=ITALY)
1605
1736
  elem = _parse(str, comp)
1606
1737
  new_by_frags(elem, sg)
1607
1738
  end
1608
1739
 
1609
- public :hour, :min, :sec, :sec_fraction, :zone, :offset, :new_offset
1740
+ def self.iso8601(str='-4712-01-01T00:00:00+00:00', sg=ITALY) # :nodoc:
1741
+ elem = _iso8601(str)
1742
+ new_by_frags(elem, sg)
1743
+ end
1744
+
1745
+ def self.rfc3339(str='-4712-01-01T00:00:00+00:00', sg=ITALY) # :nodoc:
1746
+ elem = _rfc3339(str)
1747
+ new_by_frags(elem, sg)
1748
+ end
1749
+
1750
+ def self.xmlschema(str='-4712-01-01T00:00:00+00:00', sg=ITALY) # :nodoc:
1751
+ elem = _xmlschema(str)
1752
+ new_by_frags(elem, sg)
1753
+ end
1754
+
1755
+ def self.rfc2822(str='Mon, 1 Jan -4712 00:00:00 +0000', sg=ITALY) # :nodoc:
1756
+ elem = _rfc2822(str)
1757
+ new_by_frags(elem, sg)
1758
+ end
1759
+
1760
+ class << self; alias_method :rfc822, :rfc2822 end
1761
+
1762
+ def self.httpdate(str='Mon, 01 Jan -4712 00:00:00 GMT', sg=ITALY) # :nodoc:
1763
+ elem = _httpdate(str)
1764
+ new_by_frags(elem, sg)
1765
+ end
1766
+
1767
+ def self.jisx0301(str='-4712-01-01T00:00:00+00:00', sg=ITALY) # :nodoc:
1768
+ elem = _jisx0301(str)
1769
+ new_by_frags(elem, sg)
1770
+ end
1771
+
1772
+ public :hour, :min, :sec, :sec_fraction, :zone, :offset, :new_offset,
1773
+ :minute, :second, :second_fraction
1610
1774
 
1611
1775
  def to_s # 4p
1612
1776
  format('%.4d-%02d-%02dT%02d:%02d:%02d%s',
1613
- year, mon, mday, hour, min, sec, zone)
1777
+ year, mon, mday, hour, min, sec, zone)
1614
1778
  end
1615
1779
 
1616
1780
  end
1617
1781
 
1618
1782
  class Time
1619
1783
 
1620
- # def to_time() getlocal end
1784
+ def to_time() getlocal end
1621
1785
 
1622
1786
  def to_date
1623
- jd = Date.civil_to_jd(year, mon, mday, Date::ITALY)
1624
- Date.new!(Date.jd_to_ajd(jd, 0, 0), 0, Date::ITALY)
1787
+ jd = Date.__send__(:civil_to_jd, year, mon, mday, Date::ITALY)
1788
+ Date.new!(Date.__send__(:jd_to_ajd, jd, 0, 0), 0, Date::ITALY)
1625
1789
  end
1626
1790
 
1627
1791
  def to_datetime
1628
- jd = DateTime.civil_to_jd(year, mon, mday, DateTime::ITALY)
1629
- fr = DateTime.time_to_day_fraction(hour, min, [sec, 59].min) +
1630
- Rational(usec, 86400_000_000)
1792
+ jd = DateTime.__send__(:civil_to_jd, year, mon, mday, DateTime::ITALY)
1793
+ fr = DateTime.__send__(:time_to_day_fraction, hour, min, [sec, 59].min) +
1794
+ Rational(subsec, 86400)
1631
1795
  of = Rational(utc_offset, 86400)
1632
- DateTime.new!(DateTime.jd_to_ajd(jd, fr, of), of, DateTime::ITALY)
1796
+ DateTime.new!(DateTime.__send__(:jd_to_ajd, jd, fr, of),
1797
+ of, DateTime::ITALY)
1633
1798
  end
1634
1799
 
1635
- private :to_date, :to_datetime
1636
-
1637
1800
  end
1638
1801
 
1639
1802
  class Date
1640
1803
 
1641
- =begin
1642
1804
  def to_time() Time.local(year, mon, mday) end
1643
1805
  def to_date() self end
1644
- def to_datetime() DateTime.new!(self.class.jd_to_ajd(jd, 0, 0), @of, @sg) end
1645
- =end
1806
+ def to_datetime() DateTime.new!(jd_to_ajd(jd, 0, 0), @of, @sg) end
1646
1807
 
1647
1808
  # Create a new Date object representing today.
1648
1809
  #
@@ -1660,7 +1821,7 @@ class Date
1660
1821
  t = Time.now
1661
1822
  jd = civil_to_jd(t.year, t.mon, t.mday, sg)
1662
1823
  fr = time_to_day_fraction(t.hour, t.min, [t.sec, 59].min) +
1663
- Rational(t.usec, 86400_000_000)
1824
+ Rational(t.subsec, 86400)
1664
1825
  of = Rational(t.utc_offset, 86400)
1665
1826
  new!(jd_to_ajd(jd, fr, of), of, sg)
1666
1827
  end
@@ -1671,95 +1832,19 @@ end
1671
1832
 
1672
1833
  class DateTime < Date
1673
1834
 
1674
- =begin
1675
1835
  def to_time
1676
1836
  d = new_offset(0)
1677
1837
  d.instance_eval do
1678
- Time.utc(year, mon, mday, hour, min, sec,
1679
- (sec_fraction * 86400000000).to_i)
1838
+ Time.utc(year, mon, mday, hour, min, sec +
1839
+ sec_fraction)
1680
1840
  end.
1681
- getlocal
1841
+ getlocal
1682
1842
  end
1683
1843
 
1684
- def to_date() Date.new!(self.class.jd_to_ajd(jd, 0, 0), 0, @sg) end
1844
+ def to_date() Date.new!(jd_to_ajd(jd, 0, 0), 0, @sg) end
1685
1845
  def to_datetime() self end
1686
- =end
1687
1846
 
1688
1847
  private_class_method :today
1689
1848
  public_class_method :now
1690
1849
 
1691
1850
  end
1692
-
1693
- class Date
1694
-
1695
- class << self
1696
-
1697
- def deprecated_class_method_alias(old, new) # :nodoc:
1698
- module_eval <<-"end;"
1699
- class << self
1700
- def #{old}(*args, &block)
1701
- if $VERBOSE
1702
- warn("\#{caller.shift.sub(/:in .*/, '')}: " \
1703
- "warning: \#{self}::#{old} is deprecated; " \
1704
- "use \#{self}::#{new}")
1705
- end
1706
- #{new}(*args, &block)
1707
- end
1708
- end
1709
- end;
1710
- end
1711
-
1712
- private :deprecated_class_method_alias
1713
-
1714
- def deprecated_alias(old, new) # :nodoc:
1715
- module_eval <<-"end;"
1716
- def #{old}(*args, &block)
1717
- if $VERBOSE
1718
- warn("\#{caller.shift.sub(/:in .*/, '')}: " \
1719
- "warning: \#{self.class}\##{old} is deprecated; " \
1720
- "use \#{self.class}\##{new}")
1721
- end
1722
- #{new}(*args, &block)
1723
- end
1724
- end;
1725
- end
1726
-
1727
- private :deprecated_alias
1728
-
1729
- end
1730
-
1731
- [ %w(os? julian?),
1732
- %w(ns? gregorian?),
1733
- %w(exist1? valid_jd?),
1734
- %w(exist2? valid_ordinal?),
1735
- %w(exist3? valid_date?),
1736
- %w(exist? valid_date?),
1737
- %w(existw? valid_commercial?),
1738
- %w(new0 new!),
1739
- %w(new1 jd),
1740
- %w(new2 ordinal),
1741
- %w(new3 new),
1742
- %w(neww commercial)
1743
- ].each do |old, new|
1744
- deprecated_class_method_alias(old, new)
1745
- end
1746
-
1747
- [ %w(os? julian?),
1748
- %w(ns? gregorian?),
1749
- %w(sg start),
1750
- %w(newsg new_start),
1751
- %w(of offset),
1752
- %w(newof new_offset)
1753
- ].each do |old, new|
1754
- deprecated_alias(old, new)
1755
- end
1756
-
1757
- private :of, :newof
1758
-
1759
- end
1760
-
1761
- class DateTime < Date
1762
-
1763
- public :of, :newof
1764
-
1765
- end