class Date

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.

format.rb: Written by Tadayoshi Funaba 1999-2009 $Id: format.rb,v 2.43 2008-01-17 20:16:31+09 tadf Exp $

Constants

ABBR_DAYNAMES

Abbreviated day names, in English.

ABBR_MONTHNAMES

Abbreviated month names, in English.

DAYNAMES

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.

ENGLAND

The Julian Day Number of the Day of Calendar Reform for England and her Colonies.

GREGORIAN

A constant used to indicate that a Date should always use the Gregorian calendar.

ITALY

The Julian Day Number of the Day of Calendar Reform for Italy and the Catholic countries.

JULIAN

A constant used to indicate that a Date should always use the Julian calendar.

MONTHNAMES

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).

Public Class Methods

_parse(str, comp=true) click to toggle source
# File lib/project/format.rb, line 1033
def self._parse(str, comp=true)
  str = str.dup

  e = Format::Bag.new

  e._comp = comp

  str.gsub!(/[^-+',.\/:@[:alnum:]\[\]]+/, ' ')

  _parse_time(str, e) # || _parse_beat(str, e)
  _parse_day(str, e)

  _parse_eu(str, e)     ||
  _parse_us(str, e)     ||
  _parse_iso(str, e)    ||
  _parse_jis(str, e)    ||
  _parse_vms(str, e)    ||
  _parse_sla(str, e)    ||
  _parse_dot(str, e)    ||
  _parse_iso2(str, e)   ||
  _parse_year(str, e)   ||
  _parse_mon(str, e)    ||
  _parse_mday(str, e)   ||
  _parse_ddd(str, e)

  if str.sub!(/\b(bc\b|bce\b|b\.c\.|b\.c\.e\.)/i, ' ')
    if e.year
      e.year = -e.year + 1
    end
  end

  if str.sub!(/\A\s*(\d{1,2})\s*\z/, ' ')
    if e.hour && !e.mday
      v = $1.to_i
      if (1..31) === v
        e.mday = v
      end
    end
    if e.mday && !e.hour
      v = $1.to_i
      if (0..24) === v
        e.hour = v
      end
    end
  end

  if e._comp
    if e.cwyear
      if e.cwyear >= 0 && e.cwyear <= 99
        e.cwyear += if e.cwyear >= 69
                    then 1900 else 2000 end
      end
    end
    if e.year
      if e.year >= 0 && e.year <= 99
        e.year += if e.year >= 69
                  then 1900 else 2000 end
      end
    end
  end

  e.offset ||= zone_to_diff(e.zone) if e.zone

  e.to_hash
end
_strptime(str, fmt='%F') click to toggle source
# File lib/project/format.rb, line 577
def self._strptime(str, fmt='%F')
  str = str.dup
  e = Format::Bag.new
  return unless _strptime_i(str, fmt, e)

  if e._cent
    if e.cwyear
      e.cwyear += e._cent * 100
    end
    if e.year
      e.  year += e._cent * 100
    end
  end

  if e._merid
    if e.hour
      e.hour %= 12
      e.hour += e._merid
    end
  end

  unless str.empty?
    e.leftover = str
  end

  e.to_hash
end
civil(y=-4712, m=1, d=1, sg=ITALY) click to toggle source

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 lib/project/date.rb, line 805
def self.civil(y=-4712, m=1, d=1, sg=ITALY)
  unless jd = _valid_civil?(y, m, d, sg)
    raise ArgumentError, 'invalid date'
  end
  new!(jd_to_ajd(jd, 0, 0), 0, sg)
end
Also aliased as: new
commercial(y=-4712, w=1, d=1, sg=ITALY) click to toggle source

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 -4712, w to 1, and d to 1; this is Julian Day Number day 0.

sg specifies the Day of Calendar Reform.

# File lib/project/date.rb, line 828
def self.commercial(y=-4712, w=1, d=1, sg=ITALY)
  unless jd = _valid_commercial?(y, w, d, sg)
    raise ArgumentError, 'invalid date'
  end
  new!(jd_to_ajd(jd, 0, 0), 0, sg)
end
gregorian_leap?(y) click to toggle source

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 lib/project/date.rb, line 724
def self.gregorian_leap? (y) y % 4 == 0 && y % 100 != 0 || y % 400 == 0 end
Also aliased as: leap?
jd(jd=0, sg=ITALY) click to toggle source

Create a new Date object from a Julian Day Number.

jd is the Julian Day Number; if not specified, it defaults to 0. sg specifies the Day of Calendar Reform.

# File lib/project/date.rb, line 770
def self.jd(jd=0, sg=ITALY)
  jd = _valid_jd?(jd, sg)
  new!(jd_to_ajd(jd, 0, 0), 0, sg)
end
julian_leap?(y) click to toggle source

Is a year a leap year in the Julian calendar?

All years divisible by 4 are leap years in the Julian calendar.

# File lib/project/date.rb, line 718
def self.julian_leap? (y) y % 4 == 0 end
leap?(y)
Alias for: gregorian_leap?
new(y=-4712, m=1, d=1, sg=ITALY)
Also aliased as: new!
Alias for: civil
new(ajd=0, of=0, sg=ITALY) click to toggle source

NOTE this is the documentation for the method new!(). 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 lib/project/date.rb, line 1136
def initialize(ajd=0, of=0, sg=ITALY)
  @ajd, @of, @sg = ajd, of, sg
  @__ca__ = {}
end
new!(y=-4712, m=1, d=1, sg=ITALY)
Alias for: new
ordinal(y=-4712, d=1, sg=ITALY) click to toggle source

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 lib/project/date.rb, line 785
def self.ordinal(y=-4712, d=1, sg=ITALY)
  unless jd = _valid_ordinal?(y, d, sg)
    raise ArgumentError, 'invalid date'
  end
  new!(jd_to_ajd(jd, 0, 0), 0, sg)
end
parse(str='-4712-01-01', comp=true, sg=ITALY) click to toggle source

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 lib/project/date.rb, line 1062
def self.parse(str='-4712-01-01', comp=true, sg=ITALY)
  elem = _parse(str, comp)
  new_by_frags(elem, sg)
end
strptime(str='-4712-01-01', fmt='%F', sg=ITALY) click to toggle source

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 lib/project/date.rb, line 1042
def self.strptime(str='-4712-01-01', fmt='%F', sg=ITALY)
  elem = _strptime(str, fmt)
  new_by_frags(elem, sg)
end
today(sg=ITALY) click to toggle source

Create a new Date object representing today.

sg specifies the Day of Calendar Reform.

# File lib/project/date.rb, line 1806
def self.today(sg=ITALY)
  t = Time.now
  jd = civil_to_jd(t.year, t.mon, t.mday, sg)
  new!(jd_to_ajd(jd, 0, 0), 0, sg)
end
valid_civil?(y, m, d, sg=ITALY) click to toggle source
# File lib/project/date.rb, line 737
def self.valid_civil? (y, m, d, sg=ITALY)
  !!_valid_civil?(y, m, d, sg)
end
Also aliased as: valid_date?
valid_commercial?(y, w, d, sg=ITALY) click to toggle source
# File lib/project/date.rb, line 743
def self.valid_commercial? (y, w, d, sg=ITALY)
  !!_valid_commercial?(y, w, d, sg)
end
valid_date?(y, m, d, sg=ITALY)
Alias for: valid_civil?
valid_jd?(jd, sg=ITALY) click to toggle source
# File lib/project/date.rb, line 729
def self.valid_jd? (jd, sg=ITALY)
  !!_valid_jd?(jd, sg)
end
valid_ordinal?(y, d, sg=ITALY) click to toggle source
# File lib/project/date.rb, line 733
def self.valid_ordinal? (y, d, sg=ITALY)
  !!_valid_ordinal?(y, d, sg)
end

Private Class Methods

now(sg=ITALY) click to toggle source

Create a new DateTime object representing the current time.

sg specifies the Day of Calendar Reform.

# File lib/project/date.rb, line 1815
def self.now(sg=ITALY)
  t = Time.now
  jd = civil_to_jd(t.year, t.mon, t.mday, sg)
  fr = time_to_day_fraction(t.hour, t.min, [t.sec, 59].min) +
    Rational(t.nsec, 86400_000_000_000)
  of = Rational(t.utc_offset, 86400)
  new!(jd_to_ajd(jd, fr, of), of, sg)
end
nth_kday(y=-4712, m=1, n=1, k=1, sg=ITALY) click to toggle source
# File lib/project/date.rb, line 844
def self.nth_kday(y=-4712, m=1, n=1, k=1, sg=ITALY)
  unless jd = _valid_nth_kday?(y, m, n, k, sg)
    raise ArgumentError, 'invalid date'
  end
  new!(jd_to_ajd(jd, 0, 0), 0, sg)
end
s3e(e, y, m, d, bc=false) click to toggle source
# File lib/project/format.rb, line 605
def self.s3e(e, y, m, d, bc=false)
  unless String === m
    m = m.to_s
  end

  if y && m && !d
    y, m, d = d, y, m
  end

  if y == nil
    if d && d.size > 2
      y = d
      d = nil
    end
    if d && d[0,1] == "'"
      y = d
      d = nil
    end
  end

  if y
    y.scan(/(\d+)(.+)?/)
    if $2
      y, d = d, $1
    end
  end

  if m
    if m[0,1] == "'" || m.size > 2
      y, m, d = m, d, y # us -> be
    end
  end

  if d
    if d[0,1] == "'" || d.size > 2
      y, d = d, y
    end
  end

  if y
    y =~ /([-+])?(\d+)/
    if $1 || $2.size > 2
      c = false
    end
    iy = $&.to_i
    if bc
      iy = -iy + 1
    end
    e.year = iy
  end

  if m
    m =~ /\d+/
    e.mon = $&.to_i
  end

  if d
    d =~ /\d+/
    e.mday = $&.to_i
  end

  if c != nil
    e._comp = c
  end

end
weeknum(y=-4712, w=0, d=1, f=0, sg=ITALY) click to toggle source
# File lib/project/date.rb, line 835
def self.weeknum(y=-4712, w=0, d=1, f=0, sg=ITALY)
  unless jd = _valid_weeknum?(y, w, d, f, sg)
    raise ArgumentError, 'invalid date'
  end
  new!(jd_to_ajd(jd, 0, 0), 0, sg)
end

Public Instance Methods

+(n) click to toggle source

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 lib/project/date.rb, line 1334
def + (n)
  case n
  when Numeric; return self.class.new!(@ajd + n, @of, @sg)
  end
  raise TypeError, 'expected numeric'
end
-(x) click to toggle source

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 lib/project/date.rb, line 1349
def - (x)
  case x
  when Numeric; return self.class.new!(@ajd - x, @of, @sg)
  when Date;    return @ajd - x.ajd
  end
  raise TypeError, 'expected numeric or date'
end
<<(n) click to toggle source

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 lib/project/date.rb, line 1433
def << (n) self >> -n end
<=>(other) click to toggle source

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 lib/project/date.rb, line 1368
def <=> (other)
  case other
  when Numeric; return @ajd <=> other
  when Date;    return @ajd <=> other.ajd
  else
    begin
      l, r = other.coerce(self)
      return l <=> r
    rescue NoMethodError
    end
  end
  nil
end
===(other) click to toggle source

The relationship operator for Date.

Compares dates by Julian Day Number. When comparing two DateTime instances, or a DateTime with a Date, the instances will be regarded as equivalent if they fall on the same date in local time.

# File lib/project/date.rb, line 1388
def === (other)
  case other
  when Numeric; return jd == other
  when Date;    return jd == other.jd
  else
    begin
      l, r = other.coerce(self)
      return l === r
    rescue NoMethodError
    end
  end
  false
end
>>(n) click to toggle source

Return a new Date object that is n months later 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 lib/project/date.rb, line 1416
def >> (n)
  y, m = (year * 12 + (mon - 1) + n).divmod(12)
  m,   = (m + 1)                    .divmod(1)
  d = mday
  until jd2 = _valid_civil?(y, m, d, @sg)
    d -= 1
    raise ArgumentError, 'invalid date' unless d > 0
  end
  self + (jd2 - jd)
end
ajd() click to toggle source

Get the date as an Astronomical Julian Day Number.

# File lib/project/date.rb, line 1142
def ajd() @ajd end
amjd() click to toggle source

Get the date as an Astronomical Modified Julian Day Number.

# File lib/project/date.rb, line 1145
def amjd() ajd_to_amjd(@ajd) end
asctime() click to toggle source

alias_method :format, :strftime

# File lib/project/format.rb, line 344
def asctime() strftime('%c') end
Also aliased as: ctime
ctime()
Alias for: asctime
cwday() click to toggle source

Get the commercial day of the week of this date. Monday is commercial day-of-week 1; Sunday is commercial day-of-week 7.

# File lib/project/date.rb, line 1242
def cwday() commercial[2] end
cweek() click to toggle source

Get the commercial week of the year of this date.

# File lib/project/date.rb, line 1238
def cweek() commercial[1] end
cwyear() click to toggle source

Get the commercial year of this date. See Commercial Date in the introduction for how this differs from the normal year.

# File lib/project/date.rb, line 1235
def cwyear() commercial[0] end
day()
Alias for: mday
day_fraction() click to toggle source

Get any fractional day part of the date.

# File lib/project/date.rb, line 1153
def day_fraction() ajd_to_jd(@ajd, @of)[1] end
downto(min) { |date| ... } click to toggle source

Step backward one day at a time until we reach min (inclusive), yielding each date as we go.

# File lib/project/date.rb, line 1471
def downto(min, &block) # :yield: date
  step(min, -1, &block)
end
england() click to toggle source

Create a copy of this Date object that uses the English/Colonial Day of Calendar Reform.

# File lib/project/date.rb, line 1304
def england() new_start(self.class::ENGLAND) end
eql?(other) click to toggle source

Is this Date equal to other?

other must both be a Date object, and represent the same date.

# File lib/project/date.rb, line 1478
def eql? (other) Date === other && self == other end
gregorian() click to toggle source

Create a copy of this Date object that always uses the Gregorian Calendar.

# File lib/project/date.rb, line 1312
def gregorian() new_start(self.class::GREGORIAN) end
gregorian?() click to toggle source

Is the current date new-style (Gregorian Calendar)?

# File lib/project/date.rb, line 1272
def gregorian? () !julian? end
hash() click to toggle source

Calculate a hash value for this date.

# File lib/project/date.rb, line 1481
def hash() @ajd.hash end
hour() click to toggle source

Get the hour of this date.

# File lib/project/date.rb, line 1211
def hour() time[0] end
inspect() click to toggle source

Return internal object state as a programmer-readable string.

# File lib/project/date.rb, line 1484
def inspect
  format('#<%s: %s (%s,%s,%s)>', self.class, to_s, @ajd, @of, @sg)
end
iso8601() click to toggle source
# File lib/project/format.rb, line 348
def iso8601() strftime('%F') end
italy() click to toggle source

Create a copy of this Date object that uses the Italian/Catholic Day of Calendar Reform.

# File lib/project/date.rb, line 1300
def italy() new_start(self.class::ITALY) end
jd() click to toggle source

Get the date as a Julian Day Number.

# File lib/project/date.rb, line 1150
def jd() ajd_to_jd(@ajd, @of)[0] end
jisx0301() click to toggle source
# File lib/project/format.rb, line 360
def jisx0301
  if jd < 2405160
    iso8601
  else
    case jd
    when 2405160...2419614
      g = 'M%02d' % (year - 1867)
    when 2419614...2424875
      g = 'T%02d' % (year - 1911)
    when 2424875...2447535
      g = 'S%02d' % (year - 1925)
    else
      g = 'H%02d' % (year - 1988)
    end
    g + strftime('.%m.%d')
  end
end
julian() click to toggle source

Create a copy of this Date object that always uses the Julian Calendar.

# File lib/project/date.rb, line 1308
def julian() new_start(self.class::JULIAN) end
julian?() click to toggle source

Is the current date old-style (Julian Calendar)?

# File lib/project/date.rb, line 1269
def julian? () jd < @sg end
ld() click to toggle source

Get the date as the number of days since the Day of Calendar Reform (in Italy and the Catholic countries).

# File lib/project/date.rb, line 1160
def ld() jd_to_ld(jd) end
leap?() click to toggle source

Is this a leap year?

# File lib/project/date.rb, line 1285
def leap?
  jd_to_civil(civil_to_jd(year, 3, 1, fix_style) - 1,
              fix_style)[-1] == 29
end
marshal_dump() click to toggle source

Dump to Marshal format.

# File lib/project/date.rb, line 1494
def marshal_dump() [@ajd, @of, @sg] end
marshal_load(a) click to toggle source

Load from Marshal format.

# File lib/project/date.rb, line 1497
def marshal_load(a)
  @ajd, @of, @sg, = a
  @__ca__ = {}
end
mday() click to toggle source

Get the day-of-the-month of this date.

# File lib/project/date.rb, line 1193
def mday() civil[2] end
Also aliased as: day
min() click to toggle source

Get the minute of this date.

# File lib/project/date.rb, line 1214
def min() time[1] end
Also aliased as: minute
minute()
Alias for: min
mjd() click to toggle source

Get the date as a Modified Julian Day Number.

# File lib/project/date.rb, line 1156
def mjd() jd_to_mjd(jd) end
mon() click to toggle source

Get the month of this date.

January is month 1.

# File lib/project/date.rb, line 1190
def mon() civil[1] end
Also aliased as: month
month()
Alias for: mon
new_offset(of=0) click to toggle source
# File lib/project/date.rb, line 1316
def new_offset(of=0)
  if String === of
    of = Rational(zone_to_diff(of) || 0, 86400)
  end
  self.class.new!(@ajd, of, @sg)
end
new_start(sg=self.class::ITALY) click to toggle source

Create a copy of this Date object using a new Day of Calendar Reform.

# File lib/project/date.rb, line 1296
def new_start(sg=self.class::ITALY) self.class.new!(@ajd, @of, sg) end
next() click to toggle source

Return a new Date one day after this one.

# File lib/project/date.rb, line 1406
def next() next_day end
Also aliased as: succ
next_day(n=1) click to toggle source
# File lib/project/date.rb, line 1402
def next_day(n=1) self + n end
next_month(n=1) click to toggle source
# File lib/project/date.rb, line 1435
def next_month(n=1) self >> n end
next_year(n=1) click to toggle source
# File lib/project/date.rb, line 1438
def next_year(n=1) self >> n * 12 end
offset() click to toggle source
# File lib/project/date.rb, line 1314
def offset() @of end
prev_day(n=1) click to toggle source
# File lib/project/date.rb, line 1403
def prev_day(n=1) self - n end
prev_month(n=1) click to toggle source
# File lib/project/date.rb, line 1436
def prev_month(n=1) self << n end
prev_year(n=1) click to toggle source
# File lib/project/date.rb, line 1439
def prev_year(n=1) self << n * 12 end
rfc2822() click to toggle source
# File lib/project/format.rb, line 354
def rfc2822() strftime('%a, %-d %b %Y %T %z') end
Also aliased as: rfc822
rfc3339() click to toggle source
# File lib/project/format.rb, line 350
def rfc3339() iso8601 end
rfc822()
Alias for: rfc2822
sec() click to toggle source

Get the second of this date.

# File lib/project/date.rb, line 1217
def sec() time[2] end
Also aliased as: second
sec_fraction() click to toggle source

Get the fraction-of-a-second of this date.

# File lib/project/date.rb, line 1220
def sec_fraction() time[3] end
Also aliased as: second_fraction
second()
Alias for: sec
second_fraction()
Alias for: sec_fraction
start() click to toggle source

When is the Day of Calendar Reform for this Date object?

# File lib/project/date.rb, line 1293
def start() @sg end
step(limit, step=1) { |date| ... } click to toggle source

Step the current date forward step days at a time (or backward, if step is negative) until we reach limit (inclusive), yielding the resultant date at each step.

# File lib/project/date.rb, line 1445
  def step(limit, step=1) # :yield: date
=begin
    if step.zero?
      raise ArgumentError, "step can't be 0"
    end
=end
    unless block_given?
      return to_enum(:step, limit, step)
    end
    da = self
    op = %w(- <= >=)[step <=> 0]
    while da.__send__(op, limit)
      yield da
      da += step
    end
    self
  end
strftime(fmt='%F') click to toggle source
# File lib/project/format.rb, line 218
def strftime(fmt='%F')
  fmt.gsub(/%([-_0^#]+)?(\d+)?([EO]?(?::{1,3}z|.))/m) do
    f = {}
    m = $&
    s, w, c = $1, $2, $3
    if s
      s.scan(/./) do |k|
        case k
        when '-'; f[:p] = '-'
        when '_'; f[:p] = "\s"
        when '0'; f[:p] = '0'
        when '^'; f[:u] = true
        when '#'; f[:x] = true
        end
      end
    end
    if w
      f[:w] = w.to_i
    end
    case c
    when 'A'; emit_ad(DAYNAMES[wday], 0, f)
    when 'a'; emit_ad(ABBR_DAYNAMES[wday], 0, f)
    when 'B'; emit_ad(MONTHNAMES[mon], 0, f)
    when 'b'; emit_ad(ABBR_MONTHNAMES[mon], 0, f)
    when 'C', 'EC'; emit_sn((year / 100).floor, 2, f)
    when 'c', 'Ec'; emit_a(strftime('%a %b %e %H:%M:%S %Y'), 0, f)
    when 'D'; emit_a(strftime('%m/%d/%y'), 0, f)
    when 'd', 'Od'; emit_n(mday, 2, f)
    when 'e', 'Oe'; emit_a(mday, 2, f)
    when 'F'
      if m == '%F'
        format('%.4d-%02d-%02d', year, mon, mday) # 4p
      else
        emit_a(strftime('%Y-%m-%d'), 0, f)
      end
    when 'G'; emit_sn(cwyear, 4, f)
    when 'g'; emit_n(cwyear % 100, 2, f)
    when 'H', 'OH'; emit_n(hour, 2, f)
    when 'h'; emit_ad(strftime('%b'), 0, f)
    when 'I', 'OI'; emit_n((hour % 12).nonzero? || 12, 2, f)
    when 'j'; emit_n(yday, 3, f)
    when 'k'; emit_a(hour, 2, f)
    when 'L'
      f[:p] = nil
      w = f[:w] || 3
      u = 10**w
      emit_n((sec_fraction * u).floor, w, f)
    when 'l'; emit_a((hour % 12).nonzero? || 12, 2, f)
    when 'M', 'OM'; emit_n(min, 2, f)
    when 'm', 'Om'; emit_n(mon, 2, f)
    when 'N'
      f[:p] = nil
      w = f[:w] || 9
      u = 10**w
      emit_n((sec_fraction * u).floor, w, f)
    when 'n'; emit_a("\n", 0, f)
    when 'P'; emit_ad(strftime('%p').downcase, 0, f)
    when 'p'; emit_au(if hour < 12 then 'AM' else 'PM' end, 0, f)
    when 'Q'
      s = ((ajd - UNIX_EPOCH_IN_AJD) / MILLISECONDS_IN_DAY).round
      emit_sn(s, 1, f)
    when 'R'; emit_a(strftime('%H:%M'), 0, f)
    when 'r'; emit_a(strftime('%I:%M:%S %p'), 0, f)
    when 'S', 'OS'; emit_n(sec, 2, f)
    when 's'
      s = ((ajd - UNIX_EPOCH_IN_AJD) / SECONDS_IN_DAY).round
      emit_sn(s, 1, f)
    when 'T'
      if m == '%T'
        format('%02d:%02d:%02d', hour, min, sec) # 4p
      else
        emit_a(strftime('%H:%M:%S'), 0, f)
      end
    when 't'; emit_a("\t", 0, f)
    when 'U', 'W', 'OU', 'OW'
      emit_n(if c[-1,1] == 'U' then wnum0 else wnum1 end, 2, f)
    when 'u', 'Ou'; emit_n(cwday, 1, f)
    when 'V', 'OV'; emit_n(cweek, 2, f)
    when 'v'; emit_a(strftime('%e-%b-%Y'), 0, f)
    when 'w', 'Ow'; emit_n(wday, 1, f)
    when 'X', 'EX'; emit_a(strftime('%H:%M:%S'), 0, f)
    when 'x', 'Ex'; emit_a(strftime('%m/%d/%y'), 0, f)
    when 'Y', 'EY'; emit_sn(year, 4, f)
    when 'y', 'Ey', 'Oy'; emit_n(year % 100, 2, f)
    when 'Z'; emit_au(strftime('%:z'), 0, f)
    when /\A(:{0,3})z/
      t = $1.size
      sign = if offset < 0 then -1 else +1 end
      fr = offset.abs
      ss = fr.div(SECONDS_IN_DAY) # 4p
      hh, ss = ss.divmod(3600)
      mm, ss = ss.divmod(60)
      if t == 3
        if    ss.nonzero? then t =  2
        elsif mm.nonzero? then t =  1
        else                   t = -1
        end
      end
      case t
      when -1
        tail = []
        sep = ''
      when 0
        f[:w] -= 2 if f[:w]
        tail = ['%02d' % mm]
        sep = ''
      when 1
        f[:w] -= 3 if f[:w]
        tail = ['%02d' % mm]
        sep = ':'
      when 2
        f[:w] -= 6 if f[:w]
        tail = ['%02d' % mm, '%02d' % ss]
        sep = ':'
      end
      ([emit_z(sign * hh, 2, f)] + tail).join(sep)
    when '%'; emit_a('%', 0, f)
    when '+'; emit_a(strftime('%a %b %e %H:%M:%S %Z %Y'), 0, f)
    else
      m
    end
  end
end
succ()
Alias for: next
time_to_day_fraction(h, min, s) click to toggle source
# File lib/project/date.rb, line 527
def time_to_day_fraction(h, min, s)
  Rational(h * 3600 + min * 60 + s, 86400) # 4p
end
to_date() click to toggle source
# File lib/project/date.rb, line 1800
def to_date() self end
to_datetime() click to toggle source
# File lib/project/date.rb, line 1801
def to_datetime() DateTime.new!(jd_to_ajd(jd, 0, 0), @of, @sg) end
to_s() click to toggle source

Return the date as a human-readable string.

The format used is YYYY-MM-DD.

# File lib/project/date.rb, line 1491
def to_s() format('%.4d-%02d-%02d', year, mon, mday) end
to_time() click to toggle source
# File lib/project/date.rb, line 1799
def to_time() Time.local(year, mon, mday) end
upto(max) { |date| ... } click to toggle source

Step forward one day at a time until we reach max (inclusive), yielding each date as we go.

# File lib/project/date.rb, line 1465
def upto(max, &block) # :yield: date
  step(max, +1, &block)
end
wday() click to toggle source

Get the week day of this date. Sunday is day-of-week 0; Saturday is day-of-week 6.

# File lib/project/date.rb, line 1246
def wday() jd_to_wday(jd) end
yday() click to toggle source

Get the day-of-the-year of this date.

January 1 is day-of-the-year 1

# File lib/project/date.rb, line 1185
def yday() ordinal[1] end
year() click to toggle source

Get the year of this date.

# File lib/project/date.rb, line 1180
def year() civil[0] end
zone() click to toggle source
# File lib/project/date.rb, line 1229
def zone() strftime('%:z') end

Private Instance Methods

nth_kday?(n, k) click to toggle source
# File lib/project/date.rb, line 1262
def nth_kday? (n, k)
  k == wday && jd === nth_kday_to_jd(year, mon, n, k, start)
end