class Time - RDoc Documentation

# class Time

A `Time` object represents a date and time:

    Time.new(2000, 1, 1, 0, 0, 0) # => 2000-01-01 00:00:00 -0600

Although its value can be expressed as a single numeric (see Epoch Seconds below), it can be convenient to deal with the value by parts:

    t = Time.new(-2000, 1, 1, 0, 0, 0.0)
    # => -2000-01-01 00:00:00 -0600
    t.year # => -2000
    t.month # => 1
    t.mday # => 1
    t.hour # => 0
    t.min # => 0
    t.sec # => 0
    t.subsec # => 0

    t = Time.new(2000, 12, 31, 23, 59, 59.5)
    # => 2000-12-31 23:59:59.5 -0600
    t.year # => 2000
    t.month # => 12
    t.mday # => 31
    t.hour # => 23
    t.min # => 59
    t.sec # => 59
    t.subsec # => (1/2)

## Epoch Seconds¶ ↑

Epoch seconds is the exact number of seconds (including fractional subseconds) since the Unix Epoch, January 1, 1970.

You can retrieve that value exactly using method `Time.to_r`:

    Time.at(0).to_r        # => (0/1)
    Time.at(0.999999).to_r # => (9007190247541737/9007199254740992)

Other retrieval methods such as `Time#to_i` and `Time#to_f` may return a value that rounds or truncates subseconds.

## Time Resolution¶ ↑

A `Time` object derived from the system clock (for example, by method `Time.now`) has the resolution supported by the system.

## Time Internal Representation¶ ↑

`Time` implementation uses a signed 63 bit integer, `Integer`, or `Rational`. It is a number of nanoseconds since the Epoch. The signed 63 bit integer can represent 1823-11-12 to 2116-02-20. When `Integer` or `Rational` is used (before 1823, after 2116, under nanosecond), `Time` works slower than when the signed 63 bit integer is used.

Ruby uses the C function `localtime` and `gmtime` to map between the number and 6-tuple (year,month,day,hour,minute,second). `localtime` is used for local time and “gmtime” is used for UTC.

`Integer` and `Rational` has no range limit, but the localtime and gmtime has range limits due to the C types `time_t` and `struct tm`. If that limit is exceeded, Ruby extrapolates the localtime function.

The `Time` class always uses the Gregorian calendar. I.e. the proleptic Gregorian calendar is used. Other calendars, such as Julian calendar, are not supported.

`time_t` can represent 1901-12-14 to 2038-01-19 if it is 32 bit signed integer, -292277022657-01-27 to 292277026596-12-05 if it is 64 bit signed integer. However `localtime` on some platforms doesn’t supports negative `time_t` (before 1970).

`struct tm` has tm_year member to represent years. (`tm_year = 0` means the year 1900.) It is defined as `int` in the C standard. tm_year can represent between -2147481748 to 2147485547 if `int` is 32 bit.

Ruby supports leap seconds as far as if the C function `localtime` and `gmtime` supports it. They use the tz database in most Unix systems. The tz database has timezones which supports leap seconds. For example, “Asia/Tokyo” doesn’t support leap seconds but “right/Asia/Tokyo” supports leap seconds. So, Ruby supports leap seconds if the TZ environment variable is set to “right/Asia/Tokyo” in most Unix systems.

## Examples¶ ↑

All of these examples were done using the EST timezone which is GMT-5.

### Creating a New `Time` Instance¶ ↑

You can create a new instance of `Time` with `Time.new`. This will use the current system time. `Time.now` is an alias for this. You can also pass parts of the time to `Time.new` such as year, month, minute, etc. When you want to construct a time this way you must pass at least a year. If you pass the year with nothing else time will default to January 1 of that year at 00:00:00 with the current system timezone. Here are some examples:

    Time.new(2002)         #=> 2002-01-01 00:00:00 -0500
    Time.new(2002, 10)     #=> 2002-10-01 00:00:00 -0500
    Time.new(2002, 10, 31) #=> 2002-10-31 00:00:00 -0500

You can pass a UTC offset:

    Time.new(2002, 10, 31, 2, 2, 2, "+02:00") #=> 2002-10-31 02:02:02 +0200

Or a timezone object:

    zone = timezone("Europe/Athens")      # Eastern European Time, UTC+2
    Time.new(2002, 10, 31, 2, 2, 2, zone) #=> 2002-10-31 02:02:02 +0200

You can also use `Time.local` and `Time.utc` to infer local and UTC timezones instead of using the current system setting.

You can also create a new time using `Time.at` which takes the number of seconds (with subsecond) since the Unix Epoch.

    Time.at(628232400) #=> 1989-11-28 00:00:00 -0500

### Working with an Instance of `Time`¶ ↑

Once you have an instance of `Time` there is a multitude of things you can do with it. Below are some examples. For all of the following examples, we will work on the assumption that you have done the following:

    t = Time.new(1993, 02, 24, 12, 0, 0, "+09:00")

Was that a monday?

    t.monday? #=> false

What year was that again?

    t.year #=> 1993

Was it daylight savings at the time?

    t.dst? #=> false

What’s the day a year later?

    t + (60*60*24*365) #=> 1994-02-24 12:00:00 +0900

How many seconds was that since the Unix Epoch?

    t.to_i #=> 730522800

You can also do standard functions like compare two times.

    t1 = Time.new(2010)
    t2 = Time.new(2011)

    t1 == t2 #=> false
    t1 == t1 #=> true
    t1 <  t2 #=> true
    t1 >  t2 #=> false

    Time.new(2010,10,31).between?(t1, t2) #=> true

## What’s Here¶ ↑

First, what’s elsewhere. Class `Time`:

- Inherits from class Object.

- Includes module Comparable.

Here, class `Time` provides methods that are useful for:

- Creating Time objects.

- Fetching Time values.

- Querying a Time object.

- Comparing Time objects.

- Converting a Time object.

- Rounding a Time.

### Methods for Creating¶ ↑

- `::new`: Returns a new time from specified arguments (year, month, etc.), including an optional timezone value.

- `::local` (aliased as `::mktime`): Same as `::new`, except the timezone is the local timezone.

- `::utc` (aliased as `::gm`): Same as `::new`, except the timezone is UTC.

- `::at`: Returns a new time based on seconds since epoch.

- `::now`: Returns a new time based on the current system time.

- `+` (plus): Returns a new time increased by the given number of seconds.

- `-` (minus): Returns a new time decreased by the given number of seconds.

### Methods for Fetching¶ ↑

- `year`: Returns the year of the time.

- `month` (aliased as `mon`): Returns the month of the time.

- `mday` (aliased as `day`): Returns the day of the month.

- `hour`: Returns the hours value for the time.

- `min`: Returns the minutes value for the time.

- `sec`: Returns the seconds value for the time.

- `usec` (aliased as `tv_usec`): Returns the number of microseconds in the subseconds value of the time.

