summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-02-03 15:37:45 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-02-03 15:37:45 +0000
commitb3085ba508b9582ff279c2ddf59a44885e22c074 (patch)
treec9ddb23b7ef2ed69c30aed80a916540c0939de69
parent572c266e055e517896accfee55672fa1352a36db (diff)
* time.c (time_mdump, time_mload): dump/load utc_offset.
[ruby-dev:40063] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26560 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--test/ruby/test_time.rb14
-rw-r--r--time.c26
3 files changed, 42 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 037820711e..9bc586afab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Thu Feb 4 00:37:43 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * time.c (time_mdump, time_mload): dump/load utc_offset.
+ [ruby-dev:40063]
+
Wed Feb 3 22:22:30 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
* configure.in: check for non-portable stack attribute functions.
diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb
index d5dd86765f..73afed3902 100644
--- a/test/ruby/test_time.rb
+++ b/test/ruby/test_time.rb
@@ -210,6 +210,20 @@ class TestTime < Test::Unit::TestCase
assert_marshal_roundtrip(Marshal.load(Marshal.dump(t)))
end
+ def test_marshal_timezone
+ bug = '[ruby-dev:40063]'
+
+ t1 = Time.gm(2000)
+ m = Marshal.dump(t1.getlocal("-02:00"))
+ t2 = Marshal.load(m)
+ assert_equal(t1, t2)
+ assert_equal(-7200, t2.utc_offset, bug)
+ m = Marshal.dump(t1.getlocal("+08:15"))
+ t2 = Marshal.load(m)
+ assert_equal(t1, t2)
+ assert_equal(29700, t2.utc_offset, bug)
+ end
+
# Sat Jan 01 00:00:00 UTC 2000
T2000 = Time.at(946684800).gmtime
diff --git a/time.c b/time.c
index e50389a97b..7bab3760a6 100644
--- a/time.c
+++ b/time.c
@@ -103,7 +103,7 @@ rb_localtime(const time_t *tm, struct tm *result)
}
#endif
-static ID id_divmod, id_mul, id_submicro, id_nano_num, id_nano_den;
+static ID id_divmod, id_mul, id_submicro, id_nano_num, id_nano_den, id_offset;
static ID id_eq, id_ne, id_quo, id_div, id_cmp, id_lshift;
#define eq(x,y) (RTEST(rb_funcall((x), id_eq, 1, (y))))
@@ -3675,6 +3675,13 @@ time_mdump(VALUE time)
len = 1;
rb_ivar_set(str, id_submicro, rb_str_new(buf, len));
}
+ if (!TIME_UTC_P(tobj)) {
+ VALUE off = time_utc_offset(time), div, mod;
+ divmodv(off, INT2FIX(1), &div, &mod);
+ if (rb_equal(mod, INT2FIX(0)))
+ off = rb_Integer(div);
+ rb_ivar_set(str, id_offset, off);
+ }
return str;
}
@@ -3711,7 +3718,7 @@ time_mload(VALUE time, VALUE str)
struct vtm vtm;
int i, gmt;
long nsec;
- VALUE timexv, submicro, nano_num, nano_den;
+ VALUE timexv, submicro, nano_num, nano_den, offset;
time_modify(time);
@@ -3727,6 +3734,11 @@ time_mload(VALUE time, VALUE str)
if (submicro != Qnil) {
st_delete(rb_generic_ivar_table(str), (st_data_t*)&id_submicro, 0);
}
+ offset = rb_attr_get(str, id_offset);
+ if (offset != Qnil) {
+ validate_utc_offset(offset);
+ st_delete(rb_generic_ivar_table(str), (st_data_t*)&id_offset, 0);
+ }
rb_copy_generic_ivar(time, str);
StringValue(str);
@@ -3745,6 +3757,7 @@ time_mload(VALUE time, VALUE str)
if ((p & (1UL<<31)) == 0) {
gmt = 0;
+ offset = Qnil;
sec = p;
usec = s;
nsec = usec * 1000;
@@ -3799,8 +3812,14 @@ end_submicro: ;
GetTimeval(time, tobj);
tobj->tm_got = 0;
- if (gmt) TIME_SET_UTC(tobj);
tobj->timexv = timexv;
+ if (gmt) {
+ TIME_SET_UTC(tobj);
+ }
+ else if (!NIL_P(offset)) {
+ time_set_utc_offset(time, offset);
+ time_fixoff(time);
+ }
return time;
}
@@ -3855,6 +3874,7 @@ Init_Time(void)
id_submicro = rb_intern("submicro");
id_nano_num = rb_intern("nano_num");
id_nano_den = rb_intern("nano_den");
+ id_offset = rb_intern("offset");
rb_cTime = rb_define_class("Time", rb_cObject);
rb_include_module(rb_cTime, rb_mComparable);