--- time.c.orig	Tue Feb 14 14:03:12 2006
+++ time.c	Sun Feb 26 16:32:19 2006
@@ -33,4 +33,26 @@ struct time_object {
     Data_Get_Struct(obj, struct time_object, tobj)
 
+#if defined(_WIN32) && SIZEOF_TIME_T == SIZEOF_LONG_LONG
+ #define TO_TIMET(v) ((time_t)(v & 0xffffffff))
+#else
+ #define TO_TIMET(v) v
+#endif
+
+#if SIZEOF_TIME_T == SIZEOF_LONG
+typedef unsigned long unsigned_time_t;
+#define TIMET2NUM(x) LONG2NUM(x)
+#define NUM2TIMET(x) NUM2LONG(x)
+#elif SIZEOF_TIME_T == SIZEOF_INT
+typedef unsigned int unsigned_time_t;
+#define TIMET2NUM(x) INT2NUM(x)
+#define NUM2TIMET(x) NUM2INT(x)
+#elif SIZEOF_TIME_T == SIZEOF_LONG_LONG
+typedef unsigned LONG_LONG unsigned_time_t;
+#define TIMET2NUM(x) LL2NUM(x)
+#define NUM2TIMET(x) NUM2LL(x)
+#else
+# error cannot find integer type which size is same as time_t.
+#endif
+
 static void time_free _((void *));
 
@@ -115,5 +137,4 @@ time_overflow_p(secp, usecp)
 {
     time_t tmp, sec = *secp, usec = *usecp;
-
     if (usec >= 1000000) {      /* usec positive overflow */
         tmp = sec + usec / 1000000;
@@ -191,5 +212,5 @@ time_timeval(time, interval)
             d = modf(RFLOAT(time)->value, &f);
             t.tv_sec = (time_t)f;
-            if (f != t.tv_sec) {
+            if (f != TO_TIMET(t.tv_sec)) {
                 rb_raise(rb_eRangeError, "%f out of Time range", RFLOAT(time)->value);
             }
@@ -199,5 +220,5 @@ time_timeval(time, interval)
 
       case T_BIGNUM:
-        t.tv_sec = NUM2LONG(time);
+        t.tv_sec = NUM2TIMET(time);
         if (interval && t.tv_sec < 0)
             rb_raise(rb_eArgError, "%s must be positive", tstr);
@@ -260,11 +281,11 @@ time_s_at(argc, argv, klass)
 
     if (rb_scan_args(argc, argv, "11", &time, &t) == 2) {
-        tv.tv_sec = NUM2LONG(time);
-        tv.tv_usec = NUM2LONG(t);
+        tv.tv_sec = NUM2TIMET(time);
+        tv.tv_usec = NUM2TIMET(t);
     }
     else {
         tv = rb_time_timeval(time);
     }
-    t = time_new_internal(klass, tv.tv_sec, tv.tv_usec);
+    t = time_new_internal(klass, TO_TIMET(tv.tv_sec), TO_TIMET(tv.tv_usec));
     if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) {
         struct time_object *tobj, *tobj2;
@@ -487,14 +508,4 @@ tmcmp(a, b)
 }
 
-#if SIZEOF_TIME_T == SIZEOF_LONG
-typedef unsigned long unsigned_time_t;
-#elif SIZEOF_TIME_T == SIZEOF_INT
-typedef unsigned int unsigned_time_t;
-#elif SIZEOF_TIME_T == SIZEOF_LONG_LONG
-typedef unsigned LONG_LONG unsigned_time_t;
-#else
-# error cannot find integer type which size is same as time_t.
-#endif
-
 static time_t
 search_time_t(tptr, utc_p)
@@ -884,5 +895,5 @@ time_to_i(time)
 
     GetTimeval(time, tobj);
-    return LONG2NUM(tobj->tv.tv_sec);
+    return TIMET2NUM(TO_TIMET(tobj->tv.tv_sec));
 }
 
@@ -906,5 +917,5 @@ time_to_f(time)
 
     GetTimeval(time, tobj);
-    return rb_float_new((double)tobj->tv.tv_sec+(double)tobj->tv.tv_usec/1e6);
+    return rb_float_new((double)TO_TIMET(tobj->tv.tv_sec)+(double)TO_TIMET(tobj->tv.tv_usec)/1e6);
 }
 
@@ -928,5 +939,5 @@ time_usec(time)
 
     GetTimeval(time, tobj);
-    return LONG2NUM(tobj->tv.tv_usec);
+    return TIMET2NUM(TO_TIMET(tobj->tv.tv_usec));
 }
 
