[ruby/irb] Change debug test workaround only enabled when output is
[ruby.git] / timev.rb
blob22f46b9729adbf7fb09bbabe47ed4bbb60663e07
1 # A +Time+ object represents a date and time:
3 #   Time.new(2000, 1, 1, 0, 0, 0) # => 2000-01-01 00:00:00 -0600
5 # Although its value can be expressed as a single numeric
6 # (see {Epoch Seconds}[rdoc-ref:Time@Epoch+Seconds] below),
7 # it can be convenient to deal with the value by parts:
9 #   t = Time.new(-2000, 1, 1, 0, 0, 0.0)
10 #   # => -2000-01-01 00:00:00 -0600
11 #   t.year # => -2000
12 #   t.month # => 1
13 #   t.mday # => 1
14 #   t.hour # => 0
15 #   t.min # => 0
16 #   t.sec # => 0
17 #   t.subsec # => 0
19 #   t = Time.new(2000, 12, 31, 23, 59, 59.5)
20 #   # => 2000-12-31 23:59:59.5 -0600
21 #   t.year # => 2000
22 #   t.month # => 12
23 #   t.mday # => 31
24 #   t.hour # => 23
25 #   t.min # => 59
26 #   t.sec # => 59
27 #   t.subsec # => (1/2)
29 # == Epoch Seconds
31 # <i>Epoch seconds</i> is the exact number of seconds
32 # (including fractional subseconds) since the Unix Epoch, January 1, 1970.
34 # You can retrieve that value exactly using method Time.to_r:
36 #   Time.at(0).to_r        # => (0/1)
37 #   Time.at(0.999999).to_r # => (9007190247541737/9007199254740992)
39 # Other retrieval methods such as Time#to_i and Time#to_f
40 # may return a value that rounds or truncates subseconds.
42 # == \Time Resolution
44 # A +Time+ object derived from the system clock
45 # (for example, by method Time.now)
46 # has the resolution supported by the system.
48 # == Examples
50 # All of these examples were done using the EST timezone which is GMT-5.
52 # === Creating a New +Time+ Instance
54 # You can create a new instance of Time with Time.new. This will use the
55 # current system time. Time.now is an alias for this. You can also
56 # pass parts of the time to Time.new such as year, month, minute, etc. When
57 # you want to construct a time this way you must pass at least a year. If you
58 # pass the year with nothing else time will default to January 1 of that year
59 # at 00:00:00 with the current system timezone. Here are some examples:
61 #   Time.new(2002)         #=> 2002-01-01 00:00:00 -0500
62 #   Time.new(2002, 10)     #=> 2002-10-01 00:00:00 -0500
63 #   Time.new(2002, 10, 31) #=> 2002-10-31 00:00:00 -0500
65 # You can pass a UTC offset:
67 #   Time.new(2002, 10, 31, 2, 2, 2, "+02:00") #=> 2002-10-31 02:02:02 +0200
69 # Or {a timezone object}[rdoc-ref:Time@Timezone+Objects]:
71 #   zone = timezone("Europe/Athens")      # Eastern European Time, UTC+2
72 #   Time.new(2002, 10, 31, 2, 2, 2, zone) #=> 2002-10-31 02:02:02 +0200
74 # You can also use Time.local and Time.utc to infer
75 # local and UTC timezones instead of using the current system
76 # setting.
78 # You can also create a new time using Time.at which takes the number of
79 # seconds (with subsecond) since the {Unix
80 # Epoch}[https://en.wikipedia.org/wiki/Unix_time].
82 #   Time.at(628232400) #=> 1989-11-28 00:00:00 -0500
84 # === Working with an Instance of +Time+
86 # Once you have an instance of Time there is a multitude of things you can
87 # do with it. Below are some examples. For all of the following examples, we
88 # will work on the assumption that you have done the following:
90 #   t = Time.new(1993, 02, 24, 12, 0, 0, "+09:00")
92 # Was that a monday?
94 #   t.monday? #=> false
96 # What year was that again?
98 #   t.year #=> 1993
100 # Was it daylight savings at the time?
102 #   t.dst? #=> false
104 # What's the day a year later?
106 #   t + (60*60*24*365) #=> 1994-02-24 12:00:00 +0900
108 # How many seconds was that since the Unix Epoch?
110 #   t.to_i #=> 730522800
112 # You can also do standard functions like compare two times.
114 #   t1 = Time.new(2010)
115 #   t2 = Time.new(2011)
117 #   t1 == t2 #=> false
118 #   t1 == t1 #=> true
119 #   t1 <  t2 #=> true
120 #   t1 >  t2 #=> false
122 #   Time.new(2010,10,31).between?(t1, t2) #=> true
124 # == What's Here
126 # First, what's elsewhere. \Class +Time+:
128 # - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
129 # - Includes {module Comparable}[rdoc-ref:Comparable@What-27s+Here].
131 # Here, class +Time+ provides methods that are useful for:
133 # - {Creating +Time+ objects}[rdoc-ref:Time@Methods+for+Creating].
134 # - {Fetching +Time+ values}[rdoc-ref:Time@Methods+for+Fetching].
135 # - {Querying a +Time+ object}[rdoc-ref:Time@Methods+for+Querying].
136 # - {Comparing +Time+ objects}[rdoc-ref:Time@Methods+for+Comparing].
137 # - {Converting a +Time+ object}[rdoc-ref:Time@Methods+for+Converting].
138 # - {Rounding a +Time+}[rdoc-ref:Time@Methods+for+Rounding].
140 # === Methods for Creating
142 # - ::new: Returns a new time from specified arguments (year, month, etc.),
143 #   including an optional timezone value.
144 # - ::local (aliased as ::mktime): Same as ::new, except the
145 #   timezone is the local timezone.
146 # - ::utc (aliased as ::gm): Same as ::new, except the timezone is UTC.
147 # - ::at: Returns a new time based on seconds since epoch.
148 # - ::now: Returns a new time based on the current system time.
149 # - #+ (plus): Returns a new time increased by the given number of seconds.
150 # - #- (minus): Returns a new time decreased by the given number of seconds.
152 # === Methods for Fetching
154 # - #year: Returns the year of the time.
155 # - #month (aliased as #mon): Returns the month of the time.
156 # - #mday (aliased as #day): Returns the day of the month.
157 # - #hour: Returns the hours value for the time.
158 # - #min: Returns the minutes value for the time.
159 # - #sec: Returns the seconds value for the time.
160 # - #usec (aliased as #tv_usec): Returns the number of microseconds
161 #   in the subseconds value of the time.
162 # - #nsec (aliased as #tv_nsec: Returns the number of nanoseconds
163 #   in the subsecond part of the time.
164 # - #subsec: Returns the subseconds value for the time.
165 # - #wday: Returns the integer weekday value of the time (0 == Sunday).
166 # - #yday: Returns the integer yearday value of the time (1 == January 1).
167 # - #hash: Returns the integer hash value for the time.
168 # - #utc_offset (aliased as #gmt_offset and #gmtoff): Returns the offset
169 #   in seconds between time and UTC.
170 # - #to_f: Returns the float number of seconds since epoch for the time.
171 # - #to_i (aliased as #tv_sec): Returns the integer number of seconds since epoch
172 #   for the time.
173 # - #to_r: Returns the Rational number of seconds since epoch for the time.
174 # - #zone: Returns a string representation of the timezone of the time.
176 # === Methods for Querying
178 # - #utc? (aliased as #gmt?): Returns whether the time is UTC.
179 # - #dst? (aliased as #isdst): Returns whether the time is DST (daylight saving time).
180 # - #sunday?: Returns whether the time is a Sunday.
181 # - #monday?: Returns whether the time is a Monday.
182 # - #tuesday?: Returns whether the time is a Tuesday.
183 # - #wednesday?: Returns whether the time is a Wednesday.
184 # - #thursday?: Returns whether the time is a Thursday.
185 # - #friday?: Returns whether time is a Friday.
186 # - #saturday?: Returns whether the time is a Saturday.
188 # === Methods for Comparing
190 # - #<=>: Compares +self+ to another time.
191 # - #eql?: Returns whether the time is equal to another time.
193 # === Methods for Converting
195 # - #asctime (aliased as #ctime): Returns the time as a string.
196 # - #inspect: Returns the time in detail as a string.
197 # - #strftime: Returns the time as a string, according to a given format.
198 # - #to_a: Returns a 10-element array of values from the time.
199 # - #to_s: Returns a string representation of the time.
200 # - #getutc (aliased as #getgm): Returns a new time converted to UTC.
201 # - #getlocal: Returns a new time converted to local time.
202 # - #utc (aliased as #gmtime): Converts time to UTC in place.
203 # - #localtime: Converts time to local time in place.
204 # - #deconstruct_keys: Returns a hash of time components used in pattern-matching.
206 # === Methods for Rounding
208 # - #round:Returns a new time with subseconds rounded.
209 # - #ceil: Returns a new time with subseconds raised to a ceiling.
210 # - #floor: Returns a new time with subseconds lowered to a floor.
212 # For the forms of argument +zone+, see
213 # {Timezone Specifiers}[rdoc-ref:Time@Timezone+Specifiers].
215 # :include: doc/_timezones.rdoc
216 class Time
217   # Creates a new +Time+ object from the current system time.
218   # This is the same as Time.new without arguments.
219   #
220   #    Time.now               # => 2009-06-24 12:39:54 +0900
221   #    Time.now(in: '+04:00') # => 2009-06-24 07:39:54 +0400
222   #
223   # For forms of argument +zone+, see
224   # {Timezone Specifiers}[rdoc-ref:Time@Timezone+Specifiers].
225   def self.now(in: nil)
226     Primitive.time_s_now(Primitive.arg!(:in))
227   end
229   # Returns a new +Time+ object based on the given arguments.
230   #
231   # Required argument +time+ may be either of:
232   #
233   # - A +Time+ object, whose value is the basis for the returned time;
234   #   also influenced by optional keyword argument +in:+ (see below).
235   # - A numeric number of
236   #   {Epoch seconds}[rdoc-ref:Time@Epoch+Seconds]
237   #   for the returned time.
238   #
239   # Examples:
240   #
241   #   t = Time.new(2000, 12, 31, 23, 59, 59) # => 2000-12-31 23:59:59 -0600
242   #   secs = t.to_i                          # => 978328799
243   #   Time.at(secs)                          # => 2000-12-31 23:59:59 -0600
244   #   Time.at(secs + 0.5)                    # => 2000-12-31 23:59:59.5 -0600
245   #   Time.at(1000000000)                    # => 2001-09-08 20:46:40 -0500
246   #   Time.at(0)                             # => 1969-12-31 18:00:00 -0600
247   #   Time.at(-1000000000)                   # => 1938-04-24 17:13:20 -0500
248   #
249   # Optional numeric argument +subsec+ and optional symbol argument +units+
250   # work together to specify subseconds for the returned time;
251   # argument +units+ specifies the units for +subsec+:
252   #
253   # - +:millisecond+: +subsec+ in milliseconds:
254   #
255   #     Time.at(secs, 0, :millisecond)     # => 2000-12-31 23:59:59 -0600
256   #     Time.at(secs, 500, :millisecond)   # => 2000-12-31 23:59:59.5 -0600
257   #     Time.at(secs, 1000, :millisecond)  # => 2001-01-01 00:00:00 -0600
258   #     Time.at(secs, -1000, :millisecond) # => 2000-12-31 23:59:58 -0600
259   #
260   # - +:microsecond+ or +:usec+: +subsec+ in microseconds:
261   #
262   #     Time.at(secs, 0, :microsecond)        # => 2000-12-31 23:59:59 -0600
263   #     Time.at(secs, 500000, :microsecond)   # => 2000-12-31 23:59:59.5 -0600
264   #     Time.at(secs, 1000000, :microsecond)  # => 2001-01-01 00:00:00 -0600
265   #     Time.at(secs, -1000000, :microsecond) # => 2000-12-31 23:59:58 -0600
266   #
267   # - +:nanosecond+ or +:nsec+: +subsec+ in nanoseconds:
268   #
269   #     Time.at(secs, 0, :nanosecond)           # => 2000-12-31 23:59:59 -0600
270   #     Time.at(secs, 500000000, :nanosecond)   # => 2000-12-31 23:59:59.5 -0600
271   #     Time.at(secs, 1000000000, :nanosecond)  # => 2001-01-01 00:00:00 -0600
272   #     Time.at(secs, -1000000000, :nanosecond) # => 2000-12-31 23:59:58 -0600
273   #
274   #
275   # Optional keyword argument <tt>in: zone</tt> specifies the timezone
276   # for the returned time:
277   #
278   #   Time.at(secs, in: '+12:00') # => 2001-01-01 17:59:59 +1200
279   #   Time.at(secs, in: '-12:00') # => 2000-12-31 17:59:59 -1200
280   #
281   # For the forms of argument +zone+, see
282   # {Timezone Specifiers}[rdoc-ref:Time@Timezone+Specifiers].
283   #
284   def self.at(time, subsec = false, unit = :microsecond, in: nil)
285     if Primitive.mandatory_only?
286       Primitive.time_s_at1(time)
287     else
288       Primitive.time_s_at(time, subsec, unit, Primitive.arg!(:in))
289     end
290   end
292   # call-seq:
293   #   Time.new(year = nil, mon = nil, mday = nil, hour = nil, min = nil, sec = nil, zone = nil, in: nil, precision: 9)
294   #
295   # Returns a new +Time+ object based on the given arguments,
296   # by default in the local timezone.
297   #
298   # With no positional arguments, returns the value of Time.now:
299   #
300   #   Time.new # => 2021-04-24 17:27:46.0512465 -0500
301   #
302   # With one string argument that represents a time, returns a new
303   # +Time+ object based on the given argument, in the local timezone.
304   #
305   #   Time.new('2000-12-31 23:59:59.5')              # => 2000-12-31 23:59:59.5 -0600
306   #   Time.new('2000-12-31 23:59:59.5 +0900')        # => 2000-12-31 23:59:59.5 +0900
307   #   Time.new('2000-12-31 23:59:59.5', in: '+0900') # => 2000-12-31 23:59:59.5 +0900
308   #   Time.new('2000-12-31 23:59:59.5')              # => 2000-12-31 23:59:59.5 -0600
309   #   Time.new('2000-12-31 23:59:59.56789', precision: 3) # => 2000-12-31 23:59:59.567 -0600
310   #
311   # With one to six arguments, returns a new +Time+ object
312   # based on the given arguments, in the local timezone.
313   #
314   #   Time.new(2000, 1, 2, 3, 4, 5) # => 2000-01-02 03:04:05 -0600
315   #
316   # For the positional arguments (other than +zone+):
317   #
318   # - +year+: Year, with no range limits:
319   #
320   #     Time.new(999999999)  # => 999999999-01-01 00:00:00 -0600
321   #     Time.new(-999999999) # => -999999999-01-01 00:00:00 -0600
322   #
323   # - +month+: Month in range (1..12), or case-insensitive
324   #   3-letter month name:
325   #
326   #     Time.new(2000, 1)     # => 2000-01-01 00:00:00 -0600
327   #     Time.new(2000, 12)    # => 2000-12-01 00:00:00 -0600
328   #     Time.new(2000, 'jan') # => 2000-01-01 00:00:00 -0600
329   #     Time.new(2000, 'JAN') # => 2000-01-01 00:00:00 -0600
330   #
331   # - +mday+: Month day in range(1..31):
332   #
333   #     Time.new(2000, 1, 1)  # => 2000-01-01 00:00:00 -0600
334   #     Time.new(2000, 1, 31) # => 2000-01-31 00:00:00 -0600
335   #
336   # - +hour+: Hour in range (0..23), or 24 if +min+, +sec+, and +usec+
337   #   are zero:
338   #
339   #     Time.new(2000, 1, 1, 0)  # => 2000-01-01 00:00:00 -0600
340   #     Time.new(2000, 1, 1, 23) # => 2000-01-01 23:00:00 -0600
341   #     Time.new(2000, 1, 1, 24) # => 2000-01-02 00:00:00 -0600
342   #
343   # - +min+: Minute in range (0..59):
344   #
345   #     Time.new(2000, 1, 1, 0, 0)  # => 2000-01-01 00:00:00 -0600
346   #     Time.new(2000, 1, 1, 0, 59) # => 2000-01-01 00:59:00 -0600
347   #
348   # - +sec+: Second in range (0...61):
349   #
350   #     Time.new(2000, 1, 1, 0, 0, 0)  # => 2000-01-01 00:00:00 -0600
351   #     Time.new(2000, 1, 1, 0, 0, 59) # => 2000-01-01 00:00:59 -0600
352   #     Time.new(2000, 1, 1, 0, 0, 60) # => 2000-01-01 00:01:00 -0600
353   #
354   #   +sec+ may be Float or Rational.
355   #
356   #     Time.new(2000, 1, 1, 0, 0, 59.5)  # => 2000-12-31 23:59:59.5 +0900
357   #     Time.new(2000, 1, 1, 0, 0, 59.7r) # => 2000-12-31 23:59:59.7 +0900
358   #
359   # These values may be:
360   #
361   # - Integers, as above.
362   # - Numerics convertible to integers:
363   #
364   #     Time.new(Float(0.0), Rational(1, 1), 1.0, 0.0, 0.0, 0.0)
365   #     # => 0000-01-01 00:00:00 -0600
366   #
367   # - String integers:
368   #
369   #     a = %w[0 1 1 0 0 0]
370   #     # => ["0", "1", "1", "0", "0", "0"]
371   #     Time.new(*a) # => 0000-01-01 00:00:00 -0600
372   #
373   # When positional argument +zone+ or keyword argument +in:+ is given,
374   # the new +Time+ object is in the specified timezone.
375   # For the forms of argument +zone+, see
376   # {Timezone Specifiers}[rdoc-ref:Time@Timezone+Specifiers]:
377   #
378   #   Time.new(2000, 1, 1, 0, 0, 0, '+12:00')
379   #   # => 2000-01-01 00:00:00 +1200
380   #   Time.new(2000, 1, 1, 0, 0, 0, in: '-12:00')
381   #   # => 2000-01-01 00:00:00 -1200
382   #   Time.new(in: '-12:00')
383   #   # => 2022-08-23 08:49:26.1941467 -1200
384   #
385   # Since +in:+ keyword argument just provides the default, so if the
386   # first argument in single string form contains time zone information,
387   # this keyword argument will be silently ignored.
388   #
389   #   Time.new('2000-01-01 00:00:00 +0100', in: '-0500').utc_offset  # => 3600
390   #
391   # - +precision+: maximum effective digits in sub-second part, default is 9.
392   #   More digits will be truncated, as other operations of +Time+.
393   #   Ignored unless the first argument is a string.
394   #
395   def initialize(year = (now = true), mon = (str = year; nil), mday = nil, hour = nil, min = nil, sec = nil, zone = nil,
396                  in: nil, precision: 9)
397     if zone
398       if Primitive.arg!(:in)
399         raise ArgumentError, "timezone argument given as positional and keyword arguments"
400       end
401     else
402       zone = Primitive.arg!(:in)
403     end
405     if now
406       return Primitive.time_init_now(zone)
407     end
409     if str and Primitive.time_init_parse(str, zone, precision)
410       return self
411     end
413     Primitive.time_init_args(year, mon, mday, hour, min, sec, zone)
414   end