diff options
author | Tanaka Akira <[email protected]> | 2020-07-21 20:28:36 +0900 |
---|---|---|
committer | Tanaka Akira <[email protected]> | 2020-07-21 20:28:36 +0900 |
commit | 48eb1ad2c3aa1a14bd8ef61cbd72a791b0b67418 (patch) | |
tree | 3f3e8785ad735b2b38aa5e5bf2cede309967354b /time.c | |
parent | 73ee1295a33c51f24e774b273fdeca5910ce5ba8 (diff) |
[DOC] time.c document updated.
* fraction -> subsecond
for consistency with method name
* The sentence,
"A non-portable feature allows the offset to be negative on some systems.",
is removed.
Time before 1970 should work portably now.
If localtime() doesn't work before 1970,
Ruby should extrapolate it.
* Time::new -> Time.new
"::" for method call is not common notation now.
* Time#to_i truncates subsecond
* Time#to_f approximates a value in Time object
* Time#to_r
The sentence,
"You can use this method to convert _time_ to another Epoch.",
is removed.
It is not clear because no actual example of "another Epoch" is given.
* Time#usec truncates fraction of microseconds.
* Time#nsec truncates fraction of nanoseconds.
* describe Time#inspect shows subsecond since Ruby 2.7.0.
Diffstat (limited to 'time.c')
-rw-r--r-- | time.c | 243 |
1 files changed, 130 insertions, 113 deletions
@@ -1303,7 +1303,7 @@ gmtimew(wideval_t timew, struct vtm *result) static struct tm *localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long *gmtoff, VALUE *zone); /* - * The idea is borrowed from Perl: + * The idea, extrapolate localtime() function, is borrowed from Perl: * http://web.archive.org/web/20080211114141/http://use.perl.org/articles/08/02/07/197204.shtml * * compat_common_month_table is generated by the following program. @@ -2394,12 +2394,12 @@ time_init_1(int argc, VALUE *argv, VALUE time) * It is initialized to the current system time if no argument is given. * * *Note:* The new object will use the resolution available on your - * system clock, and may include fractional seconds. + * system clock, and may include subsecond. * * If one or more arguments are specified, the time is initialized to the * specified time. * - * +sec+ may have fraction if it is a rational. + * +sec+ may have subsecond if it is a rational. * * +tz+ specifies the timezone. * It can be an offset from UTC, given either as a string such as "+09:00" @@ -2408,11 +2408,11 @@ time_init_1(int argc, VALUE *argv, VALUE time) * Or it can be a timezone object, * see {Timezone argument}[#class-Time-label-Timezone+argument] for details. * - * a = Time.new #=> 2007-11-19 07:50:02 -0600 - * b = Time.new #=> 2007-11-19 07:50:02 -0600 + * a = Time.new #=> 2020-07-21 01:27:44.917547285 +0900 + * b = Time.new #=> 2020-07-21 01:27:44.917617713 +0900 * a == b #=> false - * "%.6f" % a.to_f #=> "1195480202.282373" - * "%.6f" % b.to_f #=> "1195480202.283415" + * "%.6f" % a.to_f #=> "1595262464.917547" + * "%.6f" % b.to_f #=> "1595262464.917618" * * Time.new(2008,6,21, 13,30,0, "+09:00") #=> 2008-06-21 13:30:00 +0900 * @@ -2795,12 +2795,11 @@ get_scale(VALUE unit) * +seconds+ and +microseconds_with_frac+ since the Epoch. * +seconds_with_frac+ and +microseconds_with_frac+ * can be an Integer, Float, Rational, or other Numeric. - * A non-portable feature allows the offset to be negative on some systems. * * If +in+ argument is given, the result is in that timezone or UTC offset, or * if a numeric argument is given, the result is in local time. * The +in+ argument accepts the same types of arguments as +tz+ argument of - * Time::new: string, number of seconds, or a timezone object. + * Time.new: string, number of seconds, or a timezone object. * * * Time.at(0) #=> 1969-12-31 18:00:00 -0600 @@ -3511,7 +3510,7 @@ time_s_mkutc(int argc, VALUE *argv, VALUE klass) * Time.mktime(year, month, day, hour, min, sec, usec_with_frac) -> time * Time.mktime(sec, min, hour, day, month, year, dummy, dummy, isdst, dummy) -> time * - * Same as Time::gm, but interprets the values in the + * Same as Time.utc, but interprets the values in the * local time zone. * * Time.local(2000,"jan",1,20,15,1) #=> 2000-01-01 20:15:01 -0600 @@ -3534,9 +3533,10 @@ time_s_mktime(int argc, VALUE *argv, VALUE klass) * Returns the value of _time_ as an integer number of seconds * since the Epoch. * - * t = Time.now - * "%10.5f" % t.to_f #=> "1270968656.89607" - * t.to_i #=> 1270968656 + * If _time_ contains subsecond, they are truncated. + * + * t = Time.now #=> 2020-07-21 01:41:29.746012609 +0900 + * t.to_i #=> 1595263289 */ static VALUE @@ -3554,13 +3554,22 @@ time_to_i(VALUE time) * * Returns the value of _time_ as a floating point number of * seconds since the Epoch. + * The return value approximate the exact value in the Time object + * because floating point numbers cannot represent all rational numbers + * exactly. * - * t = Time.now - * "%10.5f" % t.to_f #=> "1270968744.77658" - * t.to_i #=> 1270968744 + * t = Time.now #=> 2020-07-20 22:00:29.38740268 +0900 + * t.to_f #=> 1595250029.3874028 + * t.to_i #=> 1595250029 * * Note that IEEE 754 double is not accurate enough to represent * the exact number of nanoseconds since the Epoch. + * (IEEE 754 double has 53bit mantissa. + * So it can represent exact number of nanoseconds only in + * `2 ** 53 / 1_000_000_000 / 60 / 60 / 24 = 104.2` days.) + * When Ruby uses a nanosecond-resolution clock function, + * such as +clock_gettime+ of POSIX, to obtain the current time, + * Time#to_f can lost information of a Time object created with +Time.now+. */ static VALUE @@ -3579,12 +3588,11 @@ time_to_f(VALUE time) * Returns the value of _time_ as a rational number of seconds * since the Epoch. * - * t = Time.now - * t.to_r #=> (1270968792716287611/1000000000) + * t = Time.now #=> 2020-07-20 22:03:45.212167333 +0900 + * t.to_r #=> (1595250225212167333/1000000000) * - * This methods is intended to be used to get an accurate value - * representing the nanoseconds since the Epoch. You can use this method - * to convert _time_ to another Epoch. + * This method is intended to be used to get an accurate value + * representing the seconds (including subsecond) since the Epoch. */ static VALUE @@ -3606,11 +3614,19 @@ time_to_r(VALUE time) * time.usec -> int * time.tv_usec -> int * - * Returns the number of microseconds for _time_. + * Returns the number of microseconds for the subsecond part of _time_. + * The result is a non-negative integer less than 10**6. + * + * t = Time.now #=> 2020-07-20 22:05:58.459785953 +0900 + * t.usec #=> 459785 * - * t = Time.now #=> 2007-11-19 08:03:26 -0600 - * "%10.6f" % t.to_f #=> "1195481006.775195" - * t.usec #=> 775195 + * If _time_ has fraction of microsecond (such as nanoseconds), + * it is truncated. + * + * t = Time.new(2000,1,1,0,0,0.666_777_888_999r) + * t.usec #=> 666777 + * + * Time#subsec can be used to obtain the subsecond part exactly. */ static VALUE @@ -3631,17 +3647,19 @@ time_usec(VALUE time) * time.nsec -> int * time.tv_nsec -> int * - * Returns the number of nanoseconds for _time_. + * Returns the number of nanoseconds for the subsecond part of _time_. + * The result is a non-negative integer less than 10**9. * - * t = Time.now #=> 2007-11-17 15:18:03 +0900 - * "%10.9f" % t.to_f #=> "1195280283.536151409" - * t.nsec #=> 536151406 + * t = Time.now #=> 2020-07-20 22:07:10.963933942 +0900 + * t.nsec #=> 963933942 * - * The lowest digits of #to_f and #nsec are different because - * IEEE 754 double is not accurate enough to represent - * the exact number of nanoseconds since the Epoch. + * If _time_ has fraction of nanosecond (such as picoseconds), + * it is truncated. + * + * t = Time.new(2000,1,1,0,0,0.666_777_888_999r) + * t.nsec #=> 666777888 * - * The more accurate value is returned by #nsec. + * Time#subsec can be used to obtain the subsecond part exactly. */ static VALUE @@ -3657,19 +3675,21 @@ time_nsec(VALUE time) * call-seq: * time.subsec -> number * - * Returns the fraction for _time_. + * Returns the subsecond for _time_. * * The return value can be a rational number. * - * t = Time.now #=> 2009-03-26 22:33:12 +0900 - * "%10.9f" % t.to_f #=> "1238074392.940563917" - * t.subsec #=> (94056401/100000000) + * t = Time.now #=> 2020-07-20 15:40:26.867462289 +0900 + * t.subsec #=> (867462289/1000000000) * - * The lowest digits of #to_f and #subsec are different because - * IEEE 754 double is not accurate enough to represent - * the rational number. + * t = Time.now #=> 2020-07-20 15:40:50.313828595 +0900 + * t.subsec #=> (62765719/200000000) + * + * t = Time.new(2000,1,1,2,3,4) #=> 2000-01-01 02:03:04 +0900 + * t.subsec #=> 0 + * + * Time.new(2000,1,1,0,0,1/3r,"UTC").subsec #=> (1/3) * - * The more accurate value is returned by #subsec. */ static VALUE @@ -3685,9 +3705,9 @@ time_subsec(VALUE time) * call-seq: * time <=> other_time -> -1, 0, +1, or nil * - * Comparison---Compares +time+ with +other_time+. + * Compares +time+ with +other_time+. * - * -1, 0, +1 or nil depending on whether +time+ is less than, equal to, or + * -1, 0, +1 or nil depending on whether +time+ is less than, equal to, or * greater than +other_time+. * * +nil+ is returned if the two values are incomparable. @@ -3730,7 +3750,7 @@ time_cmp(VALUE time1, VALUE time2) * time.eql?(other_time) * * Returns +true+ if _time_ and +other_time+ are - * both Time objects with the same seconds and fractional seconds. + * both Time objects with the same seconds (including subsecond) from the Epoch. */ static VALUE @@ -4114,7 +4134,7 @@ time_to_s(VALUE time) * time.inspect -> string * * Returns a detailed string representing _time_. Unlike to_s, - * preserves nanoseconds in the representation for easier debugging. + * preserves subsecond in the representation for easier debugging. * * t = Time.now * t.inspect #=> "2012-11-10 18:16:12.261257655 +0100" @@ -4183,11 +4203,11 @@ time_add(const struct time_object *tobj, VALUE torig, VALUE offset, int sign) * call-seq: * time + numeric -> time * - * Addition --- Adds some number of seconds (possibly fractional) to + * Adds some number of seconds (possibly including subsecond) to * _time_ and returns that value as a new Time object. * - * t = Time.now #=> 2007-11-19 08:22:21 -0600 - * t + (60 * 60 * 24) #=> 2007-11-20 08:22:21 -0600 + * t = Time.now #=> 2020-07-20 22:14:43.170490982 +0900 + * t + (60 * 60 * 24) #=> 2020-07-21 22:14:43.170490982 +0900 */ static VALUE @@ -4207,14 +4227,14 @@ time_plus(VALUE time1, VALUE time2) * time - other_time -> float * time - numeric -> time * - * Difference --- Returns a difference in seconds as a Float + * Returns a difference in seconds as a Float * between _time_ and +other_time+, or subtracts the given number * of seconds in +numeric+ from _time_. * - * t = Time.now #=> 2007-11-19 08:23:10 -0600 - * t2 = t + 2592000 #=> 2007-12-19 08:23:10 -0600 + * t = Time.now #=> 2020-07-20 22:15:49.302766336 +0900 + * t2 = t + 2592000 #=> 2020-08-19 22:15:49.302766336 +0900 * t2 - t #=> 2592000.0 - * t2 - 2592000 #=> 2007-11-19 08:23:10 -0600 + * t2 - 2592000 #=> 2020-07-20 22:15:49.302766336 +0900 */ static VALUE @@ -4285,31 +4305,29 @@ ndigits_denominator(VALUE ndigits) * call-seq: * time.round([ndigits]) -> new_time * - * Rounds sub seconds to a given precision in decimal digits (0 digits by default). + * Rounds subsecond to a given precision in decimal digits (0 digits by default). * It returns a new Time object. * +ndigits+ should be zero or a positive integer. * - * require 'time' - * * t = Time.utc(2010,3,30, 5,43,25.123456789r) - * t.iso8601(10) #=> "2010-03-30T05:43:25.1234567890Z" - * t.round.iso8601(10) #=> "2010-03-30T05:43:25.0000000000Z" - * t.round(0).iso8601(10) #=> "2010-03-30T05:43:25.0000000000Z" - * t.round(1).iso8601(10) #=> "2010-03-30T05:43:25.1000000000Z" - * t.round(2).iso8601(10) #=> "2010-03-30T05:43:25.1200000000Z" - * t.round(3).iso8601(10) #=> "2010-03-30T05:43:25.1230000000Z" - * t.round(4).iso8601(10) #=> "2010-03-30T05:43:25.1235000000Z" - * - * t = Time.utc(1999,12,31, 23,59,59) - * (t + 0.4).round.iso8601(3) #=> "1999-12-31T23:59:59.000Z" - * (t + 0.49).round.iso8601(3) #=> "1999-12-31T23:59:59.000Z" - * (t + 0.5).round.iso8601(3) #=> "2000-01-01T00:00:00.000Z" - * (t + 1.4).round.iso8601(3) #=> "2000-01-01T00:00:00.000Z" - * (t + 1.49).round.iso8601(3) #=> "2000-01-01T00:00:00.000Z" - * (t + 1.5).round.iso8601(3) #=> "2000-01-01T00:00:01.000Z" + * 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 + 0.123456789).round(4).iso8601(6) #=> "1999-12-31T23:59:59.123500Z" + * (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 + * + * t = Time.utc(1999,12,31, 23,59,59) #=> 1999-12-31 23:59:59 UTC + * (t + 0.123456789).round(4).iso8601(6) #=> 1999-12-31 23:59:59.1235 UTC */ static VALUE @@ -4337,29 +4355,27 @@ time_round(int argc, VALUE *argv, VALUE time) * call-seq: * time.floor([ndigits]) -> new_time * - * Floors sub seconds to a given precision in decimal digits (0 digits by default). + * Floors subsecond to a given precision in decimal digits (0 digits by default). * It returns a new Time object. * +ndigits+ should be zero or a positive integer. * - * require 'time' - * * t = Time.utc(2010,3,30, 5,43,25.123456789r) - * t.iso8601(10) #=> "2010-03-30T05:43:25.1234567890Z" - * t.floor.iso8601(10) #=> "2010-03-30T05:43:25.0000000000Z" - * t.floor(0).iso8601(10) #=> "2010-03-30T05:43:25.0000000000Z" - * t.floor(1).iso8601(10) #=> "2010-03-30T05:43:25.1000000000Z" - * t.floor(2).iso8601(10) #=> "2010-03-30T05:43:25.1200000000Z" - * t.floor(3).iso8601(10) #=> "2010-03-30T05:43:25.1230000000Z" - * t.floor(4).iso8601(10) #=> "2010-03-30T05:43:25.1234000000Z" + * t #=> 2010-03-30 05:43:25.123456789 UTC + * t.floor #=> 2010-03-30 05:43:25 UTC + * t.floor(0) #=> 2010-03-30 05:43:25 UTC + * t.floor(1) #=> 2010-03-30 05:43:25.1 UTC + * t.floor(2) #=> 2010-03-30 05:43:25.12 UTC + * t.floor(3) #=> 2010-03-30 05:43:25.123 UTC + * t.floor(4) #=> 2010-03-30 05:43:25.1234 UTC * * t = Time.utc(1999,12,31, 23,59,59) - * (t + 0.4).floor.iso8601(3) #=> "1999-12-31T23:59:59.000Z" - * (t + 0.9).floor.iso8601(3) #=> "1999-12-31T23:59:59.000Z" - * (t + 1.4).floor.iso8601(3) #=> "2000-01-01T00:00:00.000Z" - * (t + 1.9).floor.iso8601(3) #=> "2000-01-01T00:00:00.000Z" + * (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 * * t = Time.utc(1999,12,31, 23,59,59) - * (t + 0.123456789).floor(4).iso8601(6) #=> "1999-12-31T23:59:59.123400Z" + * (t + 0.123456789).floor(4) #=> 1999-12-31 23:59:59.1234 UTC */ static VALUE @@ -4384,29 +4400,27 @@ time_floor(int argc, VALUE *argv, VALUE time) * call-seq: * time.ceil([ndigits]) -> new_time * - * Ceils sub seconds to a given precision in decimal digits (0 digits by default). + * Ceils subsecond to a given precision in decimal digits (0 digits by default). * It returns a new Time object. * +ndigits+ should be zero or a positive integer. * - * require 'time' - * * t = Time.utc(2010,3,30, 5,43,25.0123456789r) - * t.iso8601(10) #=> "2010-03-30T05:43:25.0123456789Z" - * t.ceil.iso8601(10) #=> "2010-03-30T05:43:26.0000000000Z" - * t.ceil(0).iso8601(10) #=> "2010-03-30T05:43:26.0000000000Z" - * t.ceil(1).iso8601(10) #=> "2010-03-30T05:43:25.1000000000Z" - * t.ceil(2).iso8601(10) #=> "2010-03-30T05:43:25.0200000000Z" - * t.ceil(3).iso8601(10) #=> "2010-03-30T05:43:25.0130000000Z" - * t.ceil(4).iso8601(10) #=> "2010-03-30T05:43:25.0124000000Z" + * t #=> 2010-03-30 05:43:25 123456789/10000000000 UTC + * t.ceil #=> 2010-03-30 05:43:26 UTC + * t.ceil(0) #=> 2010-03-30 05:43:26 UTC + * t.ceil(1) #=> 2010-03-30 05:43:25.1 UTC + * t.ceil(2) #=> 2010-03-30 05:43:25.02 UTC + * t.ceil(3) #=> 2010-03-30 05:43:25.013 UTC + * t.ceil(4) #=> 2010-03-30 05:43:25.0124 UTC * * t = Time.utc(1999,12,31, 23,59,59) - * (t + 0.4).ceil.iso8601(3) #=> "2000-01-01T00:00:00.000Z" - * (t + 0.9).ceil.iso8601(3) #=> "2000-01-01T00:00:00.000Z" - * (t + 1.4).ceil.iso8601(3) #=> "2000-01-01T00:00:01.000Z" - * (t + 1.9).ceil.iso8601(3) #=> "2000-01-01T00:00:01.000Z" + * (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 * * t = Time.utc(1999,12,31, 23,59,59) - * (t + 0.123456789).ceil(4).iso8601(6) #=> "1999-12-31T23:59:59.123500Z" + * (t + 0.123456789).ceil(4) #=> 1999-12-31 23:59:59.1235 UTC */ static VALUE @@ -4496,7 +4510,7 @@ time_hour(VALUE time) * time.day -> integer * time.mday -> integer * - * Returns the day of the month (1..n) for _time_. + * Returns the day of the month (1..31) for _time_. * * t = Time.now #=> 2007-11-19 08:27:03 -0600 * t.day #=> 19 @@ -4840,7 +4854,7 @@ rb_time_utc_offset(VALUE time) * * See the individual methods for an explanation of the * valid ranges of each value. The ten elements can be passed directly - * to Time::utc or Time::local to create a + * to Time.utc or Time.local to create a * new Time object. * * t = Time.now #=> 2007-11-19 08:36:01 -0600 @@ -5709,16 +5723,19 @@ rb_time_zone_abbreviation(VALUE zone, VALUE time) /* * Time is an abstraction of dates and times. Time is stored internally as - * the number of seconds with fraction since the _Epoch_, + * the number of seconds with subsecond since the _Epoch_, * 1970-01-01 00:00:00 UTC. + * * The Time class treats GMT * (Greenwich Mean Time) and UTC (Coordinated Universal Time) as equivalent. * GMT is the older way of referring to these baseline times but persists in * the names of calls on POSIX systems. * - * All times may have fraction. Be aware of this fact when comparing times + * All times may have subsecond. Be aware of this fact when comparing times * with each other -- times that are apparently equal when displayed may be * different when compared. + * (Since Ruby 2.7.0, Time#inspect shows subsecond but + * Time#to_s still doesn't show subsecond.) * * Since Ruby 1.9.2, Time implementation uses a signed 63 bit integer, * Bignum or Rational. @@ -5733,9 +5750,9 @@ rb_time_zone_abbreviation(VALUE zone, VALUE time) * * == 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 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: @@ -5753,12 +5770,12 @@ rb_time_zone_abbreviation(VALUE zone, VALUE time) * tz = timezone("Europe/Athens") # Eastern European Time, UTC+2 * Time.new(2002, 10, 31, 2, 2, 2, tz) #=> 2002-10-31 02:02:02 +0200 * - * You can also use Time::gm, Time::local and Time::utc to infer GMT, + * 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 (or fraction of seconds) since the {Unix + * You can also create a new time using Time.at which takes the number of + * seconds (with subsecond) since the {Unix * Epoch}[http://en.wikipedia.org/wiki/Unix_time]. * * Time.at(628232400) #=> 1989-11-28 00:00:00 -0500 @@ -5813,9 +5830,9 @@ rb_time_zone_abbreviation(VALUE zone, VALUE time) * result also should be a Time or Time-like object (not necessary to * be the same class). The #zone of the result is just ignored. * Time-like argument to these methods is similar to a Time object in - * UTC without sub-second; it has attribute readers for the parts, + * UTC without subsecond; it has attribute readers for the parts, * e.g. #year, #month, and so on, and epoch time readers, #to_i. The - * sub-second attributes are fixed as 0, and #utc_offset, #zone, + * subsecond attributes are fixed as 0, and #utc_offset, #zone, * #isdst, and their aliases are same as a Time object in UTC. * Also #to_time, #+, and #- methods are defined. * |