rubysl-date 1.0.1 → 2.0.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.
- checksums.yaml +4 -4
- data/.travis.yml +7 -5
- data/lib/date/delta.rb +431 -0
- data/lib/date/delta/parser.rb +301 -0
- data/lib/date/delta/parser.ry +84 -0
- data/lib/date/format.rb +672 -551
- data/lib/rubysl/date/date.rb +653 -568
- data/lib/rubysl/date/version.rb +1 -1
- data/rubysl-date.gemspec +3 -0
- data/spec/date/relationship_spec.rb +1 -1
- metadata +36 -19
data/lib/rubysl/date/date.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
#
|
2
2
|
# date.rb - date and time library
|
3
3
|
#
|
4
|
-
# Author: Tadayoshi Funaba 1998-
|
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.
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
361
|
-
if julian?(jd, sg)
|
362
|
-
then JULIAN
|
363
|
-
else GREGORIAN end
|
364
|
-
end
|
332
|
+
private
|
365
333
|
|
366
|
-
|
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
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
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
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
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
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
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
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
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
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
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
|
-
|
426
|
-
|
427
|
-
d
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
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
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
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
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
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
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
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
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
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
|
-
|
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
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
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
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
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
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
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
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
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
|
-
|
520
|
-
|
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
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
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
|
-
|
533
|
-
|
534
|
-
|
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
|
-
|
537
|
-
|
538
|
-
|
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
|
-
|
541
|
-
|
542
|
-
|
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
|
-
|
545
|
-
|
546
|
-
|
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
|
-
|
549
|
-
|
550
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
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 =
|
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 =
|
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 =
|
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
|
767
|
-
#
|
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
|
771
|
-
unless jd =
|
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
|
778
|
-
unless jd =
|
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
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
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
|
-
|
831
|
-
|
902
|
+
elem[:year] ||= d.year
|
903
|
+
elem[:yday] ||= 1
|
832
904
|
when :civil
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
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
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
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
|
-
|
919
|
+
elem[:jd] ||= (d - d.wday + elem[:wday]).jd
|
848
920
|
when :wnum0
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
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
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
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
|
-
|
868
|
-
|
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] =
|
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
|
-
|
887
|
-
|
888
|
-
|
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
|
-
|
894
|
-
|
895
|
-
|
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
|
-
|
901
|
-
|
902
|
-
|
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
|
-
|
979
|
+
a[2] = elem[:wday].nonzero? || 7
|
908
980
|
end
|
909
981
|
if a.all?
|
910
|
-
|
911
|
-
|
912
|
-
|
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
|
-
|
989
|
+
a[2] = elem[:cwday] % 7
|
918
990
|
end
|
919
991
|
if a.all?
|
920
|
-
|
921
|
-
|
922
|
-
|
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
|
-
|
999
|
+
a[2] = (a[2] - 1) % 7
|
928
1000
|
end
|
929
1001
|
if a[2].nil? && elem[:cwday]
|
930
|
-
|
1002
|
+
a[2] = (elem[:cwday] - 1) % 7
|
931
1003
|
end
|
932
1004
|
if a.all?
|
933
|
-
|
934
|
-
|
935
|
-
|
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
|
-
|
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=
|
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
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
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)
|
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()
|
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()
|
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()
|
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()
|
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()
|
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()
|
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()
|
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()
|
1176
|
+
def commercial() jd_to_commercial(jd, @sg) end # :nodoc:
|
1070
1177
|
|
1071
|
-
def weeknum0()
|
1072
|
-
def weeknum1()
|
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()
|
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
|
-
|
1121
|
-
|
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()
|
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
|
-
|
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? ()
|
1274
|
+
def julian? () jd < @sg end
|
1161
1275
|
|
1162
1276
|
# Is the current date new-style (Gregorian Calendar)?
|
1163
|
-
def gregorian? ()
|
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
|
-
|
1178
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
1372
|
-
|
1373
|
-
# def self._load(str) new!(*Marshal.load(str)) end
|
1499
|
+
def marshal_dump() [@ajd, @of, @sg] end
|
1374
1500
|
|
1375
|
-
# Load from
|
1376
|
-
def
|
1377
|
-
|
1378
|
-
|
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+.
|
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 =
|
1456
|
-
|
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 =
|
1481
|
-
|
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 =
|
1506
|
-
|
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
|
1530
|
-
#
|
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
|
1533
|
-
unless (jd =
|
1534
|
-
|
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
|
1544
|
-
unless (jd =
|
1545
|
-
|
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
|
-
|
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=
|
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
|
-
|
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
|
-
|
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
|
-
|
1784
|
+
def to_time() getlocal end
|
1621
1785
|
|
1622
1786
|
def to_date
|
1623
|
-
jd = Date.civil_to_jd
|
1624
|
-
Date.new!(Date.jd_to_ajd
|
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
|
1629
|
-
fr = DateTime.time_to_day_fraction
|
1630
|
-
|
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
|
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!(
|
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.
|
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
|
-
|
1838
|
+
Time.utc(year, mon, mday, hour, min, sec +
|
1839
|
+
sec_fraction)
|
1680
1840
|
end.
|
1681
|
-
|
1841
|
+
getlocal
|
1682
1842
|
end
|
1683
1843
|
|
1684
|
-
def to_date() Date.new!(
|
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
|