From b3085ba508b9582ff279c2ddf59a44885e22c074 Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 3 Feb 2010 15:37:45 +0000 Subject: [PATCH] * 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 --- ChangeLog | 5 +++++ test/ruby/test_time.rb | 14 ++++++++++++++ time.c | 26 +++++++++++++++++++++++--- 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 + + * time.c (time_mdump, time_mload): dump/load utc_offset. + [ruby-dev:40063] + Wed Feb 3 22:22:30 2010 Nobuyoshi Nakada * 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);