- `nsec` (aliased as `tv_nsec`: Returns the number of nanoseconds in the subsecond part of the time.

- `subsec`: Returns the subseconds value for the time.

- `wday`: Returns the integer weekday value of the time (0 == Sunday).

- `yday`: Returns the integer yearday value of the time (1 == January 1).

- `hash`: Returns the integer hash value for the time.

- `utc_offset` (aliased as `gmt_offset` and `gmtoff`): Returns the offset in seconds between time and UTC.

- `to_f`: Returns the float number of seconds since epoch for the time.

- `to_i` (aliased as `tv_sec`): Returns the integer number of seconds since epoch for the time.

- `to_r`: Returns the `Rational` number of seconds since epoch for the time.

- `zone`: Returns a string representation of the timezone of the time.

### Methods for Querying¶ ↑

- `utc?` (aliased as `gmt?`): Returns whether the time is UTC.

- `dst?` (aliased as `isdst`): Returns whether the time is DST (daylight saving time).

- `sunday?`: Returns whether the time is a Sunday.

- `monday?`: Returns whether the time is a Monday.

- `tuesday?`: Returns whether the time is a Tuesday.

- `wednesday?`: Returns whether the time is a Wednesday.

- `thursday?`: Returns whether the time is a Thursday.

- `friday?`: Returns whether time is a Friday.

- `saturday?`: Returns whether the time is a Saturday.

### Methods for Comparing¶ ↑

- #<=>: Compares `self` to another time.

- `eql?`: Returns whether the time is equal to another time.

### Methods for Converting¶ ↑

- `asctime` (aliased as `ctime`): Returns the time as a string.

- `inspect`: Returns the time in detail as a string.

- `strftime`: Returns the time as a string, according to a given format.

- `to_a`: Returns a 10-element array of values from the time.

- `to_s`: Returns a string representation of the time.

- `getutc` (aliased as `getgm`): Returns a new time converted to UTC.

- `getlocal`: Returns a new time converted to local time.

- `utc` (aliased as `gmtime`): Converts time to UTC in place.

- `localtime`: Converts time to local time in place.

- `deconstruct_keys`: Returns a hash of time components used in pattern-matching.

### Methods for Rounding¶ ↑

- `round`:Returns a new time with subseconds rounded.

- `ceil`: Returns a new time with subseconds raised to a ceiling.

- `floor`: Returns a new time with subseconds lowered to a floor.

For the forms of argument `zone`, see Timezone Specifiers.

## Timezone Specifiers¶ ↑

Certain `Time` methods accept arguments that specify timezones:

- `Time.at`: keyword argument `in:`.

- `Time.new`: positional argument `zone` or keyword argument `in:`.

- `Time.now`: keyword argument `in:`.

- `Time#getlocal`: positional argument `zone`.

- `Time#localtime`: positional argument `zone`.

The value given with any of these must be one of the following (each detailed below):

- Hours/minutes offset.

- Single-letter offset.

- Integer offset.

- Timezone object.

- Timezone name.

### Hours/Minutes Offsets¶ ↑

The zone value may be a string offset from UTC in the form `'+HH:MM'` or `'-HH:MM'`, where:

- `HH` is the 2-digit hour in the range `0..23`.

- `MM` is the 2-digit minute in the range `0..59`.

Examples:

    t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
    Time.at(t, in: '-23:59')            # => 1999-12-31 20:16:01 -2359
    Time.at(t, in: '+23:59')            # => 2000-01-02 20:14:01 +2359

### Single-Letter Offsets¶ ↑

The zone value may be a letter in the range `'A'..'I'` or `'K'..'Z'`; see List of military time zones:

    t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
    Time.at(t, in: 'A')                 # => 2000-01-01 21:15:01 +0100
    Time.at(t, in: 'I')                 # => 2000-01-02 05:15:01 +0900
    Time.at(t, in: 'K')                 # => 2000-01-02 06:15:01 +1000
    Time.at(t, in: 'Y')                 # => 2000-01-01 08:15:01 -1200
    Time.at(t, in: 'Z')                 # => 2000-01-01 20:15:01 UTC

### Integer Offsets¶ ↑

The zone value may be an integer number of seconds in the range `-86399..86399`:

    t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
    Time.at(t, in: -86399)              # => 1999-12-31 20:15:02 -235959
    Time.at(t, in: 86399)               # => 2000-01-02 20:15:00 +235959

### Timezone Objects¶ ↑

The zone value may be an object responding to certain timezone methods, an instance of Timezone and TZInfo for example.

The timezone methods are:

- `local_to_utc`:

  Called when `Time.new` is invoked with `tz` as the value of positional argument `zone` or keyword argument `in:`.

  Argument

    a Time-like object.

  Returns

    a Time-like object in the UTC timezone.

- `utc_to_local`:

  Called when `Time.at` or `Time.now` is invoked with `tz` as the value for keyword argument `in:`, and when `Time#getlocal` or `Time#localtime` is called with `tz` as the value for positional argument `zone`.

  The UTC offset will be calculated as the difference between the original time and the returned object as an `Integer`. If the object is in fixed offset, its `utc_offset` is also counted.

  Argument

    a Time-like object.

  Returns

    a Time-like object in the local timezone.

A custom timezone class may have these instance methods, which will be called if defined:

- `abbr`:

  Called when `Time#strftime` is invoked with a format involving `%Z`.

  Argument

    a Time-like object.

  Returns

    a string abbreviation for the timezone name.

- `dst?`:

  Called when `Time.at` or `Time.now` is invoked with `tz` as the value for keyword argument `in:`, and when `Time#getlocal` or `Time#localtime` is called with `tz` as the value for positional argument `zone`.

  Argument

    a Time-like object.

  Returns

    whether the time is daylight saving time.

- `name`:

  Called when `Marshal.dump(t)` is invoked

  Argument

    none.

  Returns

    the string name of the timezone.

#### `Time`-Like Objects¶ ↑

A `Time`-like object is a container object capable of interfacing with timezone libraries for timezone conversion.

The argument to the timezone conversion methods above will have attributes similar to `Time`, except that timezone related attributes are meaningless.

The objects returned by `local_to_utc` and `utc_to_local` methods of the timezone object may be of the same class as their arguments, of arbitrary object classes, or of class `Integer`.

For a returned class other than `Integer`, the class must have the following methods:

- `year`

- `mon`

- `mday`

- `hour`

- `min`

- `sec`

- `isdst`

- `to_i`

For a returned `Integer`, its components, decomposed in UTC, are interpreted as times in the specified timezone.

### Timezone Names¶ ↑

If the class (the receiver of class methods, or the class of the receiver of instance methods) has `find_timezone` singleton method, this method is called to achieve the corresponding timezone object from a timezone name.

For example, using Timezone:

    class TimeWithTimezone < Time
      require 'timezone'
      def self.find_timezone(z) = Timezone[z]
    end

    TimeWithTimezone.now(in: "America/New_York")        #=> 2023-12-25 00:00:00 -0500
    TimeWithTimezone.new("2023-12-25 America/New_York") #=> 2023-12-25 00:00:00 -0500

Or, using TZInfo:

    class TimeWithTZInfo < Time
      require 'tzinfo'
      def self.find_timezone(z) = TZInfo::Timezone.get(z)
    end

    TimeWithTZInfo.now(in: "America/New_York")          #=> 2023-12-25 00:00:00 -0500
    TimeWithTZInfo.new("2023-12-25 America/New_York")   #=> 2023-12-25 00:00:00 -0500

You can define this method per subclasses, or on the toplevel `Time` class.

### Public Class Methods

at(time, subsec = false, unit = :microsecond, in: nil) click to toggle source

Returns a new `Time` object based on the given arguments.

Required argument `time` may be either of:

- A `Time` object, whose value is the basis for the returned time; also influenced by optional keyword argument `in:` (see below).

- A numeric number of Epoch seconds for the returned time.

Examples:

    t = Time.new(2000, 12, 31, 23, 59, 59) # => 2000-12-31 23:59:59 -0600
    secs = t.to_i                          # => 978328799
    Time.at(secs)                          # => 2000-12-31 23:59:59 -0600
    Time.at(secs + 0.5)                    # => 2000-12-31 23:59:59.5 -0600
    Time.at(1000000000)                    # => 2001-09-08 20:46:40 -0500
    Time.at(0)                             # => 1969-12-31 18:00:00 -0600
    Time.at(-1000000000)                   # => 1938-04-24 17:13:20 -0500

Optional numeric argument `subsec` and optional symbol argument `units` work together to specify subseconds for the returned time; argument `units` specifies the units for `subsec`:

- `:millisecond`: `subsec` in milliseconds:

      Time.at(secs, 0, :millisecond)     # => 2000-12-31 23:59:59 -0600
      Time.at(secs, 500, :millisecond)   # => 2000-12-31 23:59:59.5 -0600
      Time.at(secs, 1000, :millisecond)  # => 2001-01-01 00:00:00 -0600
      Time.at(secs, -1000, :millisecond) # => 2000-12-31 23:59:58 -0600

- `:microsecond` or `:usec`: `subsec` in microseconds:

      Time.at(secs, 0, :microsecond)        # => 2000-12-31 23:59:59 -0600
      Time.at(secs, 500000, :microsecond)   # => 2000-12-31 23:59:59.5 -0600
      Time.at(secs, 1000000, :microsecond)  # => 2001-01-01 00:00:00 -0600
      Time.at(secs, -1000000, :microsecond) # => 2000-12-31 23:59:58 -0600

- `:nanosecond` or `:nsec`: `subsec` in nanoseconds:

      Time.at(secs, 0, :nanosecond)           # => 2000-12-31 23:59:59 -0600
      Time.at(secs, 500000000, :nanosecond)   # => 2000-12-31 23:59:59.5 -0600
      Time.at(secs, 1000000000, :nanosecond)  # => 2001-01-01 00:00:00 -0600
      Time.at(secs, -1000000000, :nanosecond) # => 2000-12-31 23:59:58 -0600

Optional keyword argument `in: zone` specifies the timezone for the returned time:

    Time.at(secs, in: '+12:00') # => 2001-01-01 17:59:59 +1200
    Time.at(secs, in: '-12:00') # => 2000-12-31 17:59:59 -1200

For the forms of argument `zone`, see Timezone Specifiers.

    # File ruby_3_4_1/timev.rb, line 323
    def self.at(time, subsec = false, unit = :microsecond, in: nil)
      if Primitive.mandatory_only?
        Primitive.time_s_at1(time)
      else
        Primitive.time_s_at(time, subsec, unit, Primitive.arg!(:in))
      end
    end

gm(*args)

Returns a new `Time` object based the on given arguments, in the UTC timezone.

With one to seven arguments given, the arguments are interpreted as in the first calling sequence above:

    Time.utc(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0)

Examples:

    Time.utc(2000)  # => 2000-01-01 00:00:00 UTC
    Time.utc(-2000) # => -2000-01-01 00:00:00 UTC

There are no minimum and maximum values for the required argument `year`.

For the optional arguments:

- `month`: Month in range (1..12), or case-insensitive 3-letter month name:

      Time.utc(2000, 1)     # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 12)    # => 2000-12-01 00:00:00 UTC
      Time.utc(2000, 'jan') # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 'JAN') # => 2000-01-01 00:00:00 UTC

- `mday`: Month day in range(1..31):

      Time.utc(2000, 1, 1)  # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 1, 31) # => 2000-01-31 00:00:00 UTC

- `hour`: Hour in range (0..23), or 24 if `min`, `sec`, and `usec` are zero:

      Time.utc(2000, 1, 1, 0)  # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 1, 1, 23) # => 2000-01-01 23:00:00 UTC
      Time.utc(2000, 1, 1, 24) # => 2000-01-02 00:00:00 UTC

- `min`: Minute in range (0..59):

      Time.utc(2000, 1, 1, 0, 0)  # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 1, 1, 0, 59) # => 2000-01-01 00:59:00 UTC

- `sec`: Second in range (0..59), or 60 if `usec` is zero:

      Time.utc(2000, 1, 1, 0, 0, 0)  # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 1, 1, 0, 0, 59) # => 2000-01-01 00:00:59 UTC
      Time.utc(2000, 1, 1, 0, 0, 60) # => 2000-01-01 00:01:00 UTC

- `usec`: Microsecond in range (0..999999):

      Time.utc(2000, 1, 1, 0, 0, 0, 0)      # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 1, 1, 0, 0, 0, 999999) # => 2000-01-01 00:00:00.999999 UTC

The values may be:

- Integers, as above.

- Numerics convertible to integers:

      Time.utc(Float(0.0), Rational(1, 1), 1.0, 0.0, 0.0, 0.0, 0.0)
      # => 0000-01-01 00:00:00 UTC

- `String` integers:

      a = %w[0 1 1 0 0 0 0 0]
      # => ["0", "1", "1", "0", "0", "0", "0", "0"]
      Time.utc(*a) # => 0000-01-01 00:00:00 UTC

When exactly ten arguments are given, the arguments are interpreted as in the second calling sequence above:

    Time.utc(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy)

where the `dummy` arguments are ignored:

    a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    Time.utc(*a) # => 0005-04-03 02:01:00 UTC

This form is useful for creating a `Time` object from a 10-element array returned by `Time.to_a`:

    t = Time.new(2000, 1, 2, 3, 4, 5, 6) # => 2000-01-02 03:04:05 +000006
    a = t.to_a   # => [5, 4, 3, 2, 1, 2000, 0, 2, false, nil]
    Time.utc(*a) # => 2000-01-02 03:04:05 UTC

The two forms have their first six arguments in common, though in different orders; the ranges of these common arguments are the same for both forms; see above.

Raises an exception if the number of arguments is eight, nine, or greater than ten.

Related: `Time.local`.

Alias for: utc
local(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0) → new_time click to toggle source
local(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy) → new_time

Like `Time.utc`, except that the returned `Time` object has the local timezone, not the UTC timezone:

    # With seven arguments.
    Time.local(0, 1, 2, 3, 4, 5, 6)
    # => 0000-01-02 03:04:05.000006 -0600
    # With exactly ten arguments.
    Time.local(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    # => 0005-04-03 02:01:00 -0600

    static VALUE
    time_s_mktime(int argc, VALUE *argv, VALUE klass)
    {
        struct vtm vtm;

        time_arg(argc, argv, &vtm);
        return time_localtime(time_new_timew(klass, timelocalw(&vtm)));
    }

Also aliased as: mktime
mktime(*args)

Like `Time.utc`, except that the returned `Time` object has the local timezone, not the UTC timezone:

    # With seven arguments.
    Time.local(0, 1, 2, 3, 4, 5, 6)
    # => 0000-01-02 03:04:05.000006 -0600
    # With exactly ten arguments.
    Time.local(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    # => 0005-04-03 02:01:00 -0600

Alias for: local
new(year = nil, mon = nil, mday = nil, hour = nil, min = nil, sec = nil, zone = nil, in: nil, precision: 9) click to toggle source

Returns a new `Time` object based on the given arguments, by default in the local timezone.

With no positional arguments, returns the value of `Time.now`:

    Time.new # => 2021-04-24 17:27:46.0512465 -0500

With one string argument that represents a time, returns a new `Time` object based on the given argument, in the local timezone.

    Time.new('2000-12-31 23:59:59.5')              # => 2000-12-31 23:59:59.5 -0600
    Time.new('2000-12-31 23:59:59.5 +0900')        # => 2000-12-31 23:59:59.5 +0900
    Time.new('2000-12-31 23:59:59.5', in: '+0900') # => 2000-12-31 23:59:59.5 +0900
    Time.new('2000-12-31 23:59:59.5')              # => 2000-12-31 23:59:59.5 -0600
    Time.new('2000-12-31 23:59:59.56789', precision: 3) # => 2000-12-31 23:59:59.567 -0600

With one to six arguments, returns a new `Time` object based on the given arguments, in the local timezone.

    Time.new(2000, 1, 2, 3, 4, 5) # => 2000-01-02 03:04:05 -0600

For the positional arguments (other than `zone`):

- `year`: Year, with no range limits:

      Time.new(999999999)  # => 999999999-01-01 00:00:00 -0600
      Time.new(-999999999) # => -999999999-01-01 00:00:00 -0600

- `month`: Month in range (1..12), or case-insensitive 3-letter month name:

      Time.new(2000, 1)     # => 2000-01-01 00:00:00 -0600
      Time.new(2000, 12)    # => 2000-12-01 00:00:00 -0600
      Time.new(2000, 'jan') # => 2000-01-01 00:00:00 -0600
      Time.new(2000, 'JAN') # => 2000-01-01 00:00:00 -0600

- `mday`: Month day in range(1..31):

      Time.new(2000, 1, 1)  # => 2000-01-01 00:00:00 -0600
      Time.new(2000, 1, 31) # => 2000-01-31 00:00:00 -0600

- `hour`: Hour in range (0..23), or 24 if `min`, `sec`, and `usec` are zero:

      Time.new(2000, 1, 1, 0)  # => 2000-01-01 00:00:00 -0600
      Time.new(2000, 1, 1, 23) # => 2000-01-01 23:00:00 -0600
      Time.new(2000, 1, 1, 24) # => 2000-01-02 00:00:00 -0600

- `min`: Minute in range (0..59):

      Time.new(2000, 1, 1, 0, 0)  # => 2000-01-01 00:00:00 -0600
      Time.new(2000, 1, 1, 0, 59) # => 2000-01-01 00:59:00 -0600

- `sec`: Second in range (0…61):

      Time.new(2000, 1, 1, 0, 0, 0)  # => 2000-01-01 00:00:00 -0600
      Time.new(2000, 1, 1, 0, 0, 59) # => 2000-01-01 00:00:59 -0600
      Time.new(2000, 1, 1, 0, 0, 60) # => 2000-01-01 00:01:00 -0600

  `sec` may be `Float` or `Rational`.

      Time.new(2000, 1, 1, 0, 0, 59.5)  # => 2000-12-31 23:59:59.5 +0900
      Time.new(2000, 1, 1, 0, 0, 59.7r) # => 2000-12-31 23:59:59.7 +0900

These values may be:

- Integers, as above.

- Numerics convertible to integers:

      Time.new(Float(0.0), Rational(1, 1), 1.0, 0.0, 0.0, 0.0)
      # => 0000-01-01 00:00:00 -0600

- `String` integers:

      a = %w[0 1 1 0 0 0]
      # => ["0", "1", "1", "0", "0", "0"]
      Time.new(*a) # => 0000-01-01 00:00:00 -0600

When positional argument `zone` or keyword argument `in:` is given, the new `Time` object is in the specified timezone. For the forms of argument `zone`, see Timezone Specifiers:

    Time.new(2000, 1, 1, 0, 0, 0, '+12:00')
    # => 2000-01-01 00:00:00 +1200
    Time.new(2000, 1, 1, 0, 0, 0, in: '-12:00')
    # => 2000-01-01 00:00:00 -1200
    Time.new(in: '-12:00')
    # => 2022-08-23 08:49:26.1941467 -1200

Since `in:` keyword argument just provides the default, so if the first argument in single string form contains time zone information, this keyword argument will be silently ignored.

    Time.new('2000-01-01 00:00:00 +0100', in: '-0500').utc_offset  # => 3600

- `precision`: maximum effective digits in sub-second part, default is 9. More digits will be truncated, as other operations of `Time`. Ignored unless the first argument is a string.

    # File ruby_3_4_1/timev.rb, line 434
    def initialize(year = (now = true), mon = (str = year; nil), mday = nil, hour = nil, min = nil, sec = nil, zone = nil,
                   in: nil, precision: 9)
      if zone
        if Primitive.arg!(:in)
          raise ArgumentError, "timezone argument given as positional and keyword arguments"
        end
      else
        zone = Primitive.arg!(:in)
      end

      if now
        return Primitive.time_init_now(zone)
      end

      if str and Primitive.time_init_parse(str, zone, precision)
        return self
      end

      Primitive.time_init_args(year, mon, mday, hour, min, sec, zone)
    end

now(in: nil) click to toggle source

Creates a new `Time` object from the current system time. This is the same as `Time.new` without arguments.

    Time.now               # => 2009-06-24 12:39:54 +0900
    Time.now(in: '+04:00') # => 2009-06-24 07:39:54 +0400

For forms of argument `zone`, see Timezone Specifiers.

    # File ruby_3_4_1/timev.rb, line 264
    def self.now(in: nil)
      Primitive.time_s_now(Primitive.arg!(:in))
    end

utc(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0) → new_time click to toggle source
utc(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy) → new_time

Returns a new `Time` object based the on given arguments, in the UTC timezone.

With one to seven arguments given, the arguments are interpreted as in the first calling sequence above:

    Time.utc(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0)

Examples:

    Time.utc(2000)  # => 2000-01-01 00:00:00 UTC
    Time.utc(-2000) # => -2000-01-01 00:00:00 UTC

There are no minimum and maximum values for the required argument `year`.

For the optional arguments:

- `month`: Month in range (1..12), or case-insensitive 3-letter month name:

      Time.utc(2000, 1)     # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 12)    # => 2000-12-01 00:00:00 UTC
      Time.utc(2000, 'jan') # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 'JAN') # => 2000-01-01 00:00:00 UTC

- `mday`: Month day in range(1..31):

      Time.utc(2000, 1, 1)  # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 1, 31) # => 2000-01-31 00:00:00 UTC

- `hour`: Hour in range (0..23), or 24 if `min`, `sec`, and `usec` are zero:

      Time.utc(2000, 1, 1, 0)  # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 1, 1, 23) # => 2000-01-01 23:00:00 UTC
      Time.utc(2000, 1, 1, 24) # => 2000-01-02 00:00:00 UTC

- `min`: Minute in range (0..59):

      Time.utc(2000, 1, 1, 0, 0)  # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 1, 1, 0, 59) # => 2000-01-01 00:59:00 UTC

- `sec`: Second in range (0..59), or 60 if `usec` is zero:

      Time.utc(2000, 1, 1, 0, 0, 0)  # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 1, 1, 0, 0, 59) # => 2000-01-01 00:00:59 UTC
      Time.utc(2000, 1, 1, 0, 0, 60) # => 2000-01-01 00:01:00 UTC

- `usec`: Microsecond in range (0..999999):

      Time.utc(2000, 1, 1, 0, 0, 0, 0)      # => 2000-01-01 00:00:00 UTC
      Time.utc(2000, 1, 1, 0, 0, 0, 999999) # => 2000-01-01 00:00:00.999999 UTC

The values may be:

- Integers, as above.

- Numerics convertible to integers:

      Time.utc(Float(0.0), Rational(1, 1), 1.0, 0.0, 0.0, 0.0, 0.0)
      # => 0000-01-01 00:00:00 UTC

- `String` integers:

      a = %w[0 1 1 0 0 0 0 0]
      # => ["0", "1", "1", "0", "0", "0", "0", "0"]
      Time.utc(*a) # => 0000-01-01 00:00:00 UTC

When exactly ten arguments are given, the arguments are interpreted as in the second calling sequence above:

    Time.utc(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy)

where the `dummy` arguments are ignored:

    a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    Time.utc(*a) # => 0005-04-03 02:01:00 UTC

This form is useful for creating a `Time` object from a 10-element array returned by `Time.to_a`:

    t = Time.new(2000, 1, 2, 3, 4, 5, 6) # => 2000-01-02 03:04:05 +000006
    a = t.to_a   # => [5, 4, 3, 2, 1, 2000, 0, 2, false, nil]
    Time.utc(*a) # => 2000-01-02 03:04:05 UTC

The two forms have their first six arguments in common, though in different orders; the ranges of these common arguments are the same for both forms; see above.

Raises an exception if the number of arguments is eight, nine, or greater than ten.

Related: `Time.local`.

    static VALUE
    time_s_mkutc(int argc, VALUE *argv, VALUE klass)
    {
        struct vtm vtm;

        time_arg(argc, argv, &vtm);
        return time_gmtime(time_new_timew(klass, timegmw(&vtm)));
    }

Also aliased as: gm

### Public Instance Methods

self + numeric → new_time click to toggle source

Returns a new `Time` object whose value is the sum of the numeric value of `self` and the given `numeric`:

    t = Time.new(2000) # => 2000-01-01 00:00:00 -0600
    t + (60 * 60 * 24) # => 2000-01-02 00:00:00 -0600
    t + 0.5            # => 2000-01-01 00:00:00.5 -0600

Related: `Time#-`.

    static VALUE
    time_plus(VALUE time1, VALUE time2)
    {
        struct time_object *tobj;
        GetTimeval(time1, tobj);

        if (IsTimeval(time2)) {
            rb_raise(rb_eTypeError, "time + time?");
        }
        return time_add(tobj, time1, time2, 1);
    }

self - numeric → new_time click to toggle source
self - other_time → float

When `numeric` is given, returns a new `Time` object whose value is the difference of the numeric value of `self` and `numeric`:

    t = Time.new(2000) # => 2000-01-01 00:00:00 -0600
    t - (60 * 60 * 24) # => 1999-12-31 00:00:00 -0600
    t - 0.5            # => 1999-12-31 23:59:59.5 -0600

When `other_time` is given, returns a `Float` whose value is the difference of the numeric values of `self` and `other_time` in seconds:

    t - t # => 0.0

Related: `Time#+`.

    static VALUE
    time_minus(VALUE time1, VALUE time2)
    {
        struct time_object *tobj;

        GetTimeval(time1, tobj);
        if (IsTimeval(time2)) {
            struct time_object *tobj2;

            GetTimeval(time2, tobj2);
            return rb_Float(rb_time_unmagnify_to_float(wsub(tobj->timew, tobj2->timew)));
        }
        return time_add(tobj, time1, time2, -1);
    }

self <=> other_time → -1, 0, +1, or nil click to toggle source

Compares `self` with `other_time`; returns:

- `-1`, if `self` is less than `other_time`.

- `0`, if `self` is equal to `other_time`.

- `1`, if `self` is greater then `other_time`.

- `nil`, if `self` and `other_time` are incomparable.

Examples:

    t = Time.now     # => 2007-11-19 08:12:12 -0600
    t2 = t + 2592000 # => 2007-12-19 08:12:12 -0600
    t <=> t2         # => -1
    t2 <=> t         # => 1

    t = Time.now     # => 2007-11-19 08:13:38 -0600
    t2 = t + 0.1     # => 2007-11-19 08:13:38 -0600
    t.nsec           # => 98222999
    t2.nsec          # => 198222999
    t <=> t2         # => -1
    t2 <=> t         # => 1
    t <=> t          # => 0

    static VALUE
    time_cmp(VALUE time1, VALUE time2)
    {
        struct time_object *tobj1, *tobj2;
        int n;

        GetTimeval(time1, tobj1);
        if (IsTimeval(time2)) {
            GetTimeval(time2, tobj2);
            n = wcmp(tobj1->timew, tobj2->timew);
        }
        else {
            return rb_invcmp(time1, time2);
        }
        if (n == 0) return INT2FIX(0);
        if (n > 0) return INT2FIX(1);
        return INT2FIX(-1);
    }

asctime()

Returns a string representation of `self`, formatted by `strftime('%a %b %e %T %Y')` or its shorthand version `strftime('%c')`; see Formats for Dates and Times:

    t = Time.new(2000, 12, 31, 23, 59, 59, 0.5)
    t.ctime                      # => "Sun Dec 31 23:59:59 2000"
    t.strftime('%a %b %e %T %Y') # => "Sun Dec 31 23:59:59 2000"
    t.strftime('%c')             # => "Sun Dec 31 23:59:59 2000"

Related: `Time#to_s`, `Time#inspect`:

    t.inspect                    # => "2000-12-31 23:59:59.5 +000001"
    t.to_s                       # => "2000-12-31 23:59:59 +0000"

Alias for: ctime
ceil(ndigits = 0) → new_time click to toggle source

Returns a new `Time` object whose numerical value is greater than or equal to `self` with its seconds truncated to precision `ndigits`:

    t = Time.utc(2010, 3, 30, 5, 43, 25.123456789r)
    t          # => 2010-03-30 05:43:25.123456789 UTC
    t.ceil     # => 2010-03-30 05:43:26 UTC
    t.ceil(2)  # => 2010-03-30 05:43:25.13 UTC
    t.ceil(4)  # => 2010-03-30 05:43:25.1235 UTC
    t.ceil(6)  # => 2010-03-30 05:43:25.123457 UTC
    t.ceil(8)  # => 2010-03-30 05:43:25.12345679 UTC
    t.ceil(10) # => 2010-03-30 05:43:25.123456789 UTC

    t = Time.utc(1999, 12, 31, 23, 59, 59)
    t              # => 1999-12-31 23:59:59 UTC
    (t + 0.4).ceil # => 2000-01-01 00:00:00 UTC
    (t + 0.9).ceil # => 2000-01-01 00:00:00 UTC
    (t + 1.4).ceil # => 2000-01-01 00:00:01 UTC
    (t + 1.9).ceil # => 2000-01-01 00:00:01 UTC

Related: `Time#floor`, `Time#round`.

    static VALUE
    time_ceil(int argc, VALUE *argv, VALUE time)
    {
        VALUE ndigits, v, den;
        struct time_object *tobj;

        if (!rb_check_arity(argc, 0, 1) || NIL_P(ndigits = argv[0]))
            den = INT2FIX(1);
        else
            den = ndigits_denominator(ndigits);

        GetTimeval(time, tobj);
        v = w2v(rb_time_unmagnify(tobj->timew));

        v = modv(v, den);
        if (!rb_equal(v, INT2FIX(0))) {
            v = subv(den, v);
        }
        return time_add(tobj, time, v, 1);
    }

ctime → string click to toggle source

Returns a string representation of `self`, formatted by `strftime('%a %b %e %T %Y')` or its shorthand version `strftime('%c')`; see Formats for Dates and Times:

    t = Time.new(2000, 12, 31, 23, 59, 59, 0.5)
    t.ctime                      # => "Sun Dec 31 23:59:59 2000"
    t.strftime('%a %b %e %T %Y') # => "Sun Dec 31 23:59:59 2000"
    t.strftime('%c')             # => "Sun Dec 31 23:59:59 2000"

Related: `Time#to_s`, `Time#inspect`:

    t.inspect                    # => "2000-12-31 23:59:59.5 +000001"
    t.to_s                       # => "2000-12-31 23:59:59 +0000"

    static VALUE
    time_asctime(VALUE time)
    {
        return strftimev("%a %b %e %T %Y", time, rb_usascii_encoding());
    }

Also aliased as: asctime
day()

Returns the integer day of the month for `self`, in range (1..31):

    t = Time.new(2000, 1, 2, 3, 4, 5, 6)
    # => 2000-01-02 03:04:05 +000006
    t.mday # => 2

Related: `Time#year`, `Time#hour`, `Time#min`.

Alias for: mday
deconstruct_keys(array_of_names_or_nil) → hash click to toggle source

Returns a hash of the name/value pairs, to use in pattern matching. Possible keys are: `:year`, `:month`, `:day`, `:yday`, `:wday`, `:hour`, `:min`, `:sec`, `:subsec`, `:dst`, `:zone`.

Possible usages:

    t = Time.utc(2022, 10, 5, 21, 25, 30)

    if t in wday: 3, day: ..7  # uses deconstruct_keys underneath
      puts "first Wednesday of the month"
    end
    #=> prints "first Wednesday of the month"

    case t
    in year: ...2022
      puts "too old"
    in month: ..9
      puts "quarter 1-3"
    in wday: 1..5, month:
      puts "working day in month #{month}"
    end
    #=> prints "working day in month 10"

Note that deconstruction by pattern can also be combined with class check:

    if t in Time(wday: 3, day: ..7)
      puts "first Wednesday of the month"
    end

    static VALUE
    time_deconstruct_keys(VALUE time, VALUE keys)
    {
        struct time_object *tobj;
        VALUE h;
        long i;

        GetTimeval(time, tobj);
        MAKE_TM_ENSURE(time, tobj, tobj->vtm.yday != 0);

        if (NIL_P(keys)) {
            h = rb_hash_new_with_size(11);

            rb_hash_aset(h, sym_year, tobj->vtm.year);
            rb_hash_aset(h, sym_month, INT2FIX(tobj->vtm.mon));
            rb_hash_aset(h, sym_day, INT2FIX(tobj->vtm.mday));
            rb_hash_aset(h, sym_yday, INT2FIX(tobj->vtm.yday));
            rb_hash_aset(h, sym_wday, INT2FIX(tobj->vtm.wday));
            rb_hash_aset(h, sym_hour, INT2FIX(tobj->vtm.hour));
            rb_hash_aset(h, sym_min, INT2FIX(tobj->vtm.min));
            rb_hash_aset(h, sym_sec, INT2FIX(tobj->vtm.sec));
            rb_hash_aset(h, sym_subsec,
                         quov(w2v(wmod(tobj->timew, WINT2FIXWV(TIME_SCALE))), INT2FIX(TIME_SCALE)));
            rb_hash_aset(h, sym_dst, RBOOL(tobj->vtm.isdst));
            rb_hash_aset(h, sym_zone, time_zone(time));

            return h;
        }
        if (UNLIKELY(!RB_TYPE_P(keys, T_ARRAY))) {
            rb_raise(rb_eTypeError,
                     "wrong argument type %"PRIsVALUE" (expected Array or nil)",
                     rb_obj_class(keys));

        }

        h = rb_hash_new_with_size(RARRAY_LEN(keys));

        for (i=0; i<RARRAY_LEN(keys); i++) {
            VALUE key = RARRAY_AREF(keys, i);

            if (sym_year == key) rb_hash_aset(h, key, tobj->vtm.year);
            if (sym_month == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.mon));
            if (sym_day == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.mday));
            if (sym_yday == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.yday));
            if (sym_wday == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.wday));
            if (sym_hour == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.hour));
            if (sym_min == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.min));
            if (sym_sec == key) rb_hash_aset(h, key, INT2FIX(tobj->vtm.sec));
            if (sym_subsec == key) {
                rb_hash_aset(h, key, quov(w2v(wmod(tobj->timew, WINT2FIXWV(TIME_SCALE))), INT2FIX(TIME_SCALE)));
            }
            if (sym_dst == key) rb_hash_aset(h, key, RBOOL(tobj->vtm.isdst));
            if (sym_zone == key) rb_hash_aset(h, key, time_zone(time));
        }
        return h;
    }