@@ -958,8 +969,8 @@ time_cmp(time1, time2)
         if (tobj1->tv.tv_sec == tobj2->tv.tv_sec) {
             if (tobj1->tv.tv_usec == tobj2->tv.tv_usec) return INT2FIX(0);
-            if (tobj1->tv.tv_usec > tobj2->tv.tv_usec) return INT2FIX(1);
+            if (TO_TIMET(tobj1->tv.tv_usec) > TO_TIMET(tobj2->tv.tv_usec)) return INT2FIX(1);
             return INT2FIX(-1);
         }
-        if (tobj1->tv.tv_sec > tobj2->tv.tv_sec) return INT2FIX(1);
+        if (TO_TIMET(tobj1->tv.tv_sec) > TO_TIMET(tobj2->tv.tv_sec)) return INT2FIX(1);
         return INT2FIX(-1);
     }
@@ -1099,5 +1110,5 @@ time_localtime(time)
         time_modify(time);
     }
-    t = tobj->tv.tv_sec;
+    t = TO_TIMET(tobj->tv.tv_sec);
     tm_tmp = localtime(&t);
     if (!tm_tmp)
@@ -1143,5 +1154,5 @@ time_gmtime(time)
         time_modify(time);
     }
-    t = tobj->tv.tv_sec;
+    t = TO_TIMET(tobj->tv.tv_sec);
     tm_tmp = gmtime(&t);
     if (!tm_tmp)
@@ -1290,13 +1301,13 @@ time_add(tobj, offset, sign)
 
     if (sign < 0) {
-        sec = tobj->tv.tv_sec - sec_off;
-        usec = tobj->tv.tv_usec - usec_off;
-        if (sec > tobj->tv.tv_sec)
+        sec = TO_TIMET(tobj->tv.tv_sec) - sec_off;
+        usec = TO_TIMET(tobj->tv.tv_usec) - usec_off;
+        if (sec > TO_TIMET(tobj->tv.tv_sec))
             rb_raise(rb_eRangeError, "time - %f out of Time range", v);
     }
     else {
-        sec = tobj->tv.tv_sec + sec_off;
-        usec = tobj->tv.tv_usec + usec_off;
-        if (sec < tobj->tv.tv_sec)
+        sec = TO_TIMET(tobj->tv.tv_sec) + sec_off;
+        usec = TO_TIMET(tobj->tv.tv_usec) + usec_off;
+        if (sec < TO_TIMET(tobj->tv.tv_sec))
             rb_raise(rb_eRangeError, "time + %f out of Time range", v);
     }
@@ -1360,6 +1371,6 @@ time_minus(time1, time2)
 
         GetTimeval(time2, tobj2);
-        f = (double)tobj->tv.tv_sec - (double)tobj2->tv.tv_sec;
-        f += ((double)tobj->tv.tv_usec - (double)tobj2->tv.tv_usec)*1e-6;
+        f = (double)TO_TIMET(tobj->tv.tv_sec) - (double)TO_TIMET(tobj2->tv.tv_sec);
+        f += ((double)TO_TIMET(tobj->tv.tv_usec) - (double)TO_TIMET(tobj2->tv.tv_usec))*1e-6;
         /* XXX: should check float overflow on 64bit time_t platforms */
 
@@ -1383,5 +1394,5 @@ time_succ(time)
 
     GetTimeval(time, tobj);
-    return rb_time_new(tobj->tv.tv_sec + 1, tobj->tv.tv_usec);
+    return rb_time_new(TO_TIMET(tobj->tv.tv_sec) + 1, tobj->tv.tv_usec);
 }
 
@@ -1683,5 +1694,5 @@ time_utc_offset(time)
         long off;
         l = &tobj->tm;
-        t = tobj->tv.tv_sec;
+        t = TO_TIMET(tobj->tv.tv_sec);
         u = gmtime(&t);
         if (!u)
@@ -1894,5 +1905,5 @@ time_mdump(time)
     GetTimeval(time, tobj);
 
-    t = tobj->tv.tv_sec;
+    t = TO_TIMET(tobj->tv.tv_sec);
     tm = gmtime(&t);
 
@@ -1907,5 +1918,5 @@ time_mdump(time)
     s = tm->tm_min   << 26 | /*  6 */
         tm->tm_sec   << 20 | /*  6 */
-        tobj->tv.tv_usec;    /* 20 */
+        (tobj->tv.tv_usec & 0xfffff);    /* 20 */
 
     for (i=0; i<4; i++) {
