ruby-changes:64861
From: Nobuyoshi <ko1@a...>
Date: Wed, 13 Jan 2021 20:41:31 +0900 (JST)
Subject: [ruby-changes:64861] 4b15caee8f (master): Added `in:` timezone option to `Time.new` [Feature #17485]
https://git.ruby-lang.org/ruby.git/commit/?id=4b15caee8f From 4b15caee8fe7a5aaa52ed5a3ab2a3517c9206fd7 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Mon, 28 Dec 2020 21:13:41 +0900 Subject: Added `in:` timezone option to `Time.new` [Feature #17485] diff --git a/test/ruby/test_time_tz.rb b/test/ruby/test_time_tz.rb index dade0bf..7c89b35 100644 --- a/test/ruby/test_time_tz.rb +++ b/test/ruby/test_time_tz.rb @@ -606,6 +606,7 @@ module TestTimeTZ::WithTZ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_time_tz.rb#L606 assert_equal(time_class.utc(2018, 9, 1, 12+h, m, 0).to_i, t.to_i) assert_equal(6, t.wday) assert_equal(244, t.yday) + assert_equal(t, time_class.new(2018, 9, 1, 12, in: tzarg)) end def subtest_now(time_class, tz, tzarg, tzname, abbr, utc_offset) diff --git a/time.c b/time.c index 6d3352e..fc9a8ae 100644 --- a/time.c +++ b/time.c @@ -1907,7 +1907,7 @@ rb_timespec_now(struct timespec *ts) https://github.com/ruby/ruby/blob/trunk/time.c#L1907 } static VALUE -time_init_0(VALUE time) +time_init_now(rb_execution_context_t *ec, VALUE time, VALUE zone) { struct time_object *tobj; struct timespec ts; @@ -1920,6 +1920,9 @@ time_init_0(VALUE time) https://github.com/ruby/ruby/blob/trunk/time.c#L1920 rb_timespec_now(&ts); tobj->timew = timespec2timew(&ts); + if (!NIL_P(zone)) { + time_zonelocal(time, zone); + } return time; } @@ -2312,45 +2315,41 @@ find_timezone(VALUE time, VALUE zone) https://github.com/ruby/ruby/blob/trunk/time.c#L2315 } static VALUE -time_init_1(int argc, VALUE *argv, VALUE time) +time_init_args(rb_execution_context_t *ec, VALUE time, VALUE year, VALUE mon, VALUE mday, VALUE hour, VALUE min, VALUE sec, VALUE zone) { struct vtm vtm; - VALUE zone = Qnil; VALUE utc = Qnil; - VALUE v[7]; struct time_object *tobj; vtm.wday = VTM_WDAY_INITVAL; vtm.yday = 0; vtm.zone = str_empty; - /* year mon mday hour min sec off */ - rb_scan_args(argc, argv, "16", &v[0],&v[1],&v[2],&v[3],&v[4],&v[5],&v[6]); - - vtm.year = obj2vint(v[0]); + vtm.year = obj2vint(year); - vtm.mon = NIL_P(v[1]) ? 1 : month_arg(v[1]); + vtm.mon = NIL_P(mon) ? 1 : month_arg(mon); - vtm.mday = NIL_P(v[2]) ? 1 : obj2ubits(v[2], 5); + vtm.mday = NIL_P(mday) ? 1 : obj2ubits(mday, 5); - vtm.hour = NIL_P(v[3]) ? 0 : obj2ubits(v[3], 5); + vtm.hour = NIL_P(hour) ? 0 : obj2ubits(hour, 5); - vtm.min = NIL_P(v[4]) ? 0 : obj2ubits(v[4], 6); + vtm.min = NIL_P(min) ? 0 : obj2ubits(min, 6); - if (NIL_P(v[5])) { + if (NIL_P(sec)) { vtm.sec = 0; vtm.subsecx = INT2FIX(0); } else { VALUE subsecx; - vtm.sec = obj2subsecx(v[5], &subsecx); + vtm.sec = obj2subsecx(sec, &subsecx); vtm.subsecx = subsecx; } vtm.isdst = VTM_ISDST_INITVAL; vtm.utc_offset = Qnil; - if (!NIL_P(v[6])) { - VALUE arg = v[6]; + VALUE arg = zone; + if (!NIL_P(arg)) { + zone = Qnil; if (arg == ID2SYM(rb_intern("dst"))) vtm.isdst = 1; else if (arg == ID2SYM(rb_intern("std"))) @@ -2407,64 +2406,6 @@ time_init_1(int argc, VALUE *argv, VALUE time) https://github.com/ruby/ruby/blob/trunk/time.c#L2406 } } - -/* - * call-seq: - * Time.new -> time - * Time.new(year, month=nil, day=nil, hour=nil, min=nil, sec=nil, tz=nil) -> time - * - * Returns a Time object. - * - * 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 subsecond. - * - * If one or more arguments are specified, the time is initialized to the - * specified time. - * - * +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" - * or a single letter "A".."Z" excluding "J" (so-called military time zone), - * or as a number of seconds such as 32400. - * Or it can be a timezone object, - * see {Timezone argument}[#class-Time-label-Timezone+argument] for details. - * - * 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 #=> "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 - * - * # A trip for RubyConf 2007 - * t1 = Time.new(2007,11,1,15,25,0, "+09:00") # JST (Narita) - * t2 = Time.new(2007,11,1,12, 5,0, "-05:00") # CDT (Minneapolis) - * t3 = Time.new(2007,11,1,13,25,0, "-05:00") # CDT (Minneapolis) - * t4 = Time.new(2007,11,1,16,53,0, "-04:00") # EDT (Charlotte) - * t5 = Time.new(2007,11,5, 9,24,0, "-05:00") # EST (Charlotte) - * t6 = Time.new(2007,11,5,11,21,0, "-05:00") # EST (Detroit) - * t7 = Time.new(2007,11,5,13,45,0, "-05:00") # EST (Detroit) - * t8 = Time.new(2007,11,6,17,10,0, "+09:00") # JST (Narita) - * (t2-t1)/3600.0 #=> 10.666666666666666 - * (t4-t3)/3600.0 #=> 2.466666666666667 - * (t6-t5)/3600.0 #=> 1.95 - * (t8-t7)/3600.0 #=> 13.416666666666666 - * - */ - -static VALUE -time_init(int argc, VALUE *argv, VALUE time) -{ - if (argc == 0) - return time_init_0(time); - else - return time_init_1(argc, argv, time); -} - static void time_overflow_p(time_t *secp, long *nsecp) { @@ -2739,17 +2680,6 @@ rb_time_timespec_interval(VALUE num) https://github.com/ruby/ruby/blob/trunk/time.c#L2680 return time_timespec(num, TRUE); } -static VALUE -time_s_now(rb_execution_context_t *ec, VALUE klass, VALUE zone) -{ - VALUE t; - t = rb_class_new_instance(0, NULL, klass); - if (!NIL_P(zone)) { - time_zonelocal(t, zone); - } - return t; -} - static int get_scale(VALUE unit) { @@ -5809,7 +5739,6 @@ Init_Time(void) https://github.com/ruby/ruby/blob/trunk/time.c#L5739 rb_define_method(rb_cTime, "<=>", time_cmp, 1); rb_define_method(rb_cTime, "eql?", time_eql, 1); rb_define_method(rb_cTime, "hash", time_hash, 0); - rb_define_method(rb_cTime, "initialize", time_init, -1); rb_define_method(rb_cTime, "initialize_copy", time_init_copy, 1); rb_define_method(rb_cTime, "localtime", time_localtime_m, -1); diff --git a/timev.rb b/timev.rb index 37cefaf..d0989cb 100644 --- a/timev.rb +++ b/timev.rb @@ -7,7 +7,7 @@ https://github.com/ruby/ruby/blob/trunk/timev.rb#L7 # # Time.now #=> 2009-06-24 12:39:54 +0900 def Time.now(in: nil) - __builtin.time_s_now(__builtin.arg!(:in)) + new(in: __builtin.arg!(:in)) end # @@ -60,3 +60,56 @@ end https://github.com/ruby/ruby/blob/trunk/timev.rb#L60 def Time.at(time, subsec = (nosubsec = true), unit = (nounit = true), in: nil) __builtin.time_s_at(time, subsec, unit, __builtin.arg!(:in), nosubsec, nounit) end + +class Time + # call-seq: + # Time.new -> time + # Time.new(year, month=nil, day=nil, hour=nil, min=nil, sec=nil, tz=nil) -> time + # Time.new(year, month=nil, day=nil, hour=nil, min=nil, sec=nil, in: tz) -> time + # + # Returns a Time object. + # + # 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 subsecond. + # + # If one or more arguments are specified, the time is initialized to the + # specified time. + # + # +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" + # or a single letter "A".."Z" excluding "J" (so-called military time zone), + # or as a number of seconds such as 32400. + # Or it can be a timezone object, + # see {Timezone argument}[#class-Time-label-Timezone+argument] for details. + # + # 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 #=> "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 + # + # # A trip for RubyConf 2007 + # t1 = Time.new(2007,11,1,15,25,0, "+09:00") # JST (Narita) + # t2 = Time.new(2007,11,1,12, 5,0, "-05:00") # CDT (Minneapolis) + # t3 = Time.new(2007,11,1,13,25,0, "-05:00") # CDT (Minneapolis) + # t4 = Time.new(2007,11,1,16,53,0, "-04:00") # EDT (Charlotte) + # t5 = Time.new(2007,11,5, 9,24,0, "-05:00") # EST (Charlotte) + # t6 = Time.new(2007,11,5,11,21,0, "-05:00") # EST (Detroit) + # t7 = Time.new(2007,11,5,13,45,0, "-05:00") # EST (Detroit) + # t8 = Time.new(2007,11,6,17,10,0, "+09:00") # JST (Narita) + # (t2-t1)/3600.0 #=> 10.666666666666666 + # (t4-t3)/3600.0 #=> 2.466666666666667 + # (t6-t5)/3600.0 #=> 1.95 + # (t8-t7)/3600.0 #=> 13.416666666666666 + def initialize(year = (now = true), mon = nil, mday = nil, hour = nil, min = nil, sec = nil, zone = nil, in: zone) + zone = __builtin.arg!(:in) + return __builtin.time_init_now(zone) if now + __builtin.time_init_args(year, mon, mday, hour, min, sec, zone) + end +end -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/