dst? → true or false

Returns `true` if `self` is in daylight saving time, `false` otherwise:

    t = Time.local(2000, 1, 1) # => 2000-01-01 00:00:00 -0600
    t.zone                     # => "Central Standard Time"
    t.dst?                     # => false
    t = Time.local(2000, 7, 1) # => 2000-07-01 00:00:00 -0500
    t.zone                     # => "Central Daylight Time"
    t.dst?                     # => true

Alias for: isdst
eql?(other_time) click to toggle source

Returns `true` if `self` and `other_time` are both `Time` objects with the exact same time value.

    static VALUE
    time_eql(VALUE time1, VALUE time2)
    {
        struct time_object *tobj1, *tobj2;

        GetTimeval(time1, tobj1);
        if (IsTimeval(time2)) {
            GetTimeval(time2, tobj2);
            return rb_equal(w2v(tobj1->timew), w2v(tobj2->timew));
        }
        return Qfalse;
    }

floor(ndigits = 0) → new_time click to toggle source

Returns a new `Time` object whose numerical value is less than or equal to `self` with its seconds truncated to precision `ndigits`:

    t = Time.utc(2010, 3, 30, 5, 43, 25.123456789r)
    t           # => 2010-03-30 05:43:25.123456789 UTC
    t.floor     # => 2010-03-30 05:43:25 UTC
    t.floor(2)  # => 2010-03-30 05:43:25.12 UTC
    t.floor(4)  # => 2010-03-30 05:43:25.1234 UTC
    t.floor(6)  # => 2010-03-30 05:43:25.123456 UTC
    t.floor(8)  # => 2010-03-30 05:43:25.12345678 UTC
    t.floor(10) # => 2010-03-30 05:43:25.123456789 UTC

    t = Time.utc(1999, 12, 31, 23, 59, 59)
    t               # => 1999-12-31 23:59:59 UTC
    (t + 0.4).floor # => 1999-12-31 23:59:59 UTC
    (t + 0.9).floor # => 1999-12-31 23:59:59 UTC
    (t + 1.4).floor # => 2000-01-01 00:00:00 UTC
    (t + 1.9).floor # => 2000-01-01 00:00:00 UTC

