Class: Time
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
| Instance Chain: 
          self,
           ::Comparable | |
| Inherits: | Object | 
| Defined in: | timev.rb, time.c | 
Overview
A Time object represents a date and time:
Time.new(2000, 1, 1, 0, 0, 0) # => 2000-01-01 00:00:00 -0600Although 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 #to_r:
Time.at(0).to_r        # => (0/1)
Time.at(0.999999).to_r # => (9007190247541737/9007199254740992)Other retrieval methods such as #to_i and #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 .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 .new. This will use the current system time. .now is an alias for this. You can also pass parts of the time to .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 -0500You can pass a UTC offset:
Time.new(2002, 10, 31, 2, 2, 2, "+02:00") #=> 2002-10-31 02:02:02 +0200zone = timezone("Europe/Athens")      # Eastern European Time, UTC+2
Time.new(2002, 10, 31, 2, 2, 2, zone) #=> 2002-10-31 02:02:02 +0200You can also use .local and .utc to infer local and UTC timezones instead of using the current system setting.
You can also create a new time using .at which takes the number of seconds (with subsecond) since the Unix Epoch.
Time.at(628232400) #=> 1989-11-28 00:00:00 -0500Working 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? #=> falseWhat year was that again?
t.year #=> 1993Was it daylight savings at the time?
t.dst? #=> falseWhat’s the day a year later?
t + (60*60*24*365) #=> 1994-02-24 12:00:00 +0900How many seconds was that since the Unix Epoch?
t.to_i #=> 730522800You 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) #=> trueWhat’s Here
First, what’s elsewhere. Class Time:
- 
Inherits from class Object. 
- 
Includes module Comparable. 
Here, class Time provides methods that are useful for:
- 
{Time#label-Methods+for+Rounding Rounding a }. 
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. 
- 
#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 ::Rationalnumber of seconds since epoch for the time.
- 
#zone: Returns a string representation of the timezone of the time. 
Methods for Querying
- 
#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
Methods for Converting
- 
#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. 
- 
#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 zone Specifiers.
Timezone Specifiers
Certain Time methods accept arguments that specify timezones:
- 
.at: keyword argument in:.
- 
.now: keyword argument in:.
- 
#localtime: positional argument #zone. 
The value given with any of these must be one of the following (each detailed below):
Hours/Minutes Offsets
The zone value may be a string offset from UTC in the form '+HH:MM' or '-HH:MM', where:
- 
HHis the 2-digit hour in the range0..23.
- 
MMis the 2-digit minute in the range0..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 +2359Single-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 UTCInteger 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 +235959Timezone 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 tzas the value of positional argument #zone or keyword argumentin:.- Argument
- Returns
- 
a Time-like object in the UTC timezone. 
 
- 
utc_to_local:Called when Time.at or Time.now is invoked with tzas the value for keyword argumentin:, and when Time#getlocal or Time#localtime is called withtzas 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
- 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
- Returns
- 
a string abbreviation for the timezone name. 
 
- 
Called when Time.at or Time.now is invoked with tzas the value for keyword argumentin:, and when Time#getlocal or Time#localtime is called withtzas the value for positional argument #zone.- Argument
- 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:
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 -0500Or, 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 -0500You can define this method per subclasses, or on the toplevel Time class.
Class Method Summary
- 
    
      .at(time, subsec = false, unit = :microsecond, in: nil)  
    
    Returns a new Timeobject based on the given arguments.
- 
    
      .utc(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0)  ⇒ Time 
      (also: .utc)
    
    Returns a new Timeobject based the on given arguments, in the UTC timezone.
- 
    
      .local(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0)  ⇒ Time 
      (also: .mktime)
    
    Like .utc, except that the returned Timeobject has the local timezone, not the UTC timezone:
- 
    
      .local(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0)  ⇒ Time 
    
    Alias for .local. 
- 
    
      .new(year = nil, mon = nil, mday = nil, hour = nil, min = nil, sec = nil, zone = nil, in: nil, precision: 9)  ⇒ Time 
    
    constructor
    Returns a new Timeobject based on the given arguments, by default in the local timezone.
- 
    
      .now(in: nil)  
    
    Creates a new Timeobject from the current system time.
- 
    
      .utc(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0)  ⇒ Time 
    
    Alias for .gm. 
Instance Attribute Summary
- 
    
      #dst?  ⇒ Boolean 
      (also: #isdst)
    
    readonly
    Returns trueifselfis in daylight saving time,falseotherwise:
- 
    
      #friday?  ⇒ Boolean 
    
    readonly
    Returns trueifselfrepresents a Friday,falseotherwise:
- 
    
      #gmt?  ⇒ Boolean 
      (also: #utc?)
    
    readonly
    Returns trueifselfrepresents a time in UTC (GMT):
- 
    
      #isdst  ⇒ Boolean 
    
    readonly
    Alias for #dst?. 
- 
    
      #monday?  ⇒ Boolean 
    
    readonly
    Returns trueifselfrepresents a Monday,falseotherwise:
- 
    
      #saturday?  ⇒ Boolean 
    
    readonly
    Returns trueifselfrepresents a Saturday,falseotherwise:
- 
    
      #sunday?  ⇒ Boolean 
    
    readonly
    Returns trueifselfrepresents a Sunday,falseotherwise:
- 
    
      #thursday?  ⇒ Boolean 
    
    readonly
    Returns trueifselfrepresents a Thursday,falseotherwise:
- 
    
      #tuesday?  ⇒ Boolean 
    
    readonly
    Returns trueifselfrepresents a Tuesday,falseotherwise:
- 
    
      #utc?  ⇒ Boolean 
    
    readonly
    Alias for #gmt?. 
- 
    
      #wednesday?  ⇒ Boolean 
    
    readonly
    Returns trueifselfrepresents a Wednesday,falseotherwise:
Instance Method Summary
- 
    
      #+(numeric)  ⇒ Time 
    
    Returns a new Timeobject whose value is the sum of the numeric value ofselfand the givennumeric:
- 
    
      #-(numeric)  ⇒ Time 
    
    When numericis given, returns a newTimeobject whose value is the difference of the numeric value ofselfandnumeric:
- 
    
      #<=>(other_time)  ⇒ 1, ... 
    
    Compares selfwithother_time; returns:
- 
    
      #asctime  ⇒ String 
    
    Alias for #ctime. 
- 
    
      #ceil(ndigits = 0)  ⇒ Time 
    
    Returns a new Timeobject whose numerical value is greater than or equal toselfwith its seconds truncated to precisionndigits:
- 
    
      #ctime  ⇒ String 
      (also: #asctime)
    
    Returns a string representation of self, formatted bystrftime('%a %b %e %T %Y')or its shorthand versionstrftime('%c'); see Formats for Dates and Times:
- 
    
      #day  ⇒ Integer 
      (also: #mday)
    
    Returns the integer day of the month for self, in range (1..31):
- 
    
      #deconstruct_keys(array_of_names_or_nil)  ⇒ Hash 
    
    Returns a hash of the name/value pairs, to use in pattern matching. 
- 
    
      #eql?(other_time)  
    
    Returns trueifselfandother_timeare bothTimeobjects with the exact same time value.
- 
    
      #floor(ndigits = 0)  ⇒ Time 
    
    Returns a new Timeobject whose numerical value is less than or equal toselfwith its seconds truncated to precisionndigits:
- 
    
      #getutc  ⇒ Time 
      (also: #getutc)
    
    Returns a new Timeobject representing the value ofselfconverted to the UTC timezone:
- 
    
      #getlocal(zone = nil)  ⇒ Time 
    
    Returns a new Timeobject representing the value ofselfconverted to a given timezone; if #zone isnil, the local timezone is used:
- 
    
      #getutc  ⇒ Time 
    
    Alias for #getgm. 
- 
    
      #gmt_offset  ⇒ Integer 
    
    Alias for #gmtoff. 
- 
    
      #gmtime  ⇒ self 
    
    Alias for #utc. 
- 
    
      #utc_offset  ⇒ Integer 
      (also: #gmt_offset, #utc_offset)
    
    Returns the offset in seconds between the timezones of UTC and self:
- 
    
      #hash  ⇒ Integer 
    
    Returns the integer hash code for self.
- 
    
      #hour  ⇒ Integer 
    
    Returns the integer hour of the day for self, in range (0..23):
- 
    
      #inspect  ⇒ String 
    
    Returns a string representation of selfwith subseconds:
- 
    
      #iso8601(fraction_digits = 0)  ⇒ String 
      (also: #xmlschema)
    
    Returns a string which represents the time as a dateTime defined by XML Schema: 
- 
    
      #localtime  ⇒ self, Time 
    
    With no argument given: 
- 
    
      #mday  ⇒ Integer 
    
    Alias for #day. 
- 
    
      #min  ⇒ Integer 
    
    Returns the integer minute of the hour for self, in range (0..59):
- 
    
      #mon  ⇒ Integer 
      (also: #month)
    
    Returns the integer month of the year for self, in range (1..12):
- 
    
      #month  ⇒ Integer 
    
    Alias for #mon. 
- 
    
      #nsec  ⇒ Integer 
      (also: #tv_nsec)
    
    Returns the number of nanoseconds in the subseconds part of selfin the range (0..999_999_999); lower-order digits are truncated, not rounded:
- 
    
      #round(ndigits = 0)  ⇒ Time 
    
    Returns a new Timeobject whose numeric value is that ofself, with its seconds value rounded to precisionndigits:
- 
    
      #sec  ⇒ Integer 
    
    Returns the integer second of the minute for self, in range (0..60):
- 
    
      #strftime(format_string)  ⇒ String 
    
    Returns a string representation of self, formatted according to the given stringformat.
- 
    
      #subsec  ⇒ Numeric 
    
    Returns the exact subseconds for selfas a::Numeric(Integer or::Rational):
- 
    
      #to_a  ⇒ Array 
    
    Returns a 10-element array of values representing self:
- 
    
      #to_f  ⇒ Float 
    
    Returns the value of selfas a::Floatnumber Epoch seconds; subseconds are included.
- 
    
      #to_i  ⇒ Integer 
      (also: #tv_sec)
    
    Returns the value of selfas integer Epoch seconds; subseconds are truncated (not rounded):
- 
    
      #to_r  ⇒ Rational 
    
    Returns the value of selfas a::Rationalexact number of Epoch seconds;.
- 
    
      #to_s  ⇒ String 
    
    Returns a string representation of self, without subseconds:
- 
    
      #tv_nsec  ⇒ Integer 
    
    Alias for #nsec. 
- 
    
      #tv_sec  ⇒ Integer 
    
    Alias for #to_i. 
- 
    
      #tv_usec  ⇒ Integer 
    
    Alias for #usec. 
- 
    
      #usec  ⇒ Integer 
      (also: #tv_usec)
    
    Returns the number of microseconds in the subseconds part of selfin the range (0..999_999); lower-order digits are truncated, not rounded:
- 
    
      #utc  ⇒ self 
      (also: #gmtime)
    
    readonly
    Returns self, converted to the UTC timezone:
- 
    
      #utc_offset  ⇒ Integer 
    
    Alias for #gmtoff. 
- 
    
      #wday  ⇒ Integer 
    
    Returns the integer day of the week for self, in range (0..6), with Sunday as zero.
- 
    
      #xmlschema(fraction_digits = 0)  ⇒ String 
    
    Alias for #iso8601. 
- 
    
      #yday  ⇒ Integer 
    
    Returns the integer day of the year of self, in range (1..366).
- 
    
      #year  ⇒ Integer 
    
    Returns the integer year for self:
- 
    
      #zone  ⇒ String, Time 
    
    Returns the string name of the time zone for self:
- #initialize_copy(time) Internal use only
- #_dump(*args) private Internal use only
- #_load(str) private Internal use only
::Comparable - Included
| #< | Compares two objects based on the receiver’s #<=> method, returning true if it returns a value less than 0. | 
| #<= | Compares two objects based on the receiver’s #<=> method, returning true if it returns a value less than or equal to 0. | 
| #== | Compares two objects based on the receiver’s #<=> method, returning true if it returns 0. | 
| #> | Compares two objects based on the receiver’s #<=> method, returning true if it returns a value greater than 0. | 
| #>= | Compares two objects based on the receiver’s #<=> method, returning true if it returns a value greater than or equal to 0. | 
| #between? | |
| #clamp | 
Constructor Details
    .new(year = nil, mon = nil, mday = nil, hour = nil, min = nil, sec = nil, zone = nil, in: nil, precision: 9)  ⇒ Time   
Returns a new Time object based on the given arguments, by default in the local timezone.
With no positional arguments, returns the value of .now:
Time.new # => 2021-04-24 17:27:46.0512465 -0500With 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 -0600With 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 -0600For 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
- 
::Stringintegers: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 -1200Since 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 ofTime. Ignored unless the first argument is a string.
# File '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
Class Method Details
.at(time, subsec = false, unit = :microsecond, in: nil)
Returns a new Time object based on the given arguments.
Required argument time may be either of:
- 
A Timeobject, whose value is the basis for the returned time; also influenced by optional keyword argumentin:(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 -0500Optional 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
- 
:microsecondor: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
- 
:nanosecondor: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 -1200For the forms of argument #zone, see Timezone Specifiers.
    
      .utc(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0)  ⇒ Time 
      .utc(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy)  ⇒ Time 
    
    Also known as: .utc
  
Time 
      .utc(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy)  ⇒ 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 UTCThere 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
- 
::Stringintegers: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 UTCThis form is useful for creating a Time object from a 10-element array returned by #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 UTCThe 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: .local.
# File 'time.c', line 3742
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)));
}
  
    
      .local(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0)  ⇒ Time 
      .local(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy)  ⇒ Time 
    
    Also known as: .mktime
  
Time 
      .local(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy)  ⇒ Time 
    Like .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# File 'time.c', line 3768
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)));
}
  
    
      .local(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0)  ⇒ Time 
      .local(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy)  ⇒ Time 
    
  
Time 
      .local(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy)  ⇒ Time 
    Alias for .local.
.now(in: nil)
Creates a new Time object from the current system time. This is the same as .new without arguments.
Time.now               # => 2009-06-24 12:39:54 +0900
Time.now(in: '+04:00') # => 2009-06-24 07:39:54 +0400For forms of argument #zone, see Timezone Specifiers.
# File '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)  ⇒ Time 
      .utc(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy)  ⇒ Time 
    
  
Time 
      .utc(sec, min, hour, mday, month, year, dummy, dummy, dummy, dummy)  ⇒ Time 
    Alias for .gm.
Instance Attribute Details
    #dst?  ⇒ Boolean  (readonly)    Also known as: #isdst
  
# File 'time.c', line 5009
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);
}
  
    #friday?  ⇒ Boolean  (readonly)  
Returns true if self represents a Friday, false otherwise:
t = Time.utc(2000, 1, 7) # => 2000-01-07 00:00:00 UTC
t.friday?                # => trueRelated: #saturday?, #sunday?, #monday?.
# File 'time.c', line 4950
static VALUE
time_friday(VALUE time)
{
    wday_p(5);
}
  
    #gmt?  ⇒ Boolean  (readonly)    Also known as: #utc?
  
Returns true if self represents a time in UTC (GMT):
now = Time.now
# => 2022-08-18 10:24:13.5398485 -0500
now.utc? # => false
now.getutc.utc? # => true
utc = Time.utc(2000, 1, 1, 20, 15, 1)
# => 2000-01-01 20:15:01 UTC
utc.utc? # => trueTime objects created with these methods are considered to be in UTC:
Objects created in other ways will not be treated as UTC even if the environment variable “TZ” is “UTC”.
Related: .utc.
# File 'time.c', line 4028
static VALUE
time_utc_p(VALUE time)
{
    struct time_object *tobj;
    GetTimeval(time, tobj);
    return RBOOL(TZMODE_UTC_P(tobj));
}
  
    
      #dst?  ⇒ Boolean  (readonly)
      #isdst  ⇒ Boolean 
    
  
Boolean  (readonly)
      #isdst  ⇒ Boolean 
    Alias for #dst?.
    #monday?  ⇒ Boolean  (readonly)  
Returns true if self represents a Monday, false otherwise:
t = Time.utc(2000, 1, 3) # => 2000-01-03 00:00:00 UTC
t.monday?                # => trueRelated: #tuesday?, #wednesday?, #thursday?.
# File 'time.c', line 4878
static VALUE
time_monday(VALUE time)
{
    wday_p(1);
}
  
    #saturday?  ⇒ Boolean  (readonly)  
# File 'time.c', line 4968
static VALUE
time_saturday(VALUE time)
{
    wday_p(6);
}
  
    #sunday?  ⇒ Boolean  (readonly)  
Returns true if self represents a Sunday, false otherwise:
t = Time.utc(2000, 1, 2) # => 2000-01-02 00:00:00 UTC
t.sunday?                # => trueRelated: #monday?, #tuesday?, #wednesday?.
# File 'time.c', line 4860
static VALUE
time_sunday(VALUE time)
{
    wday_p(0);
}
  
    #thursday?  ⇒ Boolean  (readonly)  
Returns true if self represents a Thursday, false otherwise:
t = Time.utc(2000, 1, 6) # => 2000-01-06 00:00:00 UTC
t.thursday?              # => trueRelated: #friday?, #saturday?, #sunday?.
# File 'time.c', line 4932
static VALUE
time_thursday(VALUE time)
{
    wday_p(4);
}
  
    #tuesday?  ⇒ Boolean  (readonly)  
Returns true if self represents a Tuesday, false otherwise:
t = Time.utc(2000, 1, 4) # => 2000-01-04 00:00:00 UTC
t.tuesday?               # => trueRelated: #wednesday?, #thursday?, #friday?.
# File 'time.c', line 4896
static VALUE
time_tuesday(VALUE time)
{
    wday_p(2);
}
  
    
      #gmt?  ⇒ Boolean  (readonly)
      #utc?  ⇒ Boolean 
    
  
Boolean  (readonly)
      #utc?  ⇒ Boolean 
    Alias for #gmt?.
    #wednesday?  ⇒ Boolean  (readonly)  
Returns true if self represents a Wednesday, false otherwise:
t = Time.utc(2000, 1, 5) # => 2000-01-05 00:00:00 UTC
t.wednesday?             # => trueRelated: #thursday?, #friday?, #saturday?.
# File 'time.c', line 4914
static VALUE
time_wednesday(VALUE time)
{
    wday_p(3);
}
  Instance Method Details
    #+(numeric)  ⇒ Time   
# File 'time.c', line 4467
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);
}
  
    
      #-(numeric)  ⇒ Time 
      #-(other_time)  ⇒ Float 
    
  
Time 
      #-(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 -0600When 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.0Related: #+.
# File 'time.c', line 4501
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);
}
  
    #<=>(other_time)  ⇒ 1, ...   
