# Time (Class)

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 iso8601 parse rfc2822 rfc2822 rfc822 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 of 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, }
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'

## Public Class methods

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

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

Parses `date` using ParseDate.parsedate 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 ParseDate 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 136
        def parse(date, now=Time.now)
          year, mon, day, hour, min, sec, zone, _ = ParseDate.parsedate(date)
          year = yield(year) if year && block_given?

          if now
            begin
              break if year; year = now.year
              break if mon; mon = now.mon
              break if day; day = now.day
              break if hour; hour = now.hour
              break if min; min = now.min
              break if sec; sec = now.sec
            end until true
          end

          year ||= 1970
          mon ||= 1
          day ||= 1
          hour ||= 0
          min ||= 0
          sec ||= 0

          off = nil
          off = zone_offset(zone, year) if zone

          if off
            t = Time.utc(year, mon, day, hour, min, sec) - off
            t.localtime if off != 0
            t
          else
            Time.local(year, mon, day, hour, min, sec)
          end
        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 185
        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

            t = Time.utc(year, mon, day, hour, min, sec)
            offset = zone_offset(zone)
            t = (t - offset).localtime if offset != 0 || zone == '+0000'
            t
          else
            raise ArgumentError.new("not RFC 2822 compliant date: #{date.inspect}")
          end
        end

rfc822(date)

Alias for rfc2822

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 233
        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

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 274
        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
            datetime = [$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i]
            datetime << $7.to_f * 1000000 if $7
            if $8
              Time.utc(*datetime) - zone_offset($8)
            else
              Time.local(*datetime)
            end
          else
            raise ArgumentError.new("invalid date: #{date.inspect}")
          end
        end

iso8601(date)

Alias for xmlschema

rfc822(date)

Alias for rfc2822

iso8601(date)

Alias for xmlschema

## Public Instance methods

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 305
      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

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 336
      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

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 os 0.

[Source]

    # File time.rb, line 358
      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]