Related: `Time#ceil`, `Time#round`.

    static VALUE
    time_floor(int argc, VALUE *argv, VALUE time)
    {
        VALUE ndigits, v, den;
        struct time_object *tobj;

        if (!rb_check_arity(argc, 0, 1) || NIL_P(ndigits = argv[0]))
            den = INT2FIX(1);
        else
            den = ndigits_denominator(ndigits);

        GetTimeval(time, tobj);
        v = w2v(rb_time_unmagnify(tobj->timew));

        v = modv(v, den);
        return time_add(tobj, time, v, -1);
    }

friday? → true or false click to toggle source

Returns `true` if `self` represents a Friday, `false` otherwise:

    t = Time.utc(2000, 1, 7) # => 2000-01-07 00:00:00 UTC
    t.friday?                # => true

Related: `Time#saturday?`, `Time#sunday?`, `Time#monday?`.

    static VALUE
    time_friday(VALUE time)
    {
        wday_p(5);
    }

getgm -> new_time click to toggle source

Returns a new `Time` object representing the value of `self` converted to the UTC timezone:

    local = Time.local(2000) # => 2000-01-01 00:00:00 -0600
    local.utc?               # => false
    utc = local.getutc       # => 2000-01-01 06:00:00 UTC
    utc.utc?                 # => true
    utc == local             # => true

    static VALUE
    time_getgmtime(VALUE time)
    {
        return time_gmtime(time_dup(time));
    }

