| Class | Date |
| In: |
date.rb
date/format.rb yaml/rubytypes.rb |
| Parent: | Object |
Class representing a date.
See the documentation to the file date.rb for an overview.
Internally, the date is represented as an Astronomical Julian Day Number, ajd. The Day of Calendar Reform, sg, is also stored, for conversions to other date formats. (There is also an of field for a time zone offset, but this is only for the use of the DateTime subclass.)
A new Date object is created using one of the object creation class methods named after the corresponding date format, and the arguments appropriate to that date format; for instance, Date::civil() (aliased to Date::new()) with year, month, and day-of-month, or Date::ordinal() with year and day-of-year. All of these object creation class methods also take the Day of Calendar Reform as an optional argument.
Date objects are immutable once created.
Once a Date has been created, date values can be retrieved for the different date formats supported using instance methods. For instance, mon() gives the Civil month, cwday() gives the Commercial day of the week, and yday() gives the Ordinal day of the year. Date values can be retrieved in any format, regardless of what format was used to create the Date instance.
The Date class includes the Comparable module, allowing date objects to be compared and sorted, ranges of dates to be created, and so forth.
Methods
Included Modules
Constants
| MONTHNAMES | = | [nil] + %w(January February March April May June July August September October November December) | Full month names, in English. Months count from 1 to 12; a month’s numerical representation indexed into this array gives the name of that month (hence the first element is nil). | |
| DAYNAMES | = | %w(Sunday Monday Tuesday Wednesday Thursday Friday Saturday) | Full names of days of the week, in English. Days of the week count from 0 to 6 (except in the commercial week); a day’s numerical representation indexed into this array gives the name of that day. | |
| ABBR_MONTHNAMES | = | [nil] + %w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) | Abbreviated month names, in English. | |
| ABBR_DAYNAMES | = | %w(Sun Mon Tue Wed Thu Fri Sat) | Abbreviated day names, in English. | |
| ITALY | = | 2299161 | The Julian Day Number of the Day of Calendar Reform for Italy and the Catholic countries. | |
| ENGLAND | = | 2361222 | The Julian Day Number of the Day of Calendar Reform for England and her Colonies. | |
| JULIAN | = | false | A constant used to indicate that a Date should always use the Julian calendar. | |
| GREGORIAN | = | true | A constant used to indicate that a Date should always use the Gregorian calendar. | |
| MONTHS | = | { 'january' => 1, 'february' => 2, 'march' => 3, 'april' => 4, 'may' => 5, 'june' => 6, 'july' => 7, 'august' => 8, 'september'=> 9, 'october' =>10, 'november' =>11, 'december' =>12 | ||
| DAYS | = | { 'sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday'=> 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6 | ||
| ABBR_MONTHS | = | { 'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4, 'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8, 'sep' => 9, 'oct' =>10, 'nov' =>11, 'dec' =>12 | ||
| ABBR_DAYS | = | { 'sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3, 'thu' => 4, 'fri' => 5, 'sat' => 6 | ||
| ZONES | = | { 'ut' => 0*3600, 'gmt' => 0*3600, 'est' => -5*3600, 'edt' => -4*3600, 'cst' => -6*3600, 'cdt' => -5*3600, 'mst' => -7*3600, 'mdt' => -6*3600, 'pst' => -8*3600, 'pdt' => -7*3600, 'a' => 1*3600, 'b' => 2*3600, 'c' => 3*3600, 'd' => 4*3600, 'e' => 5*3600, 'f' => 6*3600, 'g' => 7*3600, 'h' => 8*3600, 'i' => 9*3600, 'k' => 10*3600, 'l' => 11*3600, 'm' => 12*3600, 'n' => -1*3600, 'o' => -2*3600, 'p' => -3*3600, 'q' => -4*3600, 'r' => -5*3600, 's' => -6*3600, 't' => -7*3600, 'u' => -8*3600, 'v' => -9*3600, 'w' =>-10*3600, 'x' =>-11*3600, 'y' =>-12*3600, 'z' => 0*3600, 'utc' => 0*3600, 'wet' => 0*3600, 'bst' => 1*3600, 'wat' => -1*3600, 'at' => -2*3600, 'ast' => -4*3600, 'adt' => -3*3600, 'yst' => -9*3600, 'ydt' => -8*3600, 'hst' =>-10*3600, 'hdt' => -9*3600, 'cat' =>-10*3600, 'ahst'=>-10*3600, 'nt' =>-11*3600, 'idlw'=>-12*3600, 'cet' => 1*3600, 'met' => 1*3600, 'mewt'=> 1*3600, 'mest'=> 2*3600, 'mesz'=> 2*3600, 'swt' => 1*3600, 'sst' => 2*3600, 'fwt' => 1*3600, 'fst' => 2*3600, 'eet' => 2*3600, 'bt' => 3*3600, 'zp4' => 4*3600, 'zp5' => 5*3600, 'zp6' => 6*3600, 'wast'=> 7*3600, 'wadt'=> 8*3600, 'cct' => 8*3600, 'jst' => 9*3600, 'east'=> 10*3600, 'eadt'=> 11*3600, 'gst' => 10*3600, 'nzt' => 12*3600, 'nzst'=> 12*3600, 'nzdt'=> 13*3600, 'idle'=> 12*3600 | ||
| PARSE_MONTHPAT | = | ABBR_MONTHS.keys.join('|') | ||
| PARSE_DAYPAT | = | ABBR_DAYS. keys.join('|') |
External Aliases
| gregorian_leap? | -> | leap? |
| new | -> | new0 |
| valid_civil? | -> | valid_date? |
| civil | -> | new |
Public Class methods
Load from Marshall format.
# File date.rb, line 1032
1032: def self._load(str)
1033: a = Marshal.load(str)
1034: if a.size == 2
1035: ajd, sg = a
1036: of = 0
1037: ajd -= 1.to_r/2
1038: else
1039: ajd, of, sg = a
1040: end
1041: new0(ajd, of, sg)
1042: end
# File date/format.rb, line 250
250: def self._parse(str, comp=false)
251: str = str.dup
252:
253: str.gsub!(/[^-+,.\/:0-9a-z]+/ino, ' ')
254:
255: # day
256: if str.sub!(/(#{PARSE_DAYPAT})\S*/ino, ' ')
257: wday = ABBR_DAYS[$1.downcase]
258: end
259:
260: # time
261: if str.sub!(
262: /(\d+):(\d+)
263: (?:
264: :(\d+)(?:[,.](\d*))?
265: )?
266: (?:
267: \s*
268: ([ap])(?:m\b|\.m\.)
269: )?
270: (?:
271: \s*
272: (
273: [a-z]+(?:\s+dst)?\b
274: |
275: [-+]\d+(?::?\d+)
276: )
277: )?
278: /inox,
279: ' ')
280: hour = $1.to_i
281: min = $2.to_i
282: sec = $3.to_i if $3
283: if $4
284: sec_fraction = $4.to_i.to_r / (10**$4.size)
285: end
286:
287: if $5
288: hour %= 12
289: if $5.downcase == 'p'
290: hour += 12
291: end
292: end
293:
294: if $6
295: zone = $6
296: end
297: end
298:
299: # eu
300: if str.sub!(
301: /(\d+)\S*
302: \s+
303: (#{PARSE_MONTHPAT})\S*
304: (?:
305: \s+
306: (-?\d+)
307: )?
308: /inox,
309: ' ')
310: mday = $1.to_i
311: mon = ABBR_MONTHS[$2.downcase]
312:
313: if $3
314: year = $3.to_i
315: if $3.size > 2
316: comp = false
317: end
318: end
319:
320: # us
321: elsif str.sub!(
322: /(#{PARSE_MONTHPAT})\S*
323: \s+
324: (\d+)\S*
325: (?:
326: \s+
327: (-?\d+)
328: )?
329: /inox,
330: ' ')
331: mon = ABBR_MONTHS[$1.downcase]
332: mday = $2.to_i
333:
334: if $3
335: year = $3.to_i
336: if $3.size > 2
337: comp = false
338: end
339: end
340:
341: # iso
342: elsif str.sub!(/([-+]?\d+)-(\d+)-(-?\d+)/no, ' ')
343: year = $1.to_i
344: mon = $2.to_i
345: mday = $3.to_i
346:
347: if $1.size > 2
348: comp = false
349: elsif $3.size > 2
350: comp = false
351: mday, mon, year = year, mon, mday
352: end
353:
354: # jis
355: elsif str.sub!(/([MTSH])(\d+)\.(\d+)\.(\d+)/ino, ' ')
356: e = { 'm'=>1867,
357: 't'=>1911,
358: 's'=>1925,
359: 'h'=>1988
360: }[$1.downcase]
361: year = $2.to_i + e
362: mon = $3.to_i
363: mday = $4.to_i
364:
365: # vms
366: elsif str.sub!(/(-?\d+)-(#{PARSE_MONTHPAT})[^-]*-(-?\d+)/ino, ' ')
367: mday = $1.to_i
368: mon = ABBR_MONTHS[$2.downcase]
369: year = $3.to_i
370:
371: if $1.size > 2
372: comp = false
373: year, mon, mday = mday, mon, year
374: elsif $3.size > 2
375: comp = false
376: end
377:
378: # sla
379: elsif str.sub!(%r|(-?\d+)/(\d+)(?:/(-?\d+))?|no, ' ')
380: mon = $1.to_i
381: mday = $2.to_i
382:
383: if $3
384: year = $3.to_i
385: if $3.size > 2
386: comp = false
387: end
388: end
389:
390: if $3 && $1.size > 2
391: comp = false
392: year, mon, mday = mon, mday, year
393: end
394:
395: # ddd
396: elsif str.sub!(
397: /([-+]?)(\d{4,14})
398: (?:
399: \s*
400: T?
401: \s*
402: (\d{2,6})(?:[,.](\d*))?
403: )?
404: (?:
405: \s*
406: (
407: Z
408: |
409: [-+]\d{2,4}
410: )
411: \b
412: )?
413: /inox,
414: ' ')
415: case $2.size
416: when 4
417: mon = $2[ 0, 2].to_i
418: mday = $2[ 2, 2].to_i
419: when 6
420: year = ($1 + $2[ 0, 2]).to_i
421: mon = $2[ 2, 2].to_i
422: mday = $2[ 4, 2].to_i
423: when 8, 10, 12, 14
424: year = ($1 + $2[ 0, 4]).to_i
425: mon = $2[ 4, 2].to_i
426: mday = $2[ 6, 2].to_i
427: hour = $2[ 8, 2].to_i if $2.size >= 10
428: min = $2[10, 2].to_i if $2.size >= 12
429: sec = $2[12, 2].to_i if $2.size >= 14
430: comp = false
431: end
432: if $3
433: case $3.size
434: when 2, 4, 6
435: hour = $3[ 0, 2].to_i
436: min = $3[ 2, 2].to_i if $3.size >= 4
437: sec = $3[ 4, 2].to_i if $3.size >= 6
438: end
439: end
440: if $4
441: sec_fraction = $4.to_i.to_r / (10**$4.size)
442: end
443: if $5
444: zone = $5
445: end
446: end
447:
448: if str.sub!(/\b(bc\b|bce\b|b\.c\.|b\.c\.e\.)/ino, ' ')
449: if year
450: year = -year + 1
451: end
452: end
453:
454: if comp and year
455: if year >= 0 and year <= 99
456: if year >= 69
457: year += 1900
458: else
459: year += 2000
460: end
461: end
462: end
463:
464: elem = {}
465: elem[:year] = year if year
466: elem[:mon] = mon if mon
467: elem[:mday] = mday if mday
468: elem[:hour] = hour if hour
469: elem[:min] = min if min
470: elem[:sec] = sec if sec
471: elem[:sec_fraction] = sec_fraction if sec_fraction
472: elem[:zone] = zone if zone
473: offset = zone_to_diff(zone) if zone
474: elem[:offset] = offset if offset
475: elem[:wday] = wday if wday
476: elem
477: end
# File date/format.rb, line 242
242: def self._strptime(str, fmt='%F')
243: elem = {}
244: elem if __strptime(str.dup, fmt, elem)
245: end
Convert an Astronomical Julian Day Number to an Astronomical Modified Julian Day Number.
# File date.rb, line 448
448: def self.ajd_to_amjd(ajd) ajd - 4800001.to_r/2 end
Convert an Astronomical Julian Day Number to a (civil) Julian Day Number.
ajd is the Astronomical Julian Day Number to convert. of is the offset from UTC as a fraction of a day (defaults to 0).
Returns the (civil) Julian Day Number as [day_number, fraction] where fraction is always 1/2.
# File date.rb, line 414
414: def self.ajd_to_jd(ajd, of=0) clfloor(ajd + of + 1.to_r/2) end
Convert an Astronomical Modified Julian Day Number to an Astronomical Julian Day Number.
# File date.rb, line 444
444: def self.amjd_to_ajd(amjd) amjd + 4800001.to_r/2 end
Create a new Date object for the Civil Date specified by year y, month m, and day-of-month d.
m and d can be negative, in which case they count backwards from the end of the year and the end of the month respectively. No wraparound is performed, however, and invalid values cause an ArgumentError to be raised. can be negative
y defaults to -4712, m to 1, and d to 1; this is Julian Day Number day 0.
sg specifies the Day of Calendar Reform.
# File date.rb, line 590
590: def self.civil(y=-4712, m=1, d=1, sg=ITALY)
591: unless jd = valid_civil?(y, m, d, sg)
592: raise ArgumentError, 'invalid date'
593: end
594: new0(jd_to_ajd(jd, 0, 0), 0, sg)
595: end
Convert a Civil Date to a Julian Day Number. y, m, and d are the year, month, and day of the month. sg specifies the Day of Calendar Reform.
Returns the corresponding Julian Day Number.
# File date.rb, line 295
295: def self.civil_to_jd(y, m, d, sg=GREGORIAN)
296: if m <= 2
297: y -= 1
298: m += 12
299: end
300: a = (y / 100.0).floor
301: b = 2 - a + (a / 4.0).floor
302: jd = (365.25 * (y + 4716)).floor +
303: (30.6001 * (m + 1)).floor +
304: d + b - 1524
305: if os?(jd, sg)
306: jd -= b
307: end
308: jd
309: end
Create a new Date object for the Commercial Date specified by year y, week-of-year w, and day-of-week d.
Monday is day-of-week 1; Sunday is day-of-week 7.
w and d can be negative, in which case they count backwards from the end of the year and the end of the week respectively. No wraparound is performed, however, and invalid values cause an ArgumentError to be raised.
y defaults to 1582, w to 41, and d to 5, the Day of Calendar Reform for Italy and the Catholic countries.
sg specifies the Day of Calendar Reform.
# File date.rb, line 640
640: def self.commercial(y=1582, w=41, d=5, sg=ITALY)
641: unless jd = valid_commercial?(y, w, d, sg)
642: raise ArgumentError, 'invalid date'
643: end
644: new0(jd_to_ajd(jd, 0, 0), 0, sg)
645: end
Convert a Commercial Date to a Julian Day Number.
y, w, and d are the (commercial) year, week of the year, and day of the week of the Commercial Date to convert. sg specifies the Day of Calendar Reform.
# File date.rb, line 384
384: def self.commercial_to_jd(y, w, d, ns=GREGORIAN)
385: jd = civil_to_jd(y, 1, 4, ns)
386: (jd - (((jd - 1) + 1) % 7)) +
387: 7 * (w - 1) +
388: (d - 1)
389: end
Convert a fractional day fr to [hours, minutes, seconds, fraction_of_a_second]
# File date.rb, line 429
429: def self.day_fraction_to_time(fr)
430: h, fr = clfloor(fr, 1.to_r/24)
431: min, fr = clfloor(fr, 1.to_r/1440)
432: s, fr = clfloor(fr, 1.to_r/86400)
433: return h, min, s, fr
434: end
Is a year a leap year in the Gregorian calendar?
All years divisible by 4 are leap years in the Gregorian calendar, except for years divisible by 100 and not by 400.
# File date.rb, line 480
480: def self.gregorian_leap? (y) y % 4 == 0 and y % 100 != 0 or y % 400 == 0 end
Convert a (civil) Julian Day Number to an Astronomical Julian Day Number.
jd is the Julian Day Number to convert, and fr is a fractional day. of is the offset from UTC as a fraction of a day (defaults to 0).
Returns the Astronomical Julian Day Number as a single numeric value.
# File date.rb, line 425
425: def self.jd_to_ajd(jd, fr, of=0) jd + fr - of - 1.to_r/2 end
Convert a Julian Day Number to a Civil Date. jd is the Julian Day Number. sg specifies the Day of Calendar Reform.
Returns the corresponding [year, month, day_of_month] as a three-element array.
# File date.rb, line 317
317: def self.jd_to_civil(jd, sg=GREGORIAN)
318: if os?(jd, sg)
319: a = jd
320: else
321: x = ((jd - 1867216.25) / 36524.25).floor
322: a = jd + 1 + x - (x / 4.0).floor
323: end
324: b = a + 1524
325: c = ((b - 122.1) / 365.25).floor
326: d = (365.25 * c).floor
327: e = ((b - d) / 30.6001).floor
328: dom = b - d - (30.6001 * e).floor
329: if e <= 13
330: m = e - 1
331: y = c - 4716
332: else
333: m = e - 13
334: y = c - 4715
335: end
336: return y, m, dom
337: end
Convert a Julian Day Number to a Commercial Date
jd is the Julian Day Number to convert. sg specifies the Day of Calendar Reform.
Returns the corresponding Commercial Date as [commercial_year, week_of_year, day_of_week]
# File date.rb, line 369
369: def self.jd_to_commercial(jd, sg=GREGORIAN)
370: ns = ns?(jd, sg)
371: a = jd_to_civil(jd - 3, ns)[0]
372: y = if jd >= commercial_to_jd(a + 1, 1, 1, ns) then a + 1 else a end
373: w = 1 + (jd - commercial_to_jd(y, 1, 1, ns)) / 7
374: d = (jd + 1) % 7
375: if d.zero? then d = 7 end
376: return y, w, d
377: end
Convert a Julian Day Number to the number of days since the adoption of the Gregorian Calendar (in Italy).
# File date.rb, line 464
464: def self.jd_to_ld(jd) jd - 2299160 end
Convert a Julian Day Number to a Modified Julian Day Number.
# File date.rb, line 456
456: def self.jd_to_mjd(jd) jd - 2400001 end
Convert a Julian Day Number to an Ordinal Date.
jd is the Julian Day Number to convert. sg specifies the Day of Calendar Reform.
Returns the corresponding Ordinal Date as [year, day_of_year]
# File date.rb, line 356
356: def self.jd_to_ordinal(jd, sg=GREGORIAN)
357: y = jd_to_civil(jd, sg)[0]
358: doy = jd - civil_to_jd(y - 1, 12, 31, ns?(jd, sg))
359: return y, doy
360: end
Convert a Julian Day Number to the day of the week.
Sunday is day-of-week 0; Saturday is day-of-week 6.
# File date.rb, line 469
469: def self.jd_to_wday(jd) (jd + 1) % 7 end
Is a year a leap year in the Julian calendar?
All years divisible by 4 are leap years in the Julian calendar.
# File date.rb, line 474
474: def self.julian_leap? (y) y % 4 == 0 end
Convert a count of the number of days since the adoption of the Gregorian Calendar (in Italy) to a Julian Day Number.
# File date.rb, line 460
460: def self.ld_to_jd(ld) ld + 2299160 end
Convert a Modified Julian Day Number to a Julian Day Number.
# File date.rb, line 452
452: def self.mjd_to_jd(mjd) mjd + 2400001 end
NOTE this is the documentation for the method new0(). If you are reading this as the documentation for new(), that is because rdoc doesn’t fully support the aliasing of the initialize() method. new() is in fact an alias for civil(): read the documentation for that method instead.
Create a new Date object.
ajd is the Astronomical Julian Day Number. of is the offset from UTC as a fraction of a day. Both default to 0.
sg specifies the Day of Calendar Reform to use for this Date object.
Using one of the factory methods such as Date::civil is generally easier and safer.
# File date.rb, line 751
751: def initialize(ajd=0, of=0, sg=ITALY) @ajd, @of, @sg = ajd, of, sg end
Does a given Julian Day Number fall inside the new-style (Gregorian) calendar?
The reverse of self.os? See the documentation for that method for more details.
# File date.rb, line 288
288: def self.ns? (jd, sg) not os?(jd, sg) end
Create a new Date object from an Ordinal Date, specified by year y and day-of-year d. d can be negative, in which it counts backwards from the end of the year. No year wraparound is performed, however. An invalid value for d results in an ArgumentError being raised.
y defaults to -4712, and d to 1; this is Julian Day Number day 0.
sg specifies the Day of Calendar Reform.
# File date.rb, line 538
538: def self.ordinal(y=-4712, d=1, sg=ITALY)
539: unless jd = valid_ordinal?(y, d, sg)
540: raise ArgumentError, 'invalid date'
541: end
542: new0(jd_to_ajd(jd, 0, 0), 0, sg)
543: end
Convert an Ordinal Date to a Julian Day Number.
y and d are the year and day-of-year to convert. sg specifies the Day of Calendar Reform.
Returns the corresponding Julian Day Number.
# File date.rb, line 345
345: def self.ordinal_to_jd(y, d, sg=GREGORIAN)
346: civil_to_jd(y, 1, d, sg)
347: end
Does a given Julian Day Number fall inside the old-style (Julian) calendar?
jd is the Julian Day Number in question. sg may be Date::GREGORIAN, in which case the answer is false; it may be Date::JULIAN, in which case the answer is true; or it may a number representing the Day of Calendar Reform. Date::ENGLAND and Date::ITALY are two possible such days.
# File date.rb, line 276
276: def self.os? (jd, sg)
277: case sg
278: when Numeric; jd < sg
279: else; not sg
280: end
281: end
Create a new Date object by parsing from a String, without specifying the format.
str is a String holding a date representation. comp specifies whether to interpret 2-digit years as 19XX (>= 69) or 20XX (< 69); the default is not to. The method will attempt to parse a date from the String using various heuristics; see _parse in date/format.rb for more details. If parsing fails, an ArgumentError will be raised.
The default str is ’-4712-01-01’; this is Julian Day Number day 0.
sg specifies the Day of Calendar Reform.
# File date.rb, line 694
694: def self.parse(str='-4712-01-01', comp=false, sg=ITALY)
695: elem = _parse(str, comp)
696: new_with_hash(elem, sg)
697: end
Create a new Date object by parsing from a String according to a specified format.
str is a String holding a date representation. fmt is the format that the date is in. See date/format.rb for details on supported formats.
The default str is ’-4712-01-01’, and the default fmt is ’%F’, which means Year-Month-Day_of_Month. This gives Julian Day Number day 0.
sg specifies the Day of Calendar Reform.
An ArgumentError will be raised if str cannot be parsed.
# File date.rb, line 674
674: def self.strptime(str='-4712-01-01', fmt='%F', sg=ITALY)
675: elem = _strptime(str, fmt)
676: new_with_hash(elem, sg)
677: end
Convert an h hour, min minutes, s seconds period to a fractional day.
# File date.rb, line 438
438: def self.time_to_day_fraction(h, min, s)
439: h.to_r/24 + min.to_r/1440 + s.to_r/86400
440: end
Do year y, month m, and day-of-month d make a valid Civil Date? Returns the corresponding Julian Day Number if they do, nil if they don’t.
m and d can be negative, in which case they count backwards from the end of the year and the end of the month respectively. No wraparound is performed, however, and invalid values cause an ArgumentError to be raised. A date falling in the period skipped in the Day of Calendar Reform adjustment is not valid.
sg specifies the Day of Calendar Reform.
# File date.rb, line 557
557: def self.valid_civil? (y, m, d, sg=ITALY)
558: if m < 0
559: m += 13
560: end
561: if d < 0
562: ny, nm = clfloor(y * 12 + m, 12)
563: nm, = clfloor(nm + 1, 1)
564: jd = civil_to_jd(ny, nm, d + 1, sg)
565: ns = ns?(jd, sg)
566: return unless [y, m] == jd_to_civil(jd, sg)[0..1]
567: return unless [ny, nm, 1] == jd_to_civil(jd - d, ns)
568: else
569: jd = civil_to_jd(y, m, d, sg)
570: return unless [y, m, d] == jd_to_civil(jd, sg)
571: end
572: jd
573: end
Do year y, week-of-year w, and day-of-week d make a valid Commercial Date? Returns the corresponding Julian Day Number if they do, nil if they don’t.
Monday is day-of-week 1; Sunday is day-of-week 7.
w and d can be negative, in which case they count backwards from the end of the year and the end of the week respectively. No wraparound is performed, however, and invalid values cause an ArgumentError to be raised. A date falling in the period skipped in the Day of Calendar Reform adjustment is not valid.
sg specifies the Day of Calendar Reform.
# File date.rb, line 613
613: def self.valid_commercial? (y, w, d, sg=ITALY)
614: if d < 0
615: d += 8
616: end
617: if w < 0
618: w = jd_to_commercial(commercial_to_jd(y + 1, 1, 1) + w * 7)[1]
619: end
620: jd = commercial_to_jd(y, w, d)
621: return unless ns?(jd, sg)
622: return unless [y, w, d] == jd_to_commercial(jd)
623: jd
624: end
Is jd a valid Julian Day Number?
If it is, returns it. In fact, any value is treated as a valid Julian Day Number.
# File date.rb, line 489
489: def self.valid_jd? (jd, sg=ITALY) jd end
Do the year y and day-of-year d make a valid Ordinal Date? Returns the corresponding Julian Day Number if they do, or nil if they don’t.
d can be a negative number, in which case it counts backwards from the end of the year (-1 being the last day of the year). No year wraparound is performed, however, so valid values of d are -365 .. -1, 1 .. 365 on a non-leap-year, -366 .. -1, 1 .. 366 on a leap year. A date falling in the period skipped in the Day of Calendar Reform adjustment is not valid.
sg specifies the Day of Calendar Reform.
# File date.rb, line 514
514: def self.valid_ordinal? (y, d, sg=ITALY)
515: if d < 0
516: ny, = clfloor(y + 1, 1)
517: jd = ordinal_to_jd(ny, d + 1, sg)
518: ns = ns?(jd, sg)
519: return unless [y] == jd_to_ordinal(jd, sg)[0..0]
520: return unless [ny, 1] == jd_to_ordinal(jd - d, ns)
521: else
522: jd = ordinal_to_jd(y, d, sg)
523: return unless [y, d] == jd_to_ordinal(jd, sg)
524: end
525: jd
526: end
# File date/format.rb, line 479
479: def self.zone_to_diff(str)
480: abb, dst = str.downcase.split(/\s+/o, 2)
481: if ZONES.include?(abb)
482: offset = ZONES[abb]
483: offset += 3600 if dst
484: elsif /\A([-+])(\d{2}):?(\d{2})?\Z/no =~ str
485: offset = $2.to_i * 3600 + $3.to_i * 60
486: offset *= -1 if $1 == '-'
487: end
488: offset
489: end
Public Instance methods
Return a new Date object that is n days later than the current one.
n may be a negative value, in which case the new Date is earlier than the current one; however, #-() might be more intuitive.
If n is not a Numeric, a TypeError will be thrown. In particular, two Dates cannot be added to each other.
# File date.rb, line 901
901: def + (n)
902: case n
903: when Numeric; return self.class.new0(@ajd + n, @of, @sg)
904: end
905: raise TypeError, 'expected numeric'
906: end
If x is a Numeric value, create a new Date object that is x days earlier than the current one.
If x is a Date, return the number of days between the two dates; or, more precisely, how many days later the current date is than x.
If x is neither Numeric nor a Date, a TypeError is raised.
# File date.rb, line 916
916: def - (x)
917: case x
918: when Numeric; return self.class.new0(@ajd - x, @of, @sg)
919: when Date; return @ajd - x.ajd
920: end
921: raise TypeError, 'expected numeric or date'
922: end
Return a new Date object that is n months earlier than the current one.
If the day-of-the-month of the current Date is greater than the last day of the target month, the day-of-the-month of the returned Date will be the last day of the target month.
# File date.rb, line 977
977: def << (n) self >> -n end
Compare this date with another date.
other can also be a Numeric value, in which case it is interpreted as an Astronomical Julian Day Number.
Comparison is by Astronomical Julian Day Number, including fractional days. This means that both the time and the timezone offset are taken into account when comparing two DateTime instances. When comparing a DateTime instance with a Date instance, the time of the latter will be considered as falling on midnight UTC.
# File date.rb, line 935
935: def <=> (other)
936: case other
937: when Numeric; return @ajd <=> other
938: when Date; return @ajd <=> other.ajd
939: end
940: nil
941: end