Compares self with other_time; returns:
- 
-1, ifselfis less thanother_time.
- 
0, ifselfis equal toother_time.
- 
1, ifselfis greater thenother_time.
- 
nil, ifselfandother_timeare 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# File 'time.c', line 3961
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);
}
  #_dump(*args) (private)
# File 'time.c', line 5556
static VALUE
time_dump(int argc, VALUE *argv, VALUE time)
{
    VALUE str;
    rb_check_arity(argc, 0, 1);
    str = time_mdump(time);
    return str;
}
  #_load(str) (private)
# File 'time.c', line 5742
static VALUE
time_load(VALUE klass, VALUE str)
{
    VALUE time = time_s_alloc(klass);
    time_mload(time, str);
    return time;
}
  Alias for #ctime.
    #ceil(ndigits = 0)  ⇒ Time   
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# File 'time.c', line 4652
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 Also known as: #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"t.inspect                    # => "2000-12-31 23:59:59.5 +000001"
t.to_s                       # => "2000-12-31 23:59:59 +0000"# File 'time.c', line 4341
static VALUE
time_asctime(VALUE time)
{
    return strftimev("%a %b %e %T %Y", time, rb_usascii_encoding());
}
  #day ⇒ Integer Also known as: #mday
# File 'time.c', line 4762
static VALUE
time_mday(VALUE time)
{
    struct time_object *tobj;
    GetTimeval(time, tobj);
    MAKE_TM(time, tobj);
    return INT2FIX(tobj->vtm.mday);
}
  #deconstruct_keys(array_of_names_or_nil) ⇒ Hash
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# File 'time.c', line 5150
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;
}
  #eql?(other_time)