Also aliased as: getutc
getlocal(zone = nil) → new_time click to toggle source

Returns a new `Time` object representing the value of `self` converted to a given timezone; if `zone` is `nil`, the local timezone is used:

    t = Time.utc(2000)                    # => 2000-01-01 00:00:00 UTC
    t.getlocal                            # => 1999-12-31 18:00:00 -0600
    t.getlocal('+12:00')                  # => 2000-01-01 12:00:00 +1200

For forms of argument `zone`, see Timezone Specifiers.

    static VALUE
    time_getlocaltime(int argc, VALUE *argv, VALUE time)
    {
        VALUE off;

        if (rb_check_arity(argc, 0, 1) && !NIL_P(off = argv[0])) {
            VALUE zone = off;
            if (maybe_tzobj_p(zone)) {
                VALUE t = time_dup(time);
                if (zone_localtime(off, t)) return t;
            }

            if (NIL_P(off = utc_offset_arg(off))) {
                off = zone;
                if (NIL_P(zone = find_timezone(time, off))) invalid_utc_offset(off);
                time = time_dup(time);
                if (!zone_localtime(zone, time)) invalid_utc_offset(off);
                return time;
            }
            else if (off == UTC_ZONE) {
                return time_gmtime(time_dup(time));
            }
            validate_utc_offset(off);

            time = time_dup(time);
            time_set_utc_offset(time, off);
            return time_fixoff(time);
        }

        return time_localtime(time_dup(time));
    }

getutc → new_time

Returns a new `Time` object representing the value of `self` converted to the UTC timezone:

    local = Time.local(2000) # => 2000-01-01 00:00:00 -0600
    local.utc?               # => false
    utc = local.getutc       # => 2000-01-01 06:00:00 UTC
    utc.utc?                 # => true
    utc == local             # => true

Alias for: getgm
gmt?()

Returns `true` if `self` represents a time in UTC (GMT):

    now = Time.now
    # => 2022-08-18 10:24:13.5398485 -0500
    now.utc? # => false
    utc = Time.utc(2000, 1, 1, 20, 15, 1)
    # => 2000-01-01 20:15:01 UTC
    utc.utc? # => true

Related: `Time.utc`.

Alias for: utc?
gmt_offset()

Returns the offset in seconds between the timezones of UTC and `self`:

    Time.utc(2000, 1, 1).utc_offset   # => 0
    Time.local(2000, 1, 1).utc_offset # => -21600 # -6*3600, or minus six hours.

