Class: Time

Class | Time
In: | time.rb
Parent: | Object

Implements the extensions to the Time class that are described in the documentation for the time.rb library.

### Methods

httpdate httpdate iso8601 parse rfc2822 rfc2822 rfc822 xmlschema xmlschema zone_offset

### Constants

ZoneOffset | = | { 'UTC' => 0, # ISO 8601 'Z' => 0, # RFC 822 'UT' => 0, 'GMT' => 0, 'EST' => -5, 'EDT' => -4, 'CST' => -6, 'CDT' => -5, 'MST' => -7, 'MDT' => -6, 'PST' => -8, 'PDT' => -7, # Following definition of military zones is original one. # See RFC 1123 and RFC 2822 for the error in RFC 822. 'A' => +1, 'B' => +2, 'C' => +3, 'D' => +4, 'E' => +5, 'F' => +6, 'G' => +7, 'H' => +8, 'I' => +9, 'K' => +10, 'L' => +11, 'M' => +12, 'N' => -1, 'O' => -2, 'P' => -3, 'Q' => -4, 'R' => -5, 'S' => -6, 'T' => -7, 'U' => -8, 'V' => -9, 'W' => -10, 'X' => -11, 'Y' => -12, }
LeapYearMonthDays | = | [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
CommonYearMonthDays | = | [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
MonthValue | = | { 'JAN' => 1, 'FEB' => 2, 'MAR' => 3, 'APR' => 4, 'MAY' => 5, 'JUN' => 6, 'JUL' => 7, 'AUG' => 8, 'SEP' => 9, 'OCT' =>10, 'NOV' =>11, 'DEC' =>12
RFC2822_DAY_NAME | = | [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'
RFC2822_MONTH_NAME | = | [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'

### External Aliases

rfc2822 | -> | rfc822
xmlschema | -> | iso8601

### Public Class methods

httpdate(date)

Parses `date` as HTTP-date defined by RFC 2616 and converts it to a Time object.

ArgumentError is raised if `date` is not compliant with RFC 2616 or Time class cannot represent specified date.

See httpdate for more information on this format.

[Source]

    # File time.rb, line 310
        def httpdate(date)
          if /\A\s*
              (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\x20
              (\d{2})\x20
              (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\x20
              (\d{4})\x20
              (\d{2}):(\d{2}):(\d{2})\x20
              GMT
              \s*\z/ix =~ date
            Time.rfc2822(date)
          elsif /\A\s*
                 (?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday),\x20
                 (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d)\x20
                 (\d\d):(\d\d):(\d\d)\x20
                 GMT
                 \s*\z/ix =~ date
            Time.parse(date)
          elsif /\A\s*
                 (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\x20
                 (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\x20
                 (\d\d|\x20\d)\x20
                 (\d\d):(\d\d):(\d\d)\x20
                 (\d{4})
                 \s*\z/ix =~ date
            Time.utc($6.to_i, MonthValue[$1.upcase], $2.to_i,
                     $3.to_i, $4.to_i, $5.to_i)
          else
            raise ArgumentError.new("not RFC 2616 compliant date: #{date.inspect}")
          end
        end

parse(date, now=Time.now) {|year| ...}

Parses `date` using Date._parse and converts it to a Time object.

If a block is given, the year described in `date` is converted by the block. For example:

        Time.parse(...) {|y| y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}

If the upper components of the given time are broken or missing, they are supplied with those of `now`. For the lower components, the minimum values (1 or 0) are assumed if broken or missing. For example:

        # Suppose it is "Thu Nov 29 14:33:20 GMT 2001" now and
        # your timezone is GMT:
        Time.parse("16:30")     #=> Thu Nov 29 16:30:00 GMT 2001
        Time.parse("7/23")      #=> Mon Jul 23 00:00:00 GMT 2001
        Time.parse("Aug 31")    #=> Fri Aug 31 00:00:00 GMT 2001

Since there are numerous conflicts among locally defined timezone abbreviations all over the world, this method is not made to understand all of them. For example, the abbreviation "CST" is used variously as:

        -06:00 in America/Chicago,
        -05:00 in America/Havana,
        +08:00 in Asia/Harbin,
        +09:30 in Australia/Darwin,
        +10:30 in Australia/Adelaide,
        etc.

Based on the fact, this method only understands the timezone abbreviations described in RFC 822 and the system timezone, in the order named. (i.e. a definition in RFC 822 overrides the system timezone definition.) The system timezone is taken from `Time.local(year, 1, 1).zone` and `Time.local(year, 7, 1).zone`. If the extracted timezone abbreviation does not match any of them, it is ignored and the given time is regarded as a local time.

ArgumentError is raised if Date._parse cannot extract information from `date` or Time class cannot represent specified date.

This method can be used as fail-safe for other parsing methods as:

      Time.rfc2822(date) rescue Time.parse(date)
      Time.httpdate(date) rescue Time.parse(date)
      Time.xmlschema(date) rescue Time.parse(date)

A failure for Time.parse should be checked, though.

[Source]

    # File time.rb, line 239
        def parse(date, now=Time.now)
          d = Date._parse(date, false)
          year = d[:year]
          year = yield(year) if year && block_given?
          make_time(year, d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now)
        end

rfc2822(date)

Parses `date` as date-time defined by RFC 2822 and converts it to a Time object. The format is identical to the date format defined by RFC 822 and updated by RFC 1123.

ArgumentError is raised if `date` is not compliant with RFC 2822 or Time class cannot represent specified date.

See rfc2822 for more information on this format.

[Source]

    # File time.rb, line 261
        def rfc2822(date)
          if /\A\s*
              (?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*,\s*)?
              (\d{1,2})\s+
              (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+
              (\d{2,})\s+
              (\d{2})\s*
              :\s*(\d{2})\s*
              (?::\s*(\d{2}))?\s+
              ([+-]\d{4}|
               UT|GMT|EST|EDT|CST|CDT|MST|MDT|PST|PDT|[A-IK-Z])/ix =~ date
            # Since RFC 2822 permit comments, the regexp has no right anchor.
            day = $1.to_i
            mon = MonthValue[$2.upcase]
            year = $3.to_i
            hour = $4.to_i
            min = $5.to_i
            sec = $6 ? $6.to_i : 0
            zone = $7

            # following year completion is compliant with RFC 2822.
            year = if year < 50
                     2000 + year
                   elsif year < 1000
                     1900 + year
                   else
                     year
                   end

            year, mon, day, hour, min, sec =
              apply_offset(year, mon, day, hour, min, sec, zone_offset(zone))
            t = Time.utc(year, mon, day, hour, min, sec)
            t.localtime if !zone_utc?(zone)
            t
          else
            raise ArgumentError.new("not RFC 2822 compliant date: #{date.inspect}")
          end
        end

xmlschema(date)

Parses `date` as dateTime defined by XML Schema and converts it to a Time object. The format is restricted version of the format defined by ISO 8601.

ArgumentError is raised if `date` is not compliant with the format or Time class cannot represent specified date.

See xmlschema for more information on this format.

[Source]

    # File time.rb, line 351
        def xmlschema(date)
          if /\A\s*
              (-?\d+)-(\d\d)-(\d\d)
              T
              (\d\d):(\d\d):(\d\d)
              (\.\d*)?
              (Z|[+-]\d\d:\d\d)?
              \s*\z/ix =~ date
            year = $1.to_i
            mon = $2.to_i
            day = $3.to_i
            hour = $4.to_i
            min = $5.to_i
            sec = $6.to_i
            usec = 0
            usec = $7.to_f * 1000000 if $7
            if $8
              zone = $8
              year, mon, day, hour, min, sec =
                apply_offset(year, mon, day, hour, min, sec, zone_offset(zone))
              Time.utc(year, mon, day, hour, min, sec, usec)
            else
              Time.local(year, mon, day, hour, min, sec, usec)
            end
          else
            raise ArgumentError.new("invalid date: #{date.inspect}")
          end
        end

zone_offset(zone, year=Time.now.year)

[Source]

    # File time.rb, line 69
        def zone_offset(zone, year=Time.now.year)
          off = nil
          zone = zone.upcase
          if /\A([+-])(\d\d):?(\d\d)\z/ =~ zone
            off = ($1 == '-' ? -1 : 1) * ($2.to_i * 60 + $3.to_i) * 60
          elsif /\A[+-]\d\d\z/ =~ zone
            off = zone.to_i * 3600
          elsif ZoneOffset.include?(zone)
            off = ZoneOffset[zone] * 3600
          elsif ((t = Time.local(year, 1, 1)).zone.upcase == zone rescue false)
            off = t.utc_offset
          elsif ((t = Time.local(year, 7, 1)).zone.upcase == zone rescue false)
            off = t.utc_offset
          end
          off
        end

### Public Instance methods

httpdate()

Returns a string which represents the time as rfc1123-date of HTTP-date defined by RFC 2616:

      day-of-week, DD month-name CCYY hh:mm:ss GMT

Note that the result is always UTC (GMT).

[Source]

    # File time.rb, line 422
      def httpdate
        t = dup.utc
        sprintf('%s, %02d %s %d %02d:%02d:%02d GMT',
          RFC2822_DAY_NAME[t.wday],
          t.day, RFC2822_MONTH_NAME[t.mon-1], t.year,
          t.hour, t.min, t.sec)
      end

iso8601(fraction_digits=0)

Alias for xmlschema

rfc2822()

Returns a string which represents the time as date-time defined by RFC 2822:

      day-of-week, DD month-name CCYY hh:mm:ss zone

where zone is [+-]hhmm.

If `self` is a UTC time, -0000 is used as zone.

[Source]

    # File time.rb, line 391
      def rfc2822
        sprintf('%s, %02d %s %d %02d:%02d:%02d ',
          RFC2822_DAY_NAME[wday],
          day, RFC2822_MONTH_NAME[mon-1], year,
          hour, min, sec) +
        if utc?
          '-0000'
        else
          off = utc_offset
          sign = off < 0 ? '-' : '+'
          sprintf('%s%02d%02d', sign, *(off.abs / 60).divmod(60))
        end
      end

rfc822()

Alias for rfc2822

xmlschema(fraction_digits=0)

Returns a string which represents the time as dateTime defined by XML Schema:

      CCYY-MM-DDThh:mm:ssTZD
      CCYY-MM-DDThh:mm:ss.sssTZD

where TZD is Z or [+-]hh:mm.

If self is a UTC time, Z is used as TZD. [+-]hh:mm is used otherwise.

`fractional_seconds` specifies a number of digits of fractional seconds. Its default value is 0.

[Source]

    # File time.rb, line 444
      def xmlschema(fraction_digits=0)
        sprintf('%d-%02d-%02dT%02d:%02d:%02d',
          year, mon, day, hour, min, sec) +
        if fraction_digits == 0
          ''
        elsif fraction_digits <= 6
          '.' + sprintf('%06d', usec)[0, fraction_digits]
        else
          '.' + sprintf('%06d', usec) + '0' * (fraction_digits - 6)
        end +
        if utc?
          'Z'
        else
          off = utc_offset
          sign = off < 0 ? '-' : '+'
          sprintf('%s%02d:%02d', sign, *(off.abs / 60).divmod(60))
        end
      end

[Validate]