Returns true if self and other_time are both Time objects with the exact same time value.
# File 'time.c', line 3988
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)  ⇒ Time   
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# File 'time.c', line 4607
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);
}
  
    #getutc  ⇒ Time     Also known as: #getutc
  
# File 'time.c', line 4303
static VALUE
time_getgmtime(VALUE time)
{
    return time_gmtime(time_dup(time));
}
  
    #getlocal(zone = nil)  ⇒ Time   
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 +1200For forms of argument #zone, see Timezone Specifiers.
# File 'time.c', line 4256
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  ⇒ Time 
      #getutc  ⇒ Time 
    
  
Time 
      #getutc  ⇒ Time 
    Alias for #getgm.
Alias for #gmtoff.
    
      #utc  ⇒ self 
      #gmtime  ⇒ self 
    
  
self 
      #gmtime  ⇒ self 
    Alias for #utc.
#utc_offset ⇒ Integer Also known as: #gmt_offset, #utc_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.# File 'time.c', line 5064
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;
    }
}
  #hash ⇒ Integer
Returns the integer hash code for self.
Related: Object#hash.
# File 'time.c', line 4046
static VALUE
time_hash(VALUE time)
{
    struct time_object *tobj;
    GetTimeval(time, tobj);
    return rb_hash(w2v(tobj->timew));
}
  #hour ⇒ Integer