Alias for: gmtoff
gmtime -> self click to toggle source

Returns `self`, converted to the UTC timezone:

    t = Time.new(2000) # => 2000-01-01 00:00:00 -0600
    t.utc?             # => false
    t.utc              # => 2000-01-01 06:00:00 UTC
    t.utc?             # => true

Related: `Time#getutc` (returns a new converted `Time` object).

    static VALUE
    time_gmtime(VALUE time)
    {
        struct time_object *tobj;
        struct vtm vtm;

        GetTimeval(time, tobj);
        if (TZMODE_UTC_P(tobj)) {
            if (tobj->vtm.tm_got)
                return time;
        }
        else {
            time_modify(time);
        }

        vtm.zone = str_utc;
        GMTIMEW(tobj->timew, &vtm);
        time_set_vtm(time, tobj, vtm);

        tobj->vtm.tm_got = 1;
        TZMODE_SET_UTC(tobj);
        return time;
    }

Also aliased as: utc
gmtoff -> integer click to toggle source

Returns the offset in seconds between the timezones of UTC and `self`:

    Time.utc(2000, 1, 1).utc_offset   # => 0
    Time.local(2000, 1, 1).utc_offset # => -21600 # -6*3600, or minus six hours.

    VALUE
    rb_time_utc_offset(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);

        if (TZMODE_UTC_P(tobj)) {
            return INT2FIX(0);
        }
        else {
            MAKE_TM(time, tobj);
            return tobj->vtm.utc_offset;
        }
    }

Also aliased as: gmt_offset, utc_offset
hash → integer click to toggle source

Returns the integer hash code for `self`.

Related: `Object#hash`.

    static VALUE
    time_hash(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        return rb_hash(w2v(tobj->timew));
    }

hour → integer click to toggle source

Returns the integer hour of the day for `self`, in range (0..23):

    t = Time.new(2000, 1, 2, 3, 4, 5, 6)
    # => 2000-01-02 03:04:05 +000006
    t.hour # => 3

Related: `Time#year`, `Time#mon`, `Time#min`.

    static VALUE
    time_hour(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        MAKE_TM(time, tobj);
        return INT2FIX(tobj->vtm.hour);
    }

inspect → string click to toggle source

Returns a string representation of `self` with subseconds:

    t = Time.new(2000, 12, 31, 23, 59, 59, 0.5)
    t.inspect # => "2000-12-31 23:59:59.5 +000001"

Related: `Time#ctime`, `Time#to_s`:

    t.ctime   # => "Sun Dec 31 23:59:59 2000"
    t.to_s    # => "2000-12-31 23:59:59 +0000"

    static VALUE
    time_inspect(VALUE time)
    {
        struct time_object *tobj;
        VALUE str, subsec;

        GetTimeval(time, tobj);
        str = strftimev("%Y-%m-%d %H:%M:%S", time, rb_usascii_encoding());
        subsec = w2v(wmod(tobj->timew, WINT2FIXWV(TIME_SCALE)));
        if (subsec == INT2FIX(0)) {
        }
        else if (FIXNUM_P(subsec) && FIX2LONG(subsec) < TIME_SCALE) {
            long len;
            rb_str_catf(str, ".%09ld", FIX2LONG(subsec));
            for (len=RSTRING_LEN(str); RSTRING_PTR(str)[len-1] == '0' && len > 0; len--)
                ;
            rb_str_resize(str, len);
        }
        else {
            rb_str_cat_cstr(str, " ");
            subsec = quov(subsec, INT2FIX(TIME_SCALE));
            rb_str_concat(str, rb_obj_as_string(subsec));
        }
        if (TZMODE_UTC_P(tobj)) {
            rb_str_cat_cstr(str, " UTC");
        }
        else {
            /* ?TODO: subsecond offset */
            long off = NUM2LONG(rb_funcall(tobj->vtm.utc_offset, rb_intern("round"), 0));
            char sign = (off < 0) ? (off = -off, '-') : '+';
            int sec = off % 60;
            int min = (off /= 60) % 60;
            off /= 60;
            rb_str_catf(str, " %c%.2d%.2d", sign, (int)off, min);
            if (sec) rb_str_catf(str, "%.2d", sec);
        }
        return str;
    }

isdst -> true or false click to toggle source

Returns `true` if `self` is in daylight saving time, `false` otherwise:

    t = Time.local(2000, 1, 1) # => 2000-01-01 00:00:00 -0600
    t.zone                     # => "Central Standard Time"
    t.dst?                     # => false
    t = Time.local(2000, 7, 1) # => 2000-07-01 00:00:00 -0500
    t.zone                     # => "Central Daylight Time"
    t.dst?                     # => true

    static VALUE
    time_isdst(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        MAKE_TM(time, tobj);
        if (tobj->vtm.isdst == VTM_ISDST_INITVAL) {
            rb_raise(rb_eRuntimeError, "isdst is not set yet");
        }
        return RBOOL(tobj->vtm.isdst);
    }

Also aliased as: dst?
iso8601(*args)

Returns a string which represents the time as a 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.

`fraction_digits` specifies a number of digits to use for fractional seconds. Its default value is 0.

    t = Time.now
    t.xmlschema  # => "2011-10-05T22:26:12-04:00"

Alias for: xmlschema
localtime → self or new_time click to toggle source
localtime(zone) → new_time

With no argument given:

- Returns `self` if `self` is a local time.

- Otherwise returns a new `Time` in the user’s local timezone:

      t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
      t.localtime                         # => 2000-01-01 14:15:01 -0600

With argument `zone` given, returns the new `Time` object created by converting `self` to the given time zone:

    t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC
    t.localtime("-09:00")               # => 2000-01-01 11:15:01 -0900

For forms of argument `zone`, see Timezone Specifiers.

    static VALUE
    time_localtime_m(int argc, VALUE *argv, VALUE time)
    {
        VALUE off;

        if (rb_check_arity(argc, 0, 1) && !NIL_P(off = argv[0])) {
            return time_zonelocal(time, off);
        }

        return time_localtime(time);
    }

mday -> integer click to toggle source

Returns the integer day of the month for `self`, in range (1..31):

    t = Time.new(2000, 1, 2, 3, 4, 5, 6)
    # => 2000-01-02 03:04:05 +000006
    t.mday # => 2

Related: `Time#year`, `Time#hour`, `Time#min`.

    static VALUE
    time_mday(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        MAKE_TM(time, tobj);
        return INT2FIX(tobj->vtm.mday);
    }

Also aliased as: day
min → integer click to toggle source

Returns the integer minute of the hour for `self`, in range (0..59):

    t = Time.new(2000, 1, 2, 3, 4, 5, 6)
    # => 2000-01-02 03:04:05 +000006
    t.min # => 4

Related: `Time#year`, `Time#mon`, `Time#sec`.

    static VALUE
    time_min(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        MAKE_TM(time, tobj);
        return INT2FIX(tobj->vtm.min);
    }

mon → integer click to toggle source

Returns the integer month of the year for `self`, in range (1..12):

    t = Time.new(2000, 1, 2, 3, 4, 5, 6)
    # => 2000-01-02 03:04:05 +000006
    t.mon # => 1

Related: `Time#year`, `Time#hour`, `Time#min`.

    static VALUE
    time_mon(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        MAKE_TM(time, tobj);
        return INT2FIX(tobj->vtm.mon);
    }

Also aliased as: month
monday? → true or false click to toggle source

Returns `true` if `self` represents a Monday, `false` otherwise:

    t = Time.utc(2000, 1, 3) # => 2000-01-03 00:00:00 UTC
    t.monday?                # => true

Related: `Time#tuesday?`, `Time#wednesday?`, `Time#thursday?`.

    static VALUE
    time_monday(VALUE time)
    {
        wday_p(1);
    }

month()

Returns the integer month of the year for `self`, in range (1..12):

    t = Time.new(2000, 1, 2, 3, 4, 5, 6)
    # => 2000-01-02 03:04:05 +000006
    t.mon # => 1

Related: `Time#year`, `Time#hour`, `Time#min`.

Alias for: mon
nsec → integer

Returns the number of nanoseconds in the subseconds part of `self` in the range (0..999_999_999); lower-order digits are truncated, not rounded:

    t = Time.now # => 2022-07-11 15:04:53.3219637 -0500
    t.nsec       # => 321963700

Related: `Time#subsec` (returns exact subseconds).

Alias for: tv_nsec
round(ndigits = 0) → new_time click to toggle source

Returns a new `Time` object whose numeric value is that of `self`, with its seconds value rounded to precision `ndigits`:

    t = Time.utc(2010, 3, 30, 5, 43, 25.123456789r)
    t          # => 2010-03-30 05:43:25.123456789 UTC
    t.round    # => 2010-03-30 05:43:25 UTC
    t.round(0) # => 2010-03-30 05:43:25 UTC
    t.round(1) # => 2010-03-30 05:43:25.1 UTC
    t.round(2) # => 2010-03-30 05:43:25.12 UTC
    t.round(3) # => 2010-03-30 05:43:25.123 UTC
    t.round(4) # => 2010-03-30 05:43:25.1235 UTC

    t = Time.utc(1999, 12,31, 23, 59, 59)
    t                # => 1999-12-31 23:59:59 UTC
    (t + 0.4).round  # => 1999-12-31 23:59:59 UTC
    (t + 0.49).round # => 1999-12-31 23:59:59 UTC
    (t + 0.5).round  # => 2000-01-01 00:00:00 UTC
    (t + 1.4).round  # => 2000-01-01 00:00:00 UTC
    (t + 1.49).round # => 2000-01-01 00:00:00 UTC
    (t + 1.5).round  # => 2000-01-01 00:00:01 UTC

