aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-01-07 06:59:46 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-01-07 06:59:46 +0000
commit4f9ab3a01a475f5236632575fa4d3a6b6aef7d15 (patch)
treedb56fb9849f1b066f1730399db0dcf88db5580f7
parentda1f9199bd659f6277d53cc41f6007911fb3a9c5 (diff)
downloadruby-4f9ab3a01a475f5236632575fa4d3a6b6aef7d15.tar.gz
time.c: UTC and Z timezones should be utc
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66746 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--test/ruby/test_time_tz.rb6
-rw-r--r--time.c39
2 files changed, 42 insertions, 3 deletions
diff --git a/test/ruby/test_time_tz.rb b/test/ruby/test_time_tz.rb
index 8e60cf44c5..ec5c9a2dbe 100644
--- a/test/ruby/test_time_tz.rb
+++ b/test/ruby/test_time_tz.rb
@@ -254,6 +254,12 @@ class TestTimeTZ < Test::Unit::TestCase
}
end if has_right_tz
+ def test_utc_names
+ assert_predicate(Time.new(2019, 1, 1, 0, 0, 0, "UTC"), :utc?)
+ assert_predicate(Time.new(2019, 1, 1, 0, 0, 0, "utc"), :utc?)
+ assert_predicate(Time.new(2019, 1, 1, 0, 0, 0, "Z"), :utc?)
+ end
+
MON2NUM = {
"Jan" => 1, "Feb" => 2, "Mar" => 3, "Apr" => 4, "May" => 5, "Jun" => 6,
"Jul" => 7, "Aug" => 8, "Sep" => 9, "Oct" => 10, "Nov" => 11, "Dec" => 12
diff --git a/time.c b/time.c
index 3bbfce6b38..96a657e41d 100644
--- a/time.c
+++ b/time.c
@@ -40,6 +40,7 @@ static ID id_quo, id_div;
static ID id_nanosecond, id_microsecond, id_millisecond, id_nsec, id_usec;
static ID id_local_to_utc, id_utc_to_local, id_find_timezone;
static ID id_year, id_mon, id_mday, id_hour, id_min, id_sec, id_isdst, id_name;
+#define UTC_ZONE Qundef
#ifndef TM_IS_TIME
#define TM_IS_TIME 1
@@ -2061,6 +2062,18 @@ utc_offset_arg(VALUE arg)
return Qnil;
}
switch (RSTRING_LEN(tmp)) {
+ case 1:
+ if (s[0] == 'Z') {
+ return UTC_ZONE;
+ }
+ else {
+ goto invalid_utc_offset;
+ }
+ case 3:
+ if (STRNCASECMP("UTC", s, 3) == 0) {
+ return UTC_ZONE;
+ }
+ goto invalid_utc_offset;
case 9:
if (s[6] != ':') goto invalid_utc_offset;
if (!ISDIGIT(s[7]) || !ISDIGIT(s[8])) goto invalid_utc_offset;
@@ -2232,6 +2245,7 @@ time_init_1(int argc, VALUE *argv, VALUE time)
{
struct vtm vtm;
VALUE zone = Qnil;
+ VALUE utc = Qnil;
VALUE v[7];
struct time_object *tobj;
@@ -2272,9 +2286,10 @@ time_init_1(int argc, VALUE *argv, VALUE time)
vtm.isdst = 0;
else if (maybe_tzobj_p(arg))
zone = arg;
- else if (NIL_P(vtm.utc_offset = utc_offset_arg(arg)))
- if (NIL_P(zone = find_timezone(time, arg)))
- invalid_utc_offset();
+ else if (!NIL_P(utc = utc_offset_arg(arg)))
+ vtm.utc_offset = utc == UTC_ZONE ? INT2FIX(0) : utc;
+ else if (NIL_P(zone = find_timezone(time, arg)))
+ invalid_utc_offset();
}
validate_vtm(&vtm);
@@ -2296,6 +2311,14 @@ time_init_1(int argc, VALUE *argv, VALUE time)
}
}
+ if (utc == UTC_ZONE) {
+ tobj->timew = timegmw(&vtm);
+ tobj->vtm = vtm;
+ tobj->tm_got = 1;
+ TZMODE_SET_UTC(tobj);
+ return time;
+ }
+
tobj->tzmode = TIME_TZMODE_LOCALTIME;
tobj->tm_got=0;
tobj->timew = WINT2FIXWV(0);
@@ -2503,6 +2526,10 @@ rb_time_num_new(VALUE timev, VALUE off)
if (!zone_timelocal(zone, time)) invalid_utc_offset();
return time;
}
+ else if (off == UTC_ZONE) {
+ return time_gmtime(time);
+ }
+
validate_utc_offset(off);
time_set_utc_offset(time, off);
return time;
@@ -3738,6 +3765,9 @@ time_zonelocal(VALUE time, VALUE off)
if (!zone_localtime(zone, time)) invalid_utc_offset();
return time;
}
+ else if (off == UTC_ZONE) {
+ return time_gmtime(time);
+ }
validate_utc_offset(off);
time_set_utc_offset(time, off);
@@ -3901,6 +3931,9 @@ time_getlocaltime(int argc, VALUE *argv, VALUE time)
if (!zone_localtime(zone, time)) invalid_utc_offset();
return time;
}
+ else if (off == UTC_ZONE) {
+ return time_gmtime(time_dup(time));
+ }
validate_utc_offset(off);
time = time_dup(time);