summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-28 14:08:32 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-28 14:08:32 +0000
commitbdfc701b85b3109d5954ff05fc61ec3e0bbb58e3 (patch)
tree0e623d7bbfef693d5435aefc6a23e06abe6672af
parent337b4b634495f247711cb25636364cc7f967e457 (diff)
Timezone at Time.at
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66077 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--test/ruby/test_time_tz.rb12
-rw-r--r--time.c19
2 files changed, 29 insertions, 2 deletions
diff --git a/test/ruby/test_time_tz.rb b/test/ruby/test_time_tz.rb
index 5360666d3c..777f02bed9 100644
--- a/test/ruby/test_time_tz.rb
+++ b/test/ruby/test_time_tz.rb
@@ -544,6 +544,18 @@ module TestTimeTZ::WithTZ
assert_equal(time_class.utc(2018, 9, 1, 12+h, m, s), t)
end
+ def subtest_at(time_class, tz, tzarg, tzname, abbr, utc_offset)
+ h, m = (utc_offset / 60).divmod(60)
+ utc = time_class.utc(2018, 9, 1, 12, 0, 0)
+ t = time_class.at(utc, tzarg)
+ assert_equal([2018, 9, 1, 12+h, m, 0, tz], [t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.zone])
+ assert_equal(utc.to_i, t.to_i)
+ utc = utc.to_i
+ t = time_class.at(utc, tzarg)
+ assert_equal([2018, 9, 1, 12+h, m, 0, tz], [t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.zone])
+ assert_equal(utc, t.to_i)
+ end
+
def subtest_marshal(time_class, tz, tzarg, tzname, abbr, utc_offset)
t = time_class.new(2018, 9, 1, 12, 0, 0, tzarg)
t2 = Marshal.load(Marshal.dump(t))
diff --git a/time.c b/time.c
index f9a13f9169..2b7c836970 100644
--- a/time.c
+++ b/time.c
@@ -2670,6 +2670,14 @@ get_scale(VALUE unit)
* Time.at(seconds, microseconds, :microsecond) -> time
* Time.at(seconds, nanoseconds, :nsec) -> time
* Time.at(seconds, nanoseconds, :nanosecond) -> time
+ * Time.at(time, in: tz) -> time
+ * Time.at(seconds_with_frac, in: tz) -> time
+ * Time.at(seconds, microseconds_with_frac, in: tz) -> time
+ * Time.at(seconds, milliseconds, :millisecond, in: tz) -> time
+ * Time.at(seconds, microseconds, :usec, in: tz) -> time
+ * Time.at(seconds, microseconds, :microsecond, in: tz) -> time
+ * Time.at(seconds, nanoseconds, :nsec, in: tz) -> time
+ * Time.at(seconds, nanoseconds, :nanosecond, in: tz) -> time
*
* Creates a new Time object with the value given by +time+,
* the given number of +seconds_with_frac+, or
@@ -2678,7 +2686,8 @@ get_scale(VALUE unit)
* can be an Integer, Float, Rational, or other Numeric.
* non-portable feature allows the offset to be negative on some systems.
*
- * If a numeric argument is given, the result is in local time.
+ * If +tz+ 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.
*
* Time.at(0) #=> 1969-12-31 18:00:00 -0600
* Time.at(Time.at(0)) #=> 1969-12-31 18:00:00 -0600
@@ -2692,9 +2701,12 @@ get_scale(VALUE unit)
static VALUE
time_s_at(int argc, VALUE *argv, VALUE klass)
{
- VALUE time, t, unit = Qundef;
+ VALUE time, t, unit = Qundef, zone = Qnil;
wideval_t timew;
+ if (argc > 1 && rb_obj_respond_to(argv[argc-1], id_utc_to_local, Qfalse)) {
+ zone = argv[--argc];
+ }
if (rb_scan_args(argc, argv, "12", &time, &t, &unit) >= 2) {
int scale = argc == 3 ? get_scale(unit) : 1000000;
time = num_exact(time);
@@ -2713,6 +2725,9 @@ time_s_at(int argc, VALUE *argv, VALUE klass)
timew = rb_time_magnify(v2w(num_exact(time)));
t = time_new_timew(klass, timew);
}
+ if (!NIL_P(zone)) {
+ time_zonelocal(t, zone);
+ }
return t;
}