Related: `Time#ceil`, `Time#floor`.

    static VALUE
    time_round(int argc, VALUE *argv, VALUE time)
    {
        VALUE ndigits, v, den;
        struct time_object *tobj;

        if (!rb_check_arity(argc, 0, 1) || NIL_P(ndigits = argv[0]))
            den = INT2FIX(1);
        else
            den = ndigits_denominator(ndigits);

        GetTimeval(time, tobj);
        v = w2v(rb_time_unmagnify(tobj->timew));

        v = modv(v, den);
        if (lt(v, quov(den, INT2FIX(2))))
            return time_add(tobj, time, v, -1);
        else
            return time_add(tobj, time, subv(den, v), 1);
    }

saturday? → true or false click to toggle source

Returns `true` if `self` represents a Saturday, `false` otherwise:

    t = Time.utc(2000, 1, 1) # => 2000-01-01 00:00:00 UTC
    t.saturday?              # => true

Related: `Time#sunday?`, `Time#monday?`, `Time#tuesday?`.

    static VALUE
    time_saturday(VALUE time)
    {
        wday_p(6);
    }

sec → integer click to toggle source

Returns the integer second of the minute for `self`, in range (0..60):

    t = Time.new(2000, 1, 2, 3, 4, 5, 6)
    # => 2000-01-02 03:04:05 +000006
    t.sec # => 5

Note: the second value may be 60 when there is a leap second.

Related: `Time#year`, `Time#mon`, `Time#min`.

    static VALUE
    time_sec(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        MAKE_TM(time, tobj);
        return INT2FIX(tobj->vtm.sec);
    }

strftime(format_string) → string click to toggle source

Returns a string representation of `self`, formatted according to the given string `format`. See Formats for Dates and Times.

    static VALUE
    time_strftime(VALUE time, VALUE format)
    {
        struct time_object *tobj;
        const char *fmt;
        long len;
        rb_encoding *enc;
        VALUE tmp;

        GetTimeval(time, tobj);
        MAKE_TM_ENSURE(time, tobj, tobj->vtm.yday != 0);
        StringValue(format);
        if (!rb_enc_str_asciicompat_p(format)) {
            rb_raise(rb_eArgError, "format should have ASCII compatible encoding");
        }
        tmp = rb_str_tmp_frozen_acquire(format);
        fmt = RSTRING_PTR(tmp);
        len = RSTRING_LEN(tmp);
        enc = rb_enc_get(format);
        if (len == 0) {
            rb_warning("strftime called with empty format string");
            return rb_enc_str_new(0, 0, enc);
        }
        else {
            VALUE str = rb_strftime_alloc(fmt, len, enc, time, &tobj->vtm, tobj->timew,
                                          TZMODE_UTC_P(tobj));
            rb_str_tmp_frozen_release(format, tmp);
            if (!str) rb_raise(rb_eArgError, "invalid format: %"PRIsVALUE, format);
            return str;
        }
    }

subsec → numeric click to toggle source

Returns the exact subseconds for `self` as a `Numeric` (`Integer` or `Rational`):

    t = Time.now # => 2022-07-11 15:11:36.8490302 -0500
    t.subsec     # => (4245151/5000000)

If the subseconds is zero, returns integer zero:

    t = Time.new(2000, 1, 1, 2, 3, 4) # => 2000-01-01 02:03:04 -0600
    t.subsec                          # => 0

    static VALUE
    time_subsec(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        return quov(w2v(wmod(tobj->timew, WINT2FIXWV(TIME_SCALE))), INT2FIX(TIME_SCALE));
    }

sunday? → true or false click to toggle source

Returns `true` if `self` represents a Sunday, `false` otherwise:

    t = Time.utc(2000, 1, 2) # => 2000-01-02 00:00:00 UTC
    t.sunday?                # => true

Related: `Time#monday?`, `Time#tuesday?`, `Time#wednesday?`.

    static VALUE
    time_sunday(VALUE time)
    {
        wday_p(0);
    }

thursday? → true or false click to toggle source

Returns `true` if `self` represents a Thursday, `false` otherwise:

    t = Time.utc(2000, 1, 6) # => 2000-01-06 00:00:00 UTC
    t.thursday?              # => true

Related: `Time#friday?`, `Time#saturday?`, `Time#sunday?`.

    static VALUE
    time_thursday(VALUE time)
    {
        wday_p(4);
    }

to_a → array click to toggle source

Returns a 10-element array of values representing `self`:

    Time.utc(2000, 1, 1).to_a
    # => [0,   0,   0,    1,   1,   2000, 6,    1,    false, "UTC"]
    #    [sec, min, hour, day, mon, year, wday, yday, dst?,   zone]

The returned array is suitable for use as an argument to `Time.utc` or `Time.local` to create a new `Time` object.

    static VALUE
    time_to_a(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        MAKE_TM_ENSURE(time, tobj, tobj->vtm.yday != 0);
        return rb_ary_new3(10,
                        INT2FIX(tobj->vtm.sec),
                        INT2FIX(tobj->vtm.min),
                        INT2FIX(tobj->vtm.hour),
                        INT2FIX(tobj->vtm.mday),
                        INT2FIX(tobj->vtm.mon),
                        tobj->vtm.year,
                        INT2FIX(tobj->vtm.wday),
                        INT2FIX(tobj->vtm.yday),
                        RBOOL(tobj->vtm.isdst),
                        time_zone(time));
    }

to_f → float click to toggle source

Returns the value of `self` as a `Float` number Epoch seconds; subseconds are included.

The stored value of `self` is a Rational, which means that the returned value may be approximate:

    Time.utc(1970, 1, 1, 0, 0, 0).to_f         # => 0.0
    Time.utc(1970, 1, 1, 0, 0, 0, 999999).to_f # => 0.999999
    Time.utc(1950, 1, 1, 0, 0, 0).to_f         # => -631152000.0
    Time.utc(1990, 1, 1, 0, 0, 0).to_f         # => 631152000.0

Related: `Time#to_i`, `Time#to_r`.

    static VALUE
    time_to_f(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        return rb_Float(rb_time_unmagnify_to_float(tobj->timew));
    }

to_i → integer click to toggle source

Returns the value of `self` as integer Epoch seconds; subseconds are truncated (not rounded):

    Time.utc(1970, 1, 1, 0, 0, 0).to_i         # => 0
    Time.utc(1970, 1, 1, 0, 0, 0, 999999).to_i # => 0
    Time.utc(1950, 1, 1, 0, 0, 0).to_i         # => -631152000
    Time.utc(1990, 1, 1, 0, 0, 0).to_i         # => 631152000

Related: `Time#to_f` `Time#to_r`.

    static VALUE
    time_to_i(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        return w2v(wdiv(tobj->timew, WINT2FIXWV(TIME_SCALE)));
    }

Also aliased as: tv_sec
to_r → rational click to toggle source

Returns the value of `self` as a `Rational` exact number of Epoch seconds;

    Time.now.to_r # => (16571402750320203/10000000)

Related: `Time#to_f`, `Time#to_i`.

    static VALUE
    time_to_r(VALUE time)
    {
        struct time_object *tobj;
        VALUE v;

        GetTimeval(time, tobj);
        v = rb_time_unmagnify_to_rational(tobj->timew);
        if (!RB_TYPE_P(v, T_RATIONAL)) {
            v = rb_Rational1(v);
        }
        return v;
    }

to_s → string click to toggle source

Returns a string representation of `self`, without subseconds:

    t = Time.new(2000, 12, 31, 23, 59, 59, 0.5)
    t.to_s    # => "2000-12-31 23:59:59 +0000"

Related: `Time#ctime`, `Time#inspect`:

    t.ctime   # => "Sun Dec 31 23:59:59 2000"
    t.inspect # => "2000-12-31 23:59:59.5 +000001"

    static VALUE
    time_to_s(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        if (TZMODE_UTC_P(tobj))
            return strftimev("%Y-%m-%d %H:%M:%S UTC", time, rb_usascii_encoding());
        else
            return strftimev("%Y-%m-%d %H:%M:%S %z", time, rb_usascii_encoding());
    }

tuesday? → true or false click to toggle source

Returns `true` if `self` represents a Tuesday, `false` otherwise:

    t = Time.utc(2000, 1, 4) # => 2000-01-04 00:00:00 UTC
    t.tuesday?               # => true

Related: `Time#wednesday?`, `Time#thursday?`, `Time#friday?`.

    static VALUE
    time_tuesday(VALUE time)
    {
        wday_p(2);
    }

tv_nsec -> integer click to toggle source

Returns the number of nanoseconds in the subseconds part of `self` in the range (0..999_999_999); lower-order digits are truncated, not rounded:

    t = Time.now # => 2022-07-11 15:04:53.3219637 -0500
    t.nsec       # => 321963700

Related: `Time#subsec` (returns exact subseconds).

    static VALUE
    time_nsec(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        return rb_to_int(w2v(wmulquoll(wmod(tobj->timew, WINT2WV(TIME_SCALE)), 1000000000, TIME_SCALE)));
    }

Also aliased as: nsec
tv_sec()