# File 'time.c', line 4738
static VALUE
time_hour(VALUE time)
{
    struct time_object *tobj;
    GetTimeval(time, tobj);
    MAKE_TM(time, tobj);
    return INT2FIX(tobj->vtm.hour);
}
  #initialize_copy(time)
# File 'time.c', line 4056
static VALUE
time_init_copy(VALUE copy, VALUE time)
{
    struct time_object *tobj, *tcopy;
    if (!OBJ_INIT_COPY(copy, time)) return copy;
    GetTimeval(time, tobj);
    GetNewTimeval(copy, tcopy);
    time_set_timew(copy, tcopy, tobj->timew);
    time_set_vtm(copy, tcopy, tobj->vtm);
    return copy;
}
  #inspect ⇒ String
# File 'time.c', line 4391
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;
}
  #iso8601(fraction_digits = 0) ⇒ String Also known as: #xmlschema
Returns a string which represents the time as a dateTime defined by XML Schema:
CCYY-MM-DDThh:mm:ssTZD
CCYY-MM-DDThh:mm:ss.sssTZDwhere 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"# File 'time.c', line 5300
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;
}
  
    
      #localtime  ⇒ self, Time 
      #localtime(zone)  ⇒ Time 
    
  
self, Time 
      #localtime(zone)  ⇒ Time 
    With no argument given:
- 
Returns selfifselfis a local time.
- 
Otherwise returns a new Timein 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 -0900For forms of argument #zone, see Timezone Specifiers.
# File 'time.c', line 4155
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);
}
  Alias for #day.
#min ⇒ Integer
# File 'time.c', line 4714
static VALUE
time_min(VALUE time)
{
    struct time_object *tobj;
    GetTimeval(time, tobj);
    MAKE_TM(time, tobj);
    return INT2FIX(tobj->vtm.min);
}
  #mon ⇒ Integer Also known as: #month
# File 'time.c', line 4786
static VALUE
time_mon(VALUE time)
{
    struct time_object *tobj;
    GetTimeval(time, tobj);
    MAKE_TM(time, tobj);
    return INT2FIX(tobj->vtm.mon);
}
  Alias for #mon.
#nsec ⇒ Integer Also known as: #tv_nsec
# File 'time.c', line 3898
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)));
}
  
    #round(ndigits = 0)  ⇒ Time   
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# File 'time.c', line 4559
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);
}
  #sec ⇒ Integer
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 # => 5Note: the second value may be 60 when there is a leap second.
# File 'time.c', line 4690
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
Returns a string representation of self, formatted according to the given string format. See Formats for Dates and Times.
# File 'time.c', line 5247
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
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# File 'time.c', line 3924
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));
}
  #to_a ⇒ Array
