[#35789] [Ruby 1.9 - Bug #407] (Open) String#<< — Shyouhei Urabe <redmine@...>

チケット #407 が報告されました。 (by Shyouhei Urabe)

13 messages 2008/08/06

[#35845] [Bug #437] test_strftime(TestTime) fails on Solaris — Shugo Maeda <redmine@...>

Bug #437: test_strftime(TestTime) fails on Solaris

24 messages 2008/08/13
[#35855] Re: [Bug #437] test_strftime(TestTime) fails on Solaris — "Shugo Maeda" <shugo@...> 2008/08/15

前田です。

[#35856] Re: [Bug #437] test_strftime(TestTime) fails on Solaris — SATOH Fumiyasu <fumiyas@...> 2008/08/15

さとうふみやす @ OSS テクノロジです。

[#35857] Re: [Bug #437] test_strftime(TestTime) fails on Solaris — Yukihiro Matsumoto <matz@...> 2008/08/15

まつもと ゆきひろです

[#35870] Re: [Bug #437] test_strftime(TestTime) fails on Solaris — "Shugo Maeda" <shugo@...> 2008/08/18

前田です。

[#35863] Refactoring of enumerating prime numbers — "Yugui (Yuki Sonoda)" <yugui@...>

Yuguiです。

20 messages 2008/08/16
[#35865] Re: Refactoring of enumerating prime numbers — keiju@... (keiju ISHITSUKA) 2008/08/17

けいじゅ@いしつかです.

[#35867] Re: Refactoring of enumerating prime numbers — "Yugui (Yuki Sonoda)" <yugui@...> 2008/08/17

Yuguiです。

[#35875] Re: Refactoring of enumerating prime numbers — keiju@... (keiju ISHITSUKA) 2008/08/19

けいじゅ@いしつかです.

[#35877] Re: Refactoring of enumerating prime numbers — Nobuyoshi Nakada <nobu@...> 2008/08/19

なかだです。

[#35882] Re: Refactoring of enumerating prime numbers — keiju@... (石塚圭樹) 2008/08/20

けいじゅ@いしつかです.

[#35904] [Feature:1.9] pack format 'm' based on RFC 4648 — "Yusuke ENDOH" <mame@...>

遠藤です。

14 messages 2008/08/21
[#36442] [Feature #471] pack format 'm' based on RFC 4648 — Yuki Sonoda <redmine@...> 2008/09/22

チケット #471 が更新されました。 (by Yuki Sonoda)

[#35906] %N for Time#strftime — "Shugo Maeda" <shugo@...>

前田です。

13 messages 2008/08/21

[#35986] 1.9と1.8で、delegateのインスタンスのクラス名の違う — Fujioka <fuj@...>

xibbarこと藤岡です。

17 messages 2008/08/26
[#35987] Re: 1.9と1.8で、delegateのインスタンスのクラス名の違う — Yukihiro Matsumoto <matz@...> 2008/08/26

まつもと ゆきひろです

[#35991] Re: 1.9と1.8で、delegateのインスタンスのクラス名の違う — keiju@... (石塚圭樹) 2008/08/26

けいじゅ@いしつかです.

[#35994] Re: 1.9と1.8で、delegateのインスタンスのクラス名の違う — Fujioka <fuj@...> 2008/08/27

藤岡です。

[#35998] Re: 1.9と1.8で、delegateのインスタンスのクラス名の違う — keiju@... (石塚圭樹) 2008/08/27

けいじゅ@いしつかです.

[#36066] Numeric#scalar? — Tadayoshi Funaba <tadf@...>

1.9 の Numeric#scalar? について、適当でないのでは (real? などのほうがい

24 messages 2008/08/31
[#36069] Re: Numeric#scalar? — Shin-ichiro HARA <sinara@...> 2008/08/31

原です。

[#36104] Re: Numeric#scalar? — Tadayoshi Funaba <tadf@...> 2008/09/02

> やはり、scalar? はずれているんじゃないかな。real? の方がいい

[#36122] Re: Numeric#scalar? — Shin-ichiro HARA <sinara@...> 2008/09/03

原です。

[#36133] Re: Numeric#scalar? — Tadayoshi Funaba <tadf@...> 2008/09/03

> ここで、scalar? を疑問視する理由を復習すると、たとえば、「複

[#36173] Re: Numeric#scalar? — Tadayoshi Funaba <tadf@...> 2008/09/05

1.9.1 までに時間がないので scalar? だけ何とかしたいと思っていましたが、

[#36183] Re: Numeric#scalar? — "Shugo Maeda" <shugo@...> 2008/09/06

前田です。

[#36186] Re: Numeric#scalar? — Shin-ichiro HARA <sinara@...> 2008/09/06

原です。

[ruby-dev:35912] Re: %N for Time#strftime

From: Nobuyoshi Nakada <nobu@...>
Date: 2008-08-22 05:27:09 UTC
List: ruby-dev #35912
なかだです。

At Fri, 22 Aug 2008 13:31:07 +0900,
Yukihiro Matsumoto wrote in [ruby-dev:35911]:
> |> > のように書けるのですが、こちらはPerlのとは意味が違って、9より大きい値を指定
> |> > した時に、指定した桁数になるように前に0を詰める機能で、N以外の変換指定文
> |> > 字でも使えるようです。
> |> 
> |> ちょっと試してみて思ったのですが、9 より大きな値を指定した時
> |> は 0 を右につけるべきじゃないですかね。
> |
> |+1
> 
> 私もそう思います。コミット、コミット。

date/format.rbとstrftime.cで同じようなことをやっていると一貫させ
るのがめんどうなので、Timeでもtime_tの範囲を越える範囲を表現でき
るようにして、DateTimeでもTime#strftimeを使うというのはどうでしょ
うか。

とりあえずtime.cだけ。


Index: time.c
===================================================================
--- time.c	(revision 18772)
+++ time.c	(working copy)
@@ -23,5 +23,6 @@
 
 VALUE rb_cTime;
-static VALUE time_utc_offset _((VALUE));
+static VALUE time_utc_offset(VALUE);
+static time_t make_time_t(struct tm *, int);
 
 static ID id_divmod, id_mul, id_submicro;
@@ -30,6 +31,8 @@ struct time_object {
     struct timespec ts;
     struct tm tm;
-    int gmt;
-    int tm_got;
+    union {
+	struct {int gmt:1, tm_got:1, ts_got:1;} bits;
+	int flags;
+    } as;
 };
 
@@ -43,4 +46,7 @@ time_free(void *tobj)
 }
 
+#define IS_TIME(time) (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free)
+
+
 static VALUE
 time_s_alloc(VALUE klass)
@@ -50,5 +56,5 @@ time_s_alloc(VALUE klass)
 
     obj = Data_Make_Struct(klass, struct time_object, 0, time_free, tobj);
-    tobj->tm_got=0;
+    tobj->as.flags = 0;
     tobj->ts.tv_sec = 0;
     tobj->ts.tv_nsec = 0;
@@ -96,5 +102,5 @@ time_init(VALUE time)
     time_modify(time);
     GetTimeval(time, tobj);
-    tobj->tm_got=0;
+    tobj->as.flags = 0;
     tobj->ts.tv_sec = 0;
     tobj->ts.tv_nsec = 0;
@@ -113,4 +119,5 @@ time_init(VALUE time)
     }
 #endif
+    tobj->as.bits.ts_got = 1;
 
     return time;
@@ -160,4 +167,6 @@ time_new_internal(VALUE klass, time_t se
     tobj->ts.tv_sec = sec;
     tobj->ts.tv_nsec = nsec;
+    tobj->as.flags = 0;
+    tobj->as.bits.ts_got = 1;
 
     return time;
@@ -270,7 +279,11 @@ rb_time_timeval(VALUE time)
     struct timeval t;
 
-    if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) {
+    if (IS_TIME(time)) {
 	GetTimeval(time, tobj);
-        t.tv_sec = tobj->ts.tv_sec;
+	if (!tobj->as.bits.ts_got) {
+	    tobj->ts.tv_sec = make_time_t(&tobj->tm, tobj->as.bits.gmt);
+	    tobj->as.bits.ts_got = 1;
+	}
+	t.tv_sec = tobj->ts.tv_sec;
         t.tv_usec = tobj->ts.tv_nsec / 1000;
 	return t;
@@ -279,14 +292,22 @@ rb_time_timeval(VALUE time)
 }
 
+static struct timespec
+get_timespec(struct time_object *tobj)
+{
+    if (!tobj->as.bits.ts_got) {
+	tobj->ts.tv_sec = make_time_t(&tobj->tm, tobj->as.bits.gmt);
+	tobj->as.bits.ts_got = 1;
+    }
+    return tobj->ts;
+}
+
 struct timespec
 rb_time_timespec(VALUE time)
 {
     struct time_object *tobj;
-    struct timespec t;
 
-    if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) {
+    if (IS_TIME(time)) {
 	GetTimeval(time, tobj);
-        t = tobj->ts;
-	return t;
+	return get_timespec(tobj);
     }
     return time_timespec(time, Qfalse);
@@ -328,10 +349,10 @@ time_s_at(int argc, VALUE *argv, VALUE k
     }
     t = time_new_internal(klass, ts.tv_sec, ts.tv_nsec);
-    if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) {
+    if (IS_TIME(time)) {
 	struct time_object *tobj, *tobj2;
 
 	GetTimeval(time, tobj);
 	GetTimeval(t, tobj2);
-	tobj2->gmt = tobj->gmt;
+	tobj2->as.bits.gmt = tobj->as.bits.gmt;
     }
     return t;
@@ -589,5 +610,5 @@ typedef unsigned LONG_LONG unsigned_time
 
 static time_t
-search_time_t(struct tm *tptr, int utc_p)
+search_time_t(struct tm *tptr, const int utc_p)
 {
     time_t guess, guess_lo, guess_hi;
@@ -897,10 +918,15 @@ time_utc_or_local(int argc, VALUE *argv,
     struct tm tm;
     VALUE time;
+    struct time_object *tobj;
     long nsec;
 
     time_arg(argc, argv, &tm, &nsec);
-    time = time_new_internal(klass, make_time_t(&tm, utc_p), nsec);
-    if (utc_p) return time_gmtime(time);
-    return time_localtime(time);
+    time = time_s_alloc(klass);
+    GetTimeval(time, tobj);
+    tobj->tm = tm;
+    tobj->ts.tv_nsec = nsec;
+    tobj->as.bits.tm_got = 1;
+    tobj->as.bits.gmt = utc_p != 0;
+    return time;
 }
 
@@ -993,4 +1019,5 @@ time_to_i(VALUE time)
 
     GetTimeval(time, tobj);
+    get_timespec(tobj);
     return LONG2NUM(tobj->ts.tv_sec);
 }
@@ -1017,4 +1044,5 @@ time_to_f(VALUE time)
 
     GetTimeval(time, tobj);
+    get_timespec(tobj);
     return DOUBLE2NUM((double)tobj->ts.tv_sec+(double)tobj->ts.tv_nsec/1e9);
 }
@@ -1038,4 +1066,5 @@ time_usec(VALUE time)
 
     GetTimeval(time, tobj);
+    get_timespec(tobj);
     return LONG2NUM(tobj->ts.tv_nsec/1000);
 }
@@ -1064,4 +1093,5 @@ time_nsec(VALUE time)
 
     GetTimeval(time, tobj);
+    get_timespec(tobj);
     return LONG2NUM(tobj->ts.tv_nsec);
 }
@@ -1093,6 +1123,8 @@ time_cmp(VALUE time1, VALUE time2)
 
     GetTimeval(time1, tobj1);
-    if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {
+    if (IS_TIME(time2)) {
 	GetTimeval(time2, tobj2);
+	get_timespec(tobj1);
+	get_timespec(tobj2);
 	if (tobj1->ts.tv_sec == tobj2->ts.tv_sec) {
 	    if (tobj1->ts.tv_nsec == tobj2->ts.tv_nsec) return INT2FIX(0);
@@ -1132,6 +1164,8 @@ time_eql(VALUE time1, VALUE time2)
 
     GetTimeval(time1, tobj1);
-    if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {
+    if (IS_TIME(time2)) {
 	GetTimeval(time2, tobj2);
+	get_timespec(tobj1);
+	get_timespec(tobj2);
 	if (tobj1->ts.tv_sec == tobj2->ts.tv_sec) {
 	    if (tobj1->ts.tv_nsec == tobj2->ts.tv_nsec) return Qtrue;
@@ -1166,5 +1200,5 @@ time_utc_p(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->gmt) return Qtrue;
+    if (tobj->as.bits.gmt) return Qtrue;
     return Qfalse;
 }
@@ -1180,9 +1214,8 @@ static VALUE
 time_hash(VALUE time)
 {
-    struct time_object *tobj;
+    struct timespec ts = rb_time_timespec(time);
     long hash;
 
-    GetTimeval(time, tobj);
-    hash = tobj->ts.tv_sec ^ tobj->ts.tv_nsec;
+    hash = ts.tv_sec ^ ts.tv_nsec;
     return LONG2FIX(hash);
 }
@@ -1196,5 +1229,5 @@ time_init_copy(VALUE copy, VALUE time)
     if (copy == time) return copy;
     time_modify(copy);
-    if (TYPE(time) != T_DATA || RDATA(time)->dfree != time_free) {
+    if (!IS_TIME(time)) {
 	rb_raise(rb_eTypeError, "wrong argument type");
     }
@@ -1236,6 +1269,6 @@ time_localtime(VALUE time)
 
     GetTimeval(time, tobj);
-    if (!tobj->gmt) {
-	if (tobj->tm_got)
+    if (!tobj->as.bits.gmt) {
+	if (tobj->as.bits.tm_got)
 	    return time;
     }
@@ -1243,11 +1276,11 @@ time_localtime(VALUE time)
 	time_modify(time);
     }
-    t = tobj->ts.tv_sec;
+    t = get_timespec(tobj).tv_sec;
     tm_tmp = LOCALTIME(&t, result);
     if (!tm_tmp)
 	rb_raise(rb_eArgError, "localtime error");
     tobj->tm = *tm_tmp;
-    tobj->tm_got = 1;
-    tobj->gmt = 0;
+    tobj->as.bits.tm_got = 1;
+    tobj->as.bits.gmt = 0;
     return time;
 }
@@ -1280,6 +1313,6 @@ time_gmtime(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->gmt) {
-	if (tobj->tm_got)
+    if (tobj->as.bits.gmt) {
+	if (tobj->as.bits.tm_got)
 	    return time;
     }
@@ -1287,4 +1320,5 @@ time_gmtime(VALUE time)
 	time_modify(time);
     }
+    get_timespec(tobj);
     t = tobj->ts.tv_sec;
     tm_tmp = GMTIME(&t, result);
@@ -1292,6 +1326,6 @@ time_gmtime(VALUE time)
 	rb_raise(rb_eArgError, "gmtime error");
     tobj->tm = *tm_tmp;
-    tobj->tm_got = 1;
-    tobj->gmt = 1;
+    tobj->as.bits.tm_got = 1;
+    tobj->as.bits.gmt = 1;
     return time;
 }
@@ -1363,6 +1397,6 @@ time_asctime(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (tobj->as.bits.tm_got == 0) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
     s = ASCTIME(&tobj->tm, buf);
@@ -1400,14 +1434,14 @@ time_to_s(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (tobj->as.bits.tm_got == 0) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
-    if (tobj->gmt == 1) {
+    if (tobj->as.bits.gmt) {
 	len = rb_strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S UTC",
-			  &tobj->tm, &tobj->ts, tobj->gmt);
+			  &tobj->tm, &tobj->ts, tobj->as.bits.gmt);
     }
     else {
 	len = rb_strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z",
-			  &tobj->tm, &tobj->ts, tobj->gmt);
+			  &tobj->tm, &tobj->ts, tobj->as.bits.gmt);
     }
     return rb_str_new(buf, len);
@@ -1428,4 +1462,5 @@ time_add(struct time_object *tobj, VALUE
 	sign = -sign;
     }
+    get_timespec(tobj);
     d = modf(v, &f);
     sec_off = (unsigned_time_t)f;
@@ -1448,7 +1483,7 @@ time_add(struct time_object *tobj, VALUE
     }
     result = rb_time_nano_new(sec, nsec);
-    if (tobj->gmt) {
+    if (tobj->as.bits.gmt) {
 	GetTimeval(result, tobj);
-	tobj->gmt = 1;
+	tobj->as.bits.gmt = 1;
     }
     return result;
@@ -1472,5 +1507,5 @@ time_plus(VALUE time1, VALUE time2)
     GetTimeval(time1, tobj);
 
-    if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {
+    if (IS_TIME(time2)) {
 	rb_raise(rb_eTypeError, "time + time?");
     }
@@ -1499,9 +1534,11 @@ time_minus(VALUE time1, VALUE time2)
 
     GetTimeval(time1, tobj);
-    if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {
+    if (IS_TIME(time2)) {
 	struct time_object *tobj2;
 	double f;
 
 	GetTimeval(time2, tobj2);
+	get_timespec(tobj);
+	get_timespec(tobj2);
         if (tobj->ts.tv_sec < tobj2->ts.tv_sec)
             f = -(double)(unsigned_time_t)(tobj2->ts.tv_sec - tobj->ts.tv_sec);
@@ -1532,8 +1569,9 @@ time_succ(VALUE time)
 
     GetTimeval(time, tobj);
-    gmt = tobj->gmt;
+    get_timespec(tobj);
+    gmt = tobj->as.bits.gmt;
     time = rb_time_nano_new(tobj->ts.tv_sec + 1, tobj->ts.tv_nsec);
     GetTimeval(time, tobj);
-    tobj->gmt = gmt;
+    tobj->as.bits.gmt = gmt;
     return time;
 }
@@ -1564,6 +1602,6 @@ time_sec(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (!tobj->as.bits.tm_got) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
     return INT2FIX(tobj->tm.tm_sec);
@@ -1586,6 +1624,6 @@ time_min(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (!tobj->as.bits.tm_got) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
     return INT2FIX(tobj->tm.tm_min);
@@ -1608,6 +1646,6 @@ time_hour(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (!tobj->as.bits.tm_got) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
     return INT2FIX(tobj->tm.tm_hour);
@@ -1632,6 +1670,6 @@ time_mday(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (!tobj->as.bits.tm_got) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
     return INT2FIX(tobj->tm.tm_mday);
@@ -1656,6 +1694,6 @@ time_mon(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (!tobj->as.bits.tm_got) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
     return INT2FIX(tobj->tm.tm_mon+1);
@@ -1678,6 +1716,6 @@ time_year(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (!tobj->as.bits.tm_got) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
     return LONG2NUM((long)tobj->tm.tm_year+1900);
@@ -1708,6 +1746,6 @@ time_wday(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (!tobj->as.bits.tm_got) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
     return INT2FIX(tobj->tm.tm_wday);
@@ -1717,6 +1755,6 @@ time_wday(VALUE time)
     struct time_object *tobj;\
     GetTimeval(time, tobj);\
-    if (tobj->tm_got == 0) {\
-	time_get_tm(time, tobj->gmt);\
+    if (!tobj->as.bits.tm_got) {\
+	time_get_tm(time, tobj->as.bits.gmt);\
     }\
     return (tobj->tm.tm_wday == (n)) ? Qtrue : Qfalse;\
@@ -1851,6 +1889,6 @@ time_yday(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (!tobj->as.bits.tm_got) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
     return INT2FIX(tobj->tm.tm_yday+1);
@@ -1888,6 +1926,6 @@ time_isdst(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (!tobj->as.bits.tm_got) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
     return tobj->tm.tm_isdst?Qtrue:Qfalse;
@@ -1917,9 +1955,9 @@ time_zone(VALUE time)
     
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (!tobj->as.bits.tm_got) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
 
-    if (tobj->gmt == 1) {
+    if (tobj->as.bits.gmt) {
 	return rb_str_new2("UTC");
     }
@@ -1930,5 +1968,5 @@ time_zone(VALUE time)
 #else
     len = rb_strftime(buf, sizeof(buf), "%Z",
-		      &tobj->tm, &tobj->ts, tobj->gmt);
+		      &tobj->tm, &tobj->ts, tobj->as.bits.gmt);
     return rb_str_new(buf, len);
 #endif
@@ -1956,9 +1994,9 @@ time_utc_offset(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (!tobj->as.bits.tm_got) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
 
-    if (tobj->gmt == 1) {
+    if (tobj->as.bits.gmt) {
 	return INT2FIX(0);
     }
@@ -1972,4 +2010,5 @@ time_utc_offset(VALUE time)
 	IF_HAVE_GMTIME_R(struct tm result);
 	l = &tobj->tm;
+	get_timespec(tobj);
 	t = tobj->ts.tv_sec;
 	u = GMTIME(&t, result);
@@ -2013,6 +2052,6 @@ time_to_a(VALUE time)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (!tobj->as.bits.tm_got) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
     return rb_ary_new3(10,
@@ -2119,6 +2158,6 @@ time_strftime(VALUE time, VALUE format)
 
     GetTimeval(time, tobj);
-    if (tobj->tm_got == 0) {
-	time_get_tm(time, tobj->gmt);
+    if (!tobj->as.bits.tm_got) {
+	time_get_tm(time, tobj->as.bits.gmt);
     }
     StringValue(format);
@@ -2138,5 +2177,5 @@ time_strftime(VALUE time, VALUE format)
 	str = rb_str_new(0, 0);
 	while (p < pe) {
-	    len = rb_strftime_alloc(&buf, p, &tobj->tm, &tobj->ts, tobj->gmt);
+	    len = rb_strftime_alloc(&buf, p, &tobj->tm, &tobj->ts, tobj->as.bits.gmt);
 	    rb_str_cat(str, buf, len);
 	    p += strlen(p);
@@ -2152,5 +2191,5 @@ time_strftime(VALUE time, VALUE format)
     else {
 	len = rb_strftime_alloc(&buf, RSTRING_PTR(format),
-			       	&tobj->tm, &tobj->ts, tobj->gmt);
+			       	&tobj->tm, &tobj->ts, tobj->as.bits.gmt);
     }
     str = rb_str_new(buf, len);
@@ -2174,4 +2213,5 @@ time_mdump(VALUE time)
     int nsec;
     int i;
+    int gmt;
     VALUE str;
     IF_HAVE_GMTIME_R(struct tm result);
@@ -2179,12 +2219,18 @@ time_mdump(VALUE time)
     GetTimeval(time, tobj);
 
-    t = tobj->ts.tv_sec;
-    tm = GMTIME(&t, result);
+    if (tobj->as.bits.tm_got) {
+	tm = &tobj->tm;
+    }
+    else {
+	t = tobj->ts.tv_sec;
+	tm = GMTIME(&t, result);
+    }
 
     if ((tm->tm_year & 0xffff) != tm->tm_year)
         rb_raise(rb_eArgError, "year too big to marshal: %ld", (long)tm->tm_year);
 
+    gmt = tobj->as.bits.gmt;
     p = 0x1UL        << 31 | /*  1 */
-	tobj->gmt    << 30 | /*  1 */
+	gmt          << 30 | /*  1 */
 	tm->tm_year  << 14 | /* 16 */
 	tm->tm_mon   << 10 | /*  4 */
@@ -2286,9 +2332,15 @@ time_mload(VALUE time, VALUE str)
     }
 
+    GetTimeval(time, tobj);
     if ((p & (1UL<<31)) == 0) {
-        gmt = 0;
 	sec = p;
 	usec = s;
         nsec = usec * 1000;
+	time_overflow_p(&sec, &nsec);
+	tobj->as.bits.tm_got = 0;
+	tobj->as.bits.ts_got = 1;
+	tobj->as.bits.gmt = 0;
+	tobj->ts.tv_sec = sec;
+	tobj->ts.tv_nsec = nsec;
     }
     else {
@@ -2303,5 +2355,4 @@ time_mload(VALUE time, VALUE str)
 	tm.tm_isdst = 0;
 
-	sec = make_time_t(&tm, Qtrue);
 	usec = (long)(s & 0xfffff);
         nsec = usec * 1000;
@@ -2323,14 +2374,12 @@ time_mload(VALUE time, VALUE str)
                 nsec += digit;
             }
-end_submicro: ;
         }
+      end_submicro:
+	tobj->as.bits.tm_got = 1;
+	tobj->as.bits.ts_got = 1;
+	tobj->as.bits.gmt = gmt;
+	tobj->tm = tm;
+	tobj->ts.tv_nsec = nsec;
     }
-    time_overflow_p(&sec, &nsec);
-
-    GetTimeval(time, tobj);
-    tobj->tm_got = 0;
-    tobj->gmt = gmt;
-    tobj->ts.tv_sec = sec;
-    tobj->ts.tv_nsec = nsec;
 
     return time;


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread