# <!-- rdoc-file=timev.rb -->
# 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](rdoc-ref:Time@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](rdoc-ref:Time@Timezone+Objects):
#
#     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](https://en.wikipedia.org/wiki/Unix_time).
#
#     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](rdoc-ref:Object@What-27s+Here).
# *   Includes [module Comparable](rdoc-ref:Comparable@What-27s+Here).
#
# Here, class `Time` provides methods that are useful for:
#
# *   [Creating Time objects](rdoc-ref:Time@Methods+for+Creating).
# *   [Fetching Time values](rdoc-ref:Time@Methods+for+Fetching).
# *   [Querying a Time object](rdoc-ref:Time@Methods+for+Querying).
# *   [Comparing Time objects](rdoc-ref:Time@Methods+for+Comparing).
# *   [Converting a Time object](rdoc-ref:Time@Methods+for+Converting).
# *   [Rounding a Time](rdoc-ref:Time@Methods+for+Rounding).
#
# ### 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](rdoc-ref:Time@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](rdoc-ref:Time@Hours-2FMinutes+Offsets).
# *   [Single-letter offset](rdoc-ref:Time@Single-Letter+Offsets).
# *   [Integer offset](rdoc-ref:Time@Integer+Offsets).
# *   [Timezone object](rdoc-ref:Time@Timezone+Objects).
# *   [Timezone name](rdoc-ref:Time@Timezone+Names).
#
# ### 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](https://en.wikipedia.org/wiki/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](https://github.com/panthomakos/timezone) and
# [TZInfo](https://tzinfo.github.io) 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](rdoc-ref:Time@Time-Like+Objects).
#
#     Returns
# :       a [Time-like object](rdoc-ref:Time@Time-Like+Objects) 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](rdoc-ref:Time@Time-Like+Objects).
#
#     Returns
# :       a [Time-like object](rdoc-ref:Time@Time-Like+Objects) 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](rdoc-ref:Time@Time-Like+Objects).
#
#     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](rdoc-ref:Time@Time-Like+Objects).
#
#     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](https://github.com/panthomakos/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](https://tzinfo.github.io):
#     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.
#
class Time < Object
  # A type that's used for timeouts.
  #
  # All numeric types implement this, but custom classes can also implement it if desired.
  #
  # Usage of `Time::_Timeout` is fairly common throughout the stdlib, such as in `Kernel#sleep`,
  # `IO#timeout=`, and `TCPSocket#new`'s `connet_timeout` field.
  interface _Timeout
    # Returns `[seconds, nanoseconds]`.
    #
    # The `seconds` should be a whole number of seconds, whereas the `nanoseconds` should be smaller
    # than one. For example, `3.125.divmod(1)` would yield `[3, 0.125]`
    def divmod: (1) -> [int, _TimeoutNSecs]
  end

  # The nanoseconds part of `Time::_Timeout`'s return value. See it for details
  interface _TimeoutNSecs
    # Convert `self` into a whole number of seconds.
    def *: (1_000_000_000) -> int
  end

  include Comparable

  # <!--
  #   rdoc-file=timev.rb
  #   - 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 `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](rdoc-ref:Time@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](rdoc-ref:Time@Timezone+Specifiers).
  #
  def self.at: (Time, ?in: String | Integer | nil) -> Time
             | (Numeric, ?in: String | Integer | nil) -> Time
             | (Integer sec_i, Numeric msec, subsec_unit msec, ?in: String | Integer | nil) -> Time

  type subsec_unit = :msec | :millisecond | :usec | :microsecond | :nsec | :nanosecond

  # <!-- rdoc-file=time.c -->
  # 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.
  #
  def self.gm: (Integer year, ?Integer | String month, ?Integer day, ?Integer hour, ?Integer min, ?Numeric sec, ?Numeric usec_with_frac) -> Time

  # <!--
  #   rdoc-file=time.c
  #   - Time.local(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0) -> new_time
  #   - Time.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
  #
  def self.local: (Integer year, ?Integer | String month, ?Integer day, ?Integer hour, ?Integer min, ?Numeric sec, ?Numeric usec_with_frac) -> Time

  # <!--
  #   rdoc-file=timev.rb
  #   - now(in: nil)
  # -->
  # 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](rdoc-ref:Time@Timezone+Specifiers).
  #
  def self.now: (?in: String | Integer | nil) -> Time

  # <!--
  #   rdoc-file=time.c
  #   - Time.utc(year, month = 1, mday = 1, hour = 0, min = 0, sec = 0, usec = 0) -> new_time
  #   - Time.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.
  #
  def self.utc: (Integer year, ?Integer | String month, ?Integer day, ?Integer hour, ?Integer min, ?Numeric sec, ?Numeric usec_with_frac) -> Time

  # <!--
  #   rdoc-file=time.c
  #   - self + numeric -> new_time
  # -->
  # 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#-.
  #
  def +: (Numeric arg0) -> Time

  # <!--
  #   rdoc-file=time.c
  #   - self - numeric -> new_time
  #   - 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#+.
  #
  def -: (Time arg0) -> Float
       | (Numeric arg0) -> Time

  def <: (Time arg0) -> bool

  def <=: (Time arg0) -> bool

  # <!--
  #   rdoc-file=time.c
  #   - self <=> other_time -> -1, 0, +1, or nil
  # -->
  # 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
  #
  def <=>: (Time other) -> Integer
         | (untyped other) -> Integer?

  def >: (Time arg0) -> bool

  def >=: (Time arg0) -> bool

  # <!-- rdoc-file=time.c -->
  # 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](rdoc-ref:strftime_formatting.rdoc):
  #
  #     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"
  #
  def asctime: () -> String

  # <!--
  #   rdoc-file=time.c
  #   - ctime -> string
  # -->
  # 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](rdoc-ref:strftime_formatting.rdoc):
  #
  #     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"
  #
  def ctime: () -> String

  # <!-- rdoc-file=time.c -->
  # 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.
  #
  def day: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - 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
  #
  def deconstruct_keys: (Array[Symbol]?) -> Hash[Symbol, Integer]

  # <!-- rdoc-file=time.c -->
  # 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
  #
  def dst?: () -> bool

  # <!--
  #   rdoc-file=time.c
  #   - eql?(other_time)
  # -->
  # Returns `true` if `self` and `other_time` are both `Time` objects with the
  # exact same time value.
  #
  def eql?: (untyped arg0) -> bool

  # <!--
  #   rdoc-file=time.c
  #   - friday? -> true or false
  # -->
  # 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?.
  #
  def friday?: () -> bool

  # <!--
  #   rdoc-file=time.c
  #   - 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
  #
  def getgm: () -> Time

  # <!--
  #   rdoc-file=time.c
  #   - getlocal(zone = nil) -> new_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 +1200
  #
  # For forms of argument `zone`, see [Timezone
  # Specifiers](rdoc-ref:Time@Timezone+Specifiers).
  #
  def getlocal: (?Integer utc_offset) -> Time

  # <!-- rdoc-file=time.c -->
  # 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
  #
  def getutc: () -> Time

  # <!-- rdoc-file=time.c -->
  # 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.
  #
  def gmt?: () -> bool

  # <!-- rdoc-file=time.c -->
  # 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.
  #
  def gmt_offset: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - 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).
  #
  def gmtime: () -> Time

  # <!--
  #   rdoc-file=time.c
  #   - hash -> integer
  # -->
  # Returns the integer hash code for `self`.
  #
  # Related: Object#hash.
  #
  def hash: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - hour -> integer
  # -->
  # 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.
  #
  def hour: () -> Integer

  # <!--
  #   rdoc-file=timev.rb
  #   - Time.new(year = nil, mon = nil, mday = nil, hour = nil, min = nil, sec = nil, zone = nil, in: nil, precision: 9)
  # -->
  # 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](rdoc-ref:Time@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.
  #
  def initialize: (?Integer year, ?Integer? month, ?Integer? day, ?Integer? hour, ?Integer? min, ?Numeric? sec, ?String | Integer | nil) -> void
                | (?Integer year, ?Integer? month, ?Integer? day, ?Integer? hour, ?Integer? min, ?Numeric? sec, in: String | Integer | nil) -> void
                | (String, ?in: string | int | nil, ?precision: int) -> void

  # <!--
  #   rdoc-file=time.c
  #   - inspect -> string
  # -->
  # 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"
  #
  def inspect: () -> String

  # <!--
  #   rdoc-file=time.c
  #   - 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
  #
  def isdst: () -> bool

  # <!-- rdoc-file=lib/time.rb -->
  # Parses `time` as a dateTime defined by the XML Schema and converts it to a
  # Time object.  The format is a restricted version of the format defined by ISO
  # 8601.
  #
  # ArgumentError is raised if `time` is not compliant with the format or if the
  # Time class cannot represent the specified time.
  #
  # See #xmlschema for more information on this format.
  #
  #     require 'time'
  #
  #     Time.xmlschema("2011-10-05T22:26:12-04:00")
  #     #=> 2011-10-05 22:26:12-04:00
  #
  # You must require 'time' to use this method.
  #
  alias iso8601 xmlschema

  # <!--
  #   rdoc-file=time.c
  #   - localtime -> self or new_time
  #   - 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](rdoc-ref:Time@Timezone+Specifiers).
  #
  def localtime: (?String utc_offset) -> Time

  # <!--
  #   rdoc-file=time.c
  #   - mday -> integer
  # -->
  # 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.
  #
  def mday: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - min -> integer
  # -->
  # 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.
  #
  def min: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - mon -> integer
  # -->
  # 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.
  #
  def mon: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - monday? -> true or false
  # -->
  # 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?.
  #
  def monday?: () -> bool

  # <!-- rdoc-file=time.c -->
  # 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).
  #
  def nsec: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - round(ndigits = 0) -> new_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
  #
  # Related: Time#ceil, Time#floor.
  #
  def round: (?int ndigits) -> Time

  # <!--
  #   rdoc-file=time.c
  #   - saturday? -> true or false
  # -->
  # 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?.
  #
  def saturday?: () -> bool

  # <!--
  #   rdoc-file=time.c
  #   - 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 # => 5
  #
  # Note: the second value may be 60 when there is a [leap
  # second](https://en.wikipedia.org/wiki/Leap_second).
  #
  # Related: Time#year, Time#mon, Time#min.
  #
  def sec: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - strftime(format_string) -> string
  # -->
  # Returns a string representation of `self`, formatted according to the given
  # string `format`. See [Formats for Dates and
  # Times](rdoc-ref:strftime_formatting.rdoc).
  #
  def strftime: (String arg0) -> String

  # <!--
  #   rdoc-file=time.c
  #   - 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
  #
  def subsec: () -> (0 | Rational)

  # <!--
  #   rdoc-file=time.c
  #   - sunday? -> true or false
  # -->
  # 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?.
  #
  def sunday?: () -> bool

  # <!--
  #   rdoc-file=time.c
  #   - thursday? -> true or false
  # -->
  # 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?.
  #
  def thursday?: () -> bool

  # <!--
  #   rdoc-file=time.c
  #   - to_a -> array
  # -->
  # 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.
  #
  def to_a: () -> [ Integer, Integer, Integer, Integer, Integer, Integer, Integer, Integer, bool, String? ]

  # <!--
  #   rdoc-file=time.c
  #   - to_f -> float
  # -->
  # Returns the value of `self` as a Float number [Epoch
  # seconds](rdoc-ref:Time@Epoch+Seconds); subseconds are included.
  #
  # The stored value of `self` is a [Rational](rdoc-ref:Rational@#method-i-to_f),
  # 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.
  #
  def to_f: () -> Float

  # <!--
  #   rdoc-file=time.c
  #   - to_i -> integer
  # -->
  # Returns the value of `self` as integer [Epoch
  # seconds](rdoc-ref:Time@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.
  #
  def to_i: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - to_r -> rational
  # -->
  # Returns the value of `self` as a Rational exact number of [Epoch
  # seconds](rdoc-ref:Time@Epoch+Seconds);
  #
  #     Time.now.to_r # => (16571402750320203/10000000)
  #
  # Related: Time#to_f, Time#to_i.
  #
  def to_r: () -> Rational

  # <!--
  #   rdoc-file=time.c
  #   - to_s    -> string
  # -->
  # 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"
  #
  def to_s: () -> String

  # <!--
  #   rdoc-file=time.c
  #   - tuesday? -> true or false
  # -->
  # 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?.
  #
  def tuesday?: () -> bool

  # <!--
  #   rdoc-file=time.c
  #   - 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).
  #
  def tv_nsec: () -> Integer

  # <!-- rdoc-file=time.c -->
  # Returns the value of `self` as integer [Epoch
  # seconds](rdoc-ref:Time@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.
  #
  def tv_sec: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - 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).
  #
  def tv_usec: () -> Integer

  # <!-- rdoc-file=time.c -->
  # 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).
  #
  def usec: () -> Integer

  # <!-- rdoc-file=time.c -->
  # 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).
  #
  def utc: () -> Time

  # <!--
  #   rdoc-file=time.c
  #   - utc? -> true or false
  # -->
  # 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.
  #
  def utc?: () -> bool

  # <!-- rdoc-file=time.c -->
  # 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.
  #
  def utc_offset: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - wday -> integer
  # -->
  # 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.
  #
  def wday: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - wednesday? -> true or false
  # -->
  # 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?.
  #
  def wednesday?: () -> bool

  # <!--
  #   rdoc-file=lib/time.rb
  #   - xmlschema(fraction_digits=0)
  # -->
  # 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.
  #
  #     require 'time'
  #
  #     t = Time.now
  #     t.iso8601  # => "2011-10-05T22:26:12-04:00"
  #
  # You must require 'time' to use this method.
  #
  def xmlschema: () -> String

  # <!--
  #   rdoc-file=time.c
  #   - yday -> integer
  # -->
  # 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
  #
  def yday: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - year -> integer
  # -->
  # 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.
  #
  def year: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - time.zone -> string or timezone
  # -->
  # 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"
  #
  def zone: () -> String?

  # <!-- rdoc-file=time.c -->
  # 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
  #
  def self.mktime: (Integer year, ?Integer | String month, ?Integer day, ?Integer hour, ?Integer min, ?Numeric sec, ?Numeric usec_with_frac) -> Time

  # <!--
  #   rdoc-file=time.c
  #   - 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.
  #
  def gmtoff: () -> Integer

  # <!-- rdoc-file=time.c -->
  # 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.
  #
  def month: () -> Integer

  # <!--
  #   rdoc-file=time.c
  #   - floor(ndigits = 0) -> new_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
  #
  # Related: Time#ceil, Time#round.
  #
  def floor: (?int ndigits) -> Time

  # <!--
  #   rdoc-file=time.c
  #   - ceil(ndigits = 0)   -> new_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
  #
  # Related: Time#floor, Time#round.
  #
  def ceil: (?int ndigits) -> Time
end

Time::RFC2822_DAY_NAME: Array[String]

Time::RFC2822_MONTH_NAME: Array[String]