# File 'time.c', line 5095
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
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# File 'time.c', line 3822
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 Also known as: #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# File 'time.c', line 3793
static VALUE
time_to_i(VALUE time)
{
    struct time_object *tobj;
    GetTimeval(time, tobj);
    return w2v(wdiv(tobj->timew, WINT2FIXWV(TIME_SCALE)));
}
  #to_r ⇒ Rational
Returns the value of self as a ::Rational exact number of Epoch seconds;
Time.now.to_r # => (16571402750320203/10000000)# File 'time.c', line 3843
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
# File 'time.c', line 4363
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());
}
  Alias for #nsec.
Alias for #to_i.
Alias for #usec.
#usec ⇒ Integer Also known as: #tv_usec
# File 'time.c', line 3871
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));
}
  
    #utc  ⇒ self  (readonly)    Also known as: #gmtime
  
# File 'time.c', line 4181
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;
}
  Alias for #gmtoff.
#wday ⇒ Integer
# File 'time.c', line 4834
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);
}
  Alias for #iso8601.
#yday ⇒ Integer
# File 'time.c', line 4984
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
# File 'time.c', line 4809
static VALUE
time_year(VALUE time)
{
    struct time_object *tobj;
    GetTimeval(time, tobj);
    MAKE_TM(time, tobj);
    return tobj->vtm.year;
}
  
    #zone  ⇒ String, Time   
# File 'time.c', line 5032
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;
}