Returns the value of `self` as integer Epoch seconds; subseconds are truncated (not rounded):

    Time.utc(1970, 1, 1, 0, 0, 0).to_i         # => 0
    Time.utc(1970, 1, 1, 0, 0, 0, 999999).to_i # => 0
    Time.utc(1950, 1, 1, 0, 0, 0).to_i         # => -631152000
    Time.utc(1990, 1, 1, 0, 0, 0).to_i         # => 631152000

Related: `Time#to_f` `Time#to_r`.

Alias for: to_i
tv_usec -> integer click to toggle source

Returns the number of microseconds in the subseconds part of `self` in the range (0..999_999); lower-order digits are truncated, not rounded:

    t = Time.now # => 2022-07-11 14:59:47.5484697 -0500
    t.usec       # => 548469

Related: `Time#subsec` (returns exact subseconds).

    static VALUE
    time_usec(VALUE time)
    {
        struct time_object *tobj;
        wideval_t w, q, r;

        GetTimeval(time, tobj);

        w = wmod(tobj->timew, WINT2WV(TIME_SCALE));
        wmuldivmod(w, WINT2FIXWV(1000000), WINT2FIXWV(TIME_SCALE), &q, &r);
        return rb_to_int(w2v(q));
    }

Also aliased as: usec
usec → integer

Returns the number of microseconds in the subseconds part of `self` in the range (0..999_999); lower-order digits are truncated, not rounded:

    t = Time.now # => 2022-07-11 14:59:47.5484697 -0500
    t.usec       # => 548469

Related: `Time#subsec` (returns exact subseconds).

Alias for: tv_usec
utc → self

Returns `self`, converted to the UTC timezone:

    t = Time.new(2000) # => 2000-01-01 00:00:00 -0600
    t.utc?             # => false
    t.utc              # => 2000-01-01 06:00:00 UTC
    t.utc?             # => true

Related: `Time#getutc` (returns a new converted `Time` object).

Alias for: gmtime
utc? → true or false click to toggle source

Returns `true` if `self` represents a time in UTC (GMT):

    now = Time.now
    # => 2022-08-18 10:24:13.5398485 -0500
    now.utc? # => false
    utc = Time.utc(2000, 1, 1, 20, 15, 1)
    # => 2000-01-01 20:15:01 UTC
    utc.utc? # => true

Related: `Time.utc`.

    static VALUE
    time_utc_p(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        return RBOOL(TZMODE_UTC_P(tobj));
    }

Also aliased as: gmt?
utc_offset → integer

Returns the offset in seconds between the timezones of UTC and `self`:

    Time.utc(2000, 1, 1).utc_offset   # => 0
    Time.local(2000, 1, 1).utc_offset # => -21600 # -6*3600, or minus six hours.

Alias for: gmtoff
wday → integer click to toggle source

Returns the integer day of the week for `self`, in range (0..6), with Sunday as zero.

    t = Time.new(2000, 1, 2, 3, 4, 5, 6)
    # => 2000-01-02 03:04:05 +000006
    t.wday    # => 0
    t.sunday? # => true

Related: `Time#year`, `Time#hour`, `Time#min`.

    static VALUE
    time_wday(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        MAKE_TM_ENSURE(time, tobj, tobj->vtm.wday != VTM_WDAY_INITVAL);
        return INT2FIX((int)tobj->vtm.wday);
    }

wednesday? → true or false click to toggle source

Returns `true` if `self` represents a Wednesday, `false` otherwise:

    t = Time.utc(2000, 1, 5) # => 2000-01-05 00:00:00 UTC
    t.wednesday?             # => true

Related: `Time#thursday?`, `Time#friday?`, `Time#saturday?`.

    static VALUE
    time_wednesday(VALUE time)
    {
        wday_p(3);
    }

xmlschema(fraction_digits=0) → string click to toggle source

Returns a string which represents the time as a 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.

`fraction_digits` specifies a number of digits to use for fractional seconds. Its default value is 0.

    t = Time.now
    t.xmlschema  # => "2011-10-05T22:26:12-04:00"

    static VALUE
    time_xmlschema(int argc, VALUE *argv, VALUE time)
    {
        long fraction_digits = 0;
        rb_check_arity(argc, 0, 1);
        if (argc > 0) {
            fraction_digits = NUM2LONG(argv[0]);
            if (fraction_digits < 0) {
                fraction_digits = 0;
            }
        }

        struct time_object *tobj;

        GetTimeval(time, tobj);
        MAKE_TM(time, tobj);

        const long size_after_year = sizeof("-MM-DDTHH:MM:SS+ZH:ZM") + fraction_digits
            + (fraction_digits > 0);
        VALUE str;
        char *ptr;

    # define fill_digits_long(len, prec, n) \
        for (int fill_it = 1, written = snprintf(ptr, len, "%0*ld", prec, n); \
             fill_it; ptr += written, fill_it = 0)

        if (FIXNUM_P(tobj->vtm.year)) {
            long year = FIX2LONG(tobj->vtm.year);
            int year_width = (year < 0) + rb_strlen_lit("YYYY");
            int w = (year >= -9999 && year <= 9999 ? year_width : (year < 0) + (int)DECIMAL_SIZE_OF(year));
            str = rb_usascii_str_new(0, w + size_after_year);
            ptr = RSTRING_PTR(str);
            fill_digits_long(w + 1, year_width, year) {
                if (year >= -9999 && year <= 9999) {
                    RUBY_ASSERT(written == year_width);
                }
                else {
                    RUBY_ASSERT(written >= year_width);
                    RUBY_ASSERT(written <= w);
                }
            }
        }
        else {
            str = rb_int2str(tobj->vtm.year, 10);
            rb_str_modify_expand(str, size_after_year);
            ptr = RSTRING_END(str);
        }

    # define fill_2(c, n) (*ptr++ = c, *ptr++ = '0' + (n) / 10, *ptr++ = '0' + (n) % 10)
        fill_2('-', tobj->vtm.mon);
        fill_2('-', tobj->vtm.mday);
        fill_2('T', tobj->vtm.hour);
        fill_2(':', tobj->vtm.min);
        fill_2(':', tobj->vtm.sec);

        if (fraction_digits > 0) {
            VALUE subsecx = tobj->vtm.subsecx;
            long subsec;
            int digits = -1;
            *ptr++ = '.';
            if (fraction_digits <= TIME_SCALE_NUMDIGITS) {
                digits = TIME_SCALE_NUMDIGITS - (int)fraction_digits;
            }
            else {
                long w = fraction_digits - TIME_SCALE_NUMDIGITS; /* > 0 */
                subsecx = mulv(subsecx, rb_int_positive_pow(10, (unsigned long)w));
                if (!RB_INTEGER_TYPE_P(subsecx)) { /* maybe Rational */
                    subsecx = rb_Integer(subsecx);
                }
                if (FIXNUM_P(subsecx)) digits = 0;
            }
            if (digits >= 0 && fraction_digits < INT_MAX) {
                subsec = NUM2LONG(subsecx);
                if (digits > 0) subsec /= (long)pow(10, digits);
                fill_digits_long(fraction_digits + 1, (int)fraction_digits, subsec) {
                    RUBY_ASSERT(written == (int)fraction_digits);
                }
            }
            else {
                subsecx = rb_int2str(subsecx, 10);
                long len = RSTRING_LEN(subsecx);
                if (fraction_digits > len) {
                    memset(ptr, '0', fraction_digits - len);
                }
                else {
                    len = fraction_digits;
                }
                ptr += fraction_digits;
                memcpy(ptr - len, RSTRING_PTR(subsecx), len);
            }
        }

        if (TZMODE_UTC_P(tobj)) {
            *ptr = 'Z';
            ptr++;
        }
        else {
            long offset = NUM2LONG(rb_time_utc_offset(time));
            char sign = offset < 0 ? '-' : '+';
            if (offset < 0) offset = -offset;
            offset /= 60;
            fill_2(sign, offset / 60);
            fill_2(':', offset % 60);
        }
        const char *const start = RSTRING_PTR(str);
        rb_str_set_len(str, ptr - start); // We could skip coderange scanning as we know it's full ASCII.
        return str;
    }

Also aliased as: iso8601
yday → integer click to toggle source

Returns the integer day of the year of `self`, in range (1..366).

    Time.new(2000, 1, 1).yday   # => 1
    Time.new(2000, 12, 31).yday # => 366

    static VALUE
    time_yday(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        MAKE_TM_ENSURE(time, tobj, tobj->vtm.yday != 0);
        return INT2FIX(tobj->vtm.yday);
    }

year → integer click to toggle source

Returns the integer year for `self`:

    t = Time.new(2000, 1, 2, 3, 4, 5, 6)
    # => 2000-01-02 03:04:05 +000006
    t.year # => 2000

Related: `Time#mon`, `Time#hour`, `Time#min`.

    static VALUE
    time_year(VALUE time)
    {
        struct time_object *tobj;

        GetTimeval(time, tobj);
        MAKE_TM(time, tobj);
        return tobj->vtm.year;
    }

zone → string or timezone click to toggle source

Returns the string name of the time zone for `self`:

    Time.utc(2000, 1, 1).zone # => "UTC"
    Time.new(2000, 1, 1).zone # => "Central Standard Time"

    static VALUE
    time_zone(VALUE time)
    {
        struct time_object *tobj;
        VALUE zone;

        GetTimeval(time, tobj);
        MAKE_TM(time, tobj);

        if (TZMODE_UTC_P(tobj)) {
            return rb_usascii_str_new_cstr("UTC");
        }
        zone = tobj->vtm.zone;
        if (NIL_P(zone))
            return Qnil;

        if (RB_TYPE_P(zone, T_STRING))
            zone = rb_str_dup(zone);
        return zone;
    }