Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

* timev.h (TIME_SCALE): defined as 1000000000.

  (struct vtm): subsec is replaced by subsecx.
  subsec * TIME_SCALE == subsecx.

* time.c: avoid rational in most cases.
  (struct time_object): timev is replaced by timexv.
  timev * TIME_SCALE == timexv.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24707 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information...
commit 8b32a1de29b09e4bbd9671db7172dac245611105 1 parent 4a9bca2
akr akr authored

Showing 3 changed files with 177 additions and 146 deletions. Show diff stats Hide diff stats

  1. +10 0 ChangeLog
  2. +164 145 time.c
  3. +3 1 timev.h
10 ChangeLog
... ... @@ -1,3 +1,13 @@
  1 +Sun Aug 30 03:59:43 2009 Tanaka Akira <akr@fsij.org>
  2 +
  3 + * timev.h (TIME_SCALE): defined as 1000000000.
  4 + (struct vtm): subsec is replaced by subsecx.
  5 + subsec * TIME_SCALE == subsecx.
  6 +
  7 + * time.c: avoid rational in most cases.
  8 + (struct time_object): timev is replaced by timexv.
  9 + timev * TIME_SCALE == timexv.
  10 +
1 11 Sun Aug 30 03:17:25 2009 Tanaka Akira <akr@fsij.org>
2 12
3 13 * time.c (init_leap_second_info): use TIMET_MAX.
309 time.c
@@ -66,7 +66,7 @@ static int tmcmp(struct tm *a, struct tm *b);
66 66 static int vtmcmp(struct vtm *a, struct vtm *b);
67 67 static const char *find_time_t(struct tm *tptr, int utc_p, time_t *tp);
68 68
69   -static struct vtm *localtimev(VALUE timev, struct vtm *result);
  69 +static struct vtm *localtimexv(VALUE timexv, struct vtm *result);
70 70
71 71 static int leap_year_p(long y);
72 72 #define leap_year_v_p(y) leap_year_p(NUM2LONG(mod(v, INT2FIX(400))))
@@ -133,6 +133,8 @@ quo(VALUE x, VALUE y)
133 133 return ret;
134 134 }
135 135
  136 +#define mulquo(x,y,z) ((y == z) ? x : quo(mul(x,y),z))
  137 +
136 138 static void
137 139 divmodv(VALUE n, VALUE d, VALUE *q, VALUE *r)
138 140 {
@@ -180,6 +182,18 @@ num_exact(VALUE v)
180 182 return v;
181 183 }
182 184
  185 +static VALUE
  186 +rb_time_magnify(VALUE v)
  187 +{
  188 + return mul(v, INT2FIX(TIME_SCALE));
  189 +}
  190 +
  191 +static VALUE
  192 +rb_time_unmagnify(VALUE v)
  193 +{
  194 + return quo(v, INT2FIX(TIME_SCALE));
  195 +}
  196 +
183 197 static const int common_year_yday_offset[] = {
184 198 -1,
185 199 -1 + 31,
@@ -219,7 +233,7 @@ static const int leap_year_days_in_month[] = {
219 233 };
220 234
221 235 static VALUE
222   -timegmv_noleapsecond(struct vtm *vtm)
  236 +timegmxv_noleapsecond(struct vtm *vtm)
223 237 {
224 238 VALUE year1900;
225 239 VALUE q400, r400;
@@ -255,7 +269,7 @@ timegmv_noleapsecond(struct vtm *vtm)
255 269 ret = add(ret, mul(LONG2NUM(days_in400), INT2FIX(86400)));
256 270 ret = add(ret, mul(q400, INT2FIX(97*86400)));
257 271 ret = add(ret, mul(year1900, INT2FIX(365*86400)));
258   - ret = add(ret, vtm->subsec);
  272 + ret = add(rb_time_magnify(ret), vtm->subsecx);
259 273
260 274 return ret;
261 275 }
@@ -282,16 +296,17 @@ zone_str(const char *s)
282 296 }
283 297
284 298 static void
285   -gmtimev_noleapsecond(VALUE timev, struct vtm *vtm)
  299 +gmtimexv_noleapsecond(VALUE timexv, struct vtm *vtm)
286 300 {
287 301 VALUE v;
288 302 int i, n, x, y;
289 303 const int *yday_offset;
290 304 int wday;
  305 + VALUE timev;
291 306
292 307 vtm->isdst = 0;
293 308
294   - divmodv(timev, INT2FIX(1), &timev, &vtm->subsec);
  309 + divmodv(timexv, INT2FIX(TIME_SCALE), &timev, &vtm->subsecx);
295 310 divmodv(timev, INT2FIX(86400), &timev, &v);
296 311
297 312 wday = NUM2INT(mod(timev, INT2FIX(7)));
@@ -521,7 +536,7 @@ init_leap_second_info()
521 536 time_t now;
522 537 struct tm *tm, result;
523 538 struct vtm vtm;
524   - VALUE timev;
  539 + VALUE timexv;
525 540 now = time(NULL);
526 541 gmtime(&now);
527 542 tm = gmtime_with_leapsecond(&now, &result);
@@ -541,19 +556,19 @@ init_leap_second_info()
541 556 vtm.hour = result.tm_hour;
542 557 vtm.min = result.tm_min;
543 558 vtm.sec = result.tm_sec;
544   - vtm.subsec = INT2FIX(0);
  559 + vtm.subsecx = INT2FIX(0);
545 560 vtm.utc_offset = INT2FIX(0);
546 561
547   - timev = timegmv_noleapsecond(&vtm);
  562 + timexv = timegmxv_noleapsecond(&vtm);
548 563
549   - number_of_leap_seconds_known = NUM2INT(sub(TIMET2NUM(known_leap_seconds_limit), timev));
  564 + number_of_leap_seconds_known = NUM2INT(sub(TIMET2NUM(known_leap_seconds_limit), rb_time_unmagnify(timexv)));
550 565 }
551 566 }
552 567
553 568 static VALUE
554   -timegmv(struct vtm *vtm)
  569 +timegmxv(struct vtm *vtm)
555 570 {
556   - VALUE timev;
  571 + VALUE timexv;
557 572 struct tm tm;
558 573 time_t t;
559 574 const char *errmsg;
@@ -561,14 +576,14 @@ timegmv(struct vtm *vtm)
561 576 /* The first leap second is 1972-06-30 23:59:60 UTC.
562 577 * No leap seconds before. */
563 578 if (RTEST(gt(INT2FIX(1972), vtm->year)))
564   - return timegmv_noleapsecond(vtm);
  579 + return timegmxv_noleapsecond(vtm);
565 580
566 581 init_leap_second_info();
567 582
568   - timev = timegmv_noleapsecond(vtm);
  583 + timexv = timegmxv_noleapsecond(vtm);
569 584
570   - if (RTEST(lt(TIMET2NUM(known_leap_seconds_limit), timev))) {
571   - return add(timev, INT2NUM(number_of_leap_seconds_known));
  585 + if (RTEST(lt(rb_time_magnify(TIMET2NUM(known_leap_seconds_limit)), timexv))) {
  586 + return add(timexv, rb_time_magnify(INT2NUM(number_of_leap_seconds_known)));
572 587 }
573 588
574 589 tm.tm_year = NUM2LONG(vtm->year) - 1900;
@@ -582,30 +597,31 @@ timegmv(struct vtm *vtm)
582 597 errmsg = find_time_t(&tm, 1, &t);
583 598 if (errmsg)
584 599 rb_raise(rb_eArgError, "%s", errmsg);
585   - return add(TIMET2NUM(t), vtm->subsec);
  600 + return add(rb_time_magnify(TIMET2NUM(t)), vtm->subsecx);
586 601 }
587 602
588 603 static struct vtm *
589   -gmtimev(VALUE timev, struct vtm *result)
  604 +gmtimexv(VALUE timexv, struct vtm *result)
590 605 {
591 606 time_t t;
592 607 struct tm tm;
593   - VALUE subsec;
  608 + VALUE subsecx;
  609 + VALUE timev;
594 610
595   - if (RTEST(lt(timev, INT2FIX(0)))) {
596   - gmtimev_noleapsecond(timev, result);
  611 + if (RTEST(lt(timexv, INT2FIX(0)))) {
  612 + gmtimexv_noleapsecond(timexv, result);
597 613 return result;
598 614 }
599 615
600 616 init_leap_second_info();
601 617
602   - if (RTEST(lt(LONG2NUM(known_leap_seconds_limit), timev))) {
603   - timev = sub(timev, INT2NUM(number_of_leap_seconds_known));
604   - gmtimev_noleapsecond(timev, result);
  618 + if (RTEST(lt(rb_time_magnify(LONG2NUM(known_leap_seconds_limit)), timexv))) {
  619 + timexv = sub(timexv, rb_time_magnify(INT2NUM(number_of_leap_seconds_known)));
  620 + gmtimexv_noleapsecond(timexv, result);
605 621 return result;
606 622 }
607 623
608   - divmodv(timev, INT2FIX(1), &timev, &subsec);
  624 + divmodv(timexv, INT2FIX(TIME_SCALE), &timev, &subsecx);
609 625
610 626 t = NUM2TIMET(timev);
611 627 if (!gmtime_with_leapsecond(&t, &tm))
@@ -617,7 +633,7 @@ gmtimev(VALUE timev, struct vtm *result)
617 633 result->hour = tm.tm_hour;
618 634 result->min = tm.tm_min;
619 635 result->sec = tm.tm_sec;
620   - result->subsec = subsec;
  636 + result->subsecx = subsecx;
621 637 result->utc_offset = INT2FIX(0);
622 638 result->wday = tm.tm_wday;
623 639 result->yday = tm.tm_yday+1;
@@ -760,7 +776,7 @@ guess_local_offset(struct vtm *vtm_utc)
760 776 else
761 777 vtm2.year = INT2FIX(compat_common_month_table[vtm_utc->mon-1][wday]);
762 778
763   - timev = timegmv(&vtm2);
  779 + timev = rb_time_unmagnify(timegmxv(&vtm2));
764 780 t = NUM2TIMET(timev);
765 781 if (localtime_with_gmtoff(&t, &tm, &gmtoff))
766 782 return LONG2FIX(gmtoff);
@@ -796,12 +812,12 @@ small_vtm_sub(struct vtm *vtm1, struct vtm *vtm2)
796 812 }
797 813
798 814 static VALUE
799   -timelocalv(struct vtm *vtm)
  815 +timelocalxv(struct vtm *vtm)
800 816 {
801 817 time_t t;
802 818 struct tm tm;
803 819 VALUE v;
804   - VALUE timev1, timev2;
  820 + VALUE timexv1, timexv2;
805 821 struct vtm vtm1, vtm2;
806 822 int n;
807 823
@@ -827,54 +843,54 @@ timelocalv(struct vtm *vtm)
827 843
828 844 if (find_time_t(&tm, 0, &t))
829 845 goto no_localtime;
830   - return add(TIMET2NUM(t), vtm->subsec);
  846 + return add(rb_time_magnify(TIMET2NUM(t)), vtm->subsecx);
831 847
832 848 no_localtime:
833   - timev1 = timegmv(vtm);
  849 + timexv1 = timegmxv(vtm);
834 850
835   - if (!localtimev(timev1, &vtm1))
836   - rb_raise(rb_eArgError, "localtimev error");
  851 + if (!localtimexv(timexv1, &vtm1))
  852 + rb_raise(rb_eArgError, "localtimexv error");
837 853
838 854 n = vtmcmp(vtm, &vtm1);
839 855 if (n == 0) {
840   - timev1 = sub(timev1, INT2FIX(12*3600));
841   - if (!localtimev(timev1, &vtm1))
842   - rb_raise(rb_eArgError, "localtimev error");
  856 + timexv1 = sub(timexv1, rb_time_magnify(INT2FIX(12*3600)));
  857 + if (!localtimexv(timexv1, &vtm1))
  858 + rb_raise(rb_eArgError, "localtimexv error");
843 859 n = 1;
844 860 }
845 861
846 862 if (n < 0) {
847   - timev2 = timev1;
  863 + timexv2 = timexv1;
848 864 vtm2 = vtm1;
849   - timev1 = sub(timev1, INT2FIX(24*3600));
850   - if (!localtimev(timev1, &vtm1))
851   - rb_raise(rb_eArgError, "localtimev error");
  865 + timexv1 = sub(timexv1, rb_time_magnify(INT2FIX(24*3600)));
  866 + if (!localtimexv(timexv1, &vtm1))
  867 + rb_raise(rb_eArgError, "localtimexv error");
852 868 }
853 869 else {
854   - timev2 = add(timev1, INT2FIX(24*3600));
855   - if (!localtimev(timev2, &vtm2))
856   - rb_raise(rb_eArgError, "localtimev error");
  870 + timexv2 = add(timexv1, rb_time_magnify(INT2FIX(24*3600)));
  871 + if (!localtimexv(timexv2, &vtm2))
  872 + rb_raise(rb_eArgError, "localtimexv error");
857 873 }
858   - timev1 = add(timev1, small_vtm_sub(vtm, &vtm1));
859   - timev2 = add(timev2, small_vtm_sub(vtm, &vtm2));
  874 + timexv1 = add(timexv1, rb_time_magnify(small_vtm_sub(vtm, &vtm1)));
  875 + timexv2 = add(timexv2, rb_time_magnify(small_vtm_sub(vtm, &vtm2)));
860 876
861   - if (eq(timev1, timev2))
862   - return timev1;
  877 + if (eq(timexv1, timexv2))
  878 + return timexv1;
863 879
864   - if (!localtimev(timev1, &vtm1))
865   - rb_raise(rb_eArgError, "localtimev error");
  880 + if (!localtimexv(timexv1, &vtm1))
  881 + rb_raise(rb_eArgError, "localtimexv error");
866 882 if (vtm->hour != vtm1.hour || vtm->min != vtm1.min || vtm->sec != vtm1.sec)
867   - return timev2;
  883 + return timexv2;
868 884
869   - if (!localtimev(timev2, &vtm2))
870   - rb_raise(rb_eArgError, "localtimev error");
  885 + if (!localtimexv(timexv2, &vtm2))
  886 + rb_raise(rb_eArgError, "localtimexv error");
871 887 if (vtm->hour != vtm2.hour || vtm->min != vtm2.min || vtm->sec != vtm2.sec)
872   - return timev1;
  888 + return timexv1;
873 889
874 890 if (vtm->isdst)
875   - return lt(vtm1.utc_offset, vtm2.utc_offset) ? timev2 : timev1;
  891 + return lt(vtm1.utc_offset, vtm2.utc_offset) ? timexv2 : timexv1;
876 892 else
877   - return lt(vtm1.utc_offset, vtm2.utc_offset) ? timev1 : timev2;
  893 + return lt(vtm1.utc_offset, vtm2.utc_offset) ? timexv1 : timexv2;
878 894 }
879 895
880 896 static struct tm *
@@ -913,10 +929,10 @@ localtime_with_gmtoff(const time_t *t, struct tm *result, long *gmtoff)
913 929 }
914 930
915 931 static struct vtm *
916   -localtimev(VALUE timev, struct vtm *result)
  932 +localtimexv(VALUE timexv, struct vtm *result)
917 933 {
918   - VALUE subsec, offset;
919   - divmodv(timev, INT2FIX(1), &timev, &subsec);
  934 + VALUE timev, subsecx, offset;
  935 + divmodv(timexv, INT2FIX(TIME_SCALE), &timev, &subsecx);
920 936
921 937 if (le(TIMET2NUM(TIMET_MIN), timev) &&
922 938 le(timev, TIMET2NUM(TIMET_MAX))) {
@@ -932,7 +948,7 @@ localtimev(VALUE timev, struct vtm *result)
932 948 result->hour = tm.tm_hour;
933 949 result->min = tm.tm_min;
934 950 result->sec = tm.tm_sec;
935   - result->subsec = subsec;
  951 + result->subsecx = subsecx;
936 952 result->wday = tm.tm_wday;
937 953 result->yday = tm.tm_yday+1;
938 954 result->isdst = tm.tm_isdst;
@@ -954,12 +970,12 @@ localtimev(VALUE timev, struct vtm *result)
954 970 }
955 971 }
956 972
957   - if (!gmtimev(timev, result))
  973 + if (!gmtimexv(timexv, result))
958 974 return NULL;
959 975
960 976 offset = guess_local_offset(result);
961 977
962   - if (!gmtimev(add(timev, offset), result))
  978 + if (!gmtimexv(add(timexv, rb_time_magnify(offset)), result))
963 979 return NULL;
964 980
965 981 result->utc_offset = offset;
@@ -968,7 +984,7 @@ localtimev(VALUE timev, struct vtm *result)
968 984 }
969 985
970 986 struct time_object {
971   - VALUE timev;
  987 + VALUE timexv;
972 988 struct vtm vtm;
973 989 int gmt;
974 990 int tm_got;
@@ -1004,9 +1020,9 @@ time_mark(void *ptr)
1004 1020 {
1005 1021 struct time_object *tobj = ptr;
1006 1022 if (!tobj) return;
1007   - rb_gc_mark(tobj->timev);
  1023 + rb_gc_mark(tobj->timexv);
1008 1024 rb_gc_mark(tobj->vtm.year);
1009   - rb_gc_mark(tobj->vtm.subsec);
  1025 + rb_gc_mark(tobj->vtm.subsecx);
1010 1026 rb_gc_mark(tobj->vtm.utc_offset);
1011 1027 }
1012 1028
@@ -1024,7 +1040,7 @@ time_s_alloc(VALUE klass)
1024 1040
1025 1041 obj = Data_Make_Struct(klass, struct time_object, time_mark, time_free, tobj);
1026 1042 tobj->tm_got=0;
1027   - tobj->timev = INT2FIX(0);
  1043 + tobj->timexv = INT2FIX(0);
1028 1044
1029 1045 return obj;
1030 1046 }
@@ -1038,27 +1054,27 @@ time_modify(VALUE time)
1038 1054 }
1039 1055
1040 1056 static VALUE
1041   -timespec2timev(struct timespec *ts)
  1057 +timespec2timexv(struct timespec *ts)
1042 1058 {
1043   - VALUE timev;
  1059 + VALUE timexv;
1044 1060
1045   - timev = TIMET2NUM(ts->tv_sec);
  1061 + timexv = rb_time_magnify(TIMET2NUM(ts->tv_sec));
1046 1062 if (ts->tv_nsec)
1047   - timev = add(timev, quo(LONG2NUM(ts->tv_nsec), INT2FIX(1000000000)));
1048   - return timev;
  1063 + timexv = add(timexv, mulquo(LONG2NUM(ts->tv_nsec), INT2FIX(TIME_SCALE), INT2FIX(1000000000)));
  1064 + return timexv;
1049 1065 }
1050 1066
1051 1067 static struct timespec
1052   -timev2timespec(VALUE timev)
  1068 +timexv2timespec(VALUE timexv)
1053 1069 {
1054   - VALUE subsec;
  1070 + VALUE timev, subsecx;
1055 1071 struct timespec ts;
1056 1072
1057   - divmodv(timev, INT2FIX(1), &timev, &subsec);
  1073 + divmodv(timexv, INT2FIX(TIME_SCALE), &timev, &subsecx);
1058 1074 if (lt(timev, TIMET2NUM(TIMET_MIN)) || lt(TIMET2NUM(TIMET_MAX), timev))
1059 1075 rb_raise(rb_eArgError, "time out of system range");
1060 1076 ts.tv_sec = NUM2TIMET(timev);
1061   - ts.tv_nsec = NUM2LONG(mul(subsec, INT2FIX(1000000000)));
  1077 + ts.tv_nsec = NUM2LONG(mulquo(subsecx, INT2FIX(1000000000), INT2FIX(TIME_SCALE)));
1062 1078 return ts;
1063 1079 }
1064 1080
@@ -1078,7 +1094,7 @@ time_init_0(VALUE time)
1078 1094 time_modify(time);
1079 1095 GetTimeval(time, tobj);
1080 1096 tobj->tm_got=0;
1081   - tobj->timev = INT2FIX(0);
  1097 + tobj->timexv = INT2FIX(0);
1082 1098 #ifdef HAVE_CLOCK_GETTIME
1083 1099 if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
1084 1100 rb_sys_fail("clock_gettime");
@@ -1093,7 +1109,7 @@ time_init_0(VALUE time)
1093 1109 ts.tv_nsec = tv.tv_usec * 1000;
1094 1110 }
1095 1111 #endif
1096   - tobj->timev = timespec2timev(&ts);
  1112 + tobj->timexv = timespec2timexv(&ts);
1097 1113
1098 1114 return time;
1099 1115 }
@@ -1148,13 +1164,13 @@ vtm_add_offset(struct vtm *vtm, VALUE off)
1148 1164 day = 0;
1149 1165
1150 1166 if (!rb_equal(subsec, INT2FIX(0))) {
1151   - vtm->subsec = add(vtm->subsec, subsec);
1152   - if (lt(vtm->subsec, INT2FIX(0))) {
1153   - vtm->subsec = add(vtm->subsec, INT2FIX(1));
  1167 + vtm->subsecx = add(vtm->subsecx, rb_time_magnify(subsec));
  1168 + if (lt(vtm->subsecx, INT2FIX(0))) {
  1169 + vtm->subsecx = add(vtm->subsecx, INT2FIX(TIME_SCALE));
1154 1170 sec -= 1;
1155 1171 }
1156   - if (le(INT2FIX(1), vtm->subsec)) {
1157   - vtm->subsec = sub(vtm->subsec, INT2FIX(1));
  1172 + if (le(INT2FIX(TIME_SCALE), vtm->subsecx)) {
  1173 + vtm->subsecx = sub(vtm->subsecx, INT2FIX(TIME_SCALE));
1158 1174 sec += 1;
1159 1175 }
1160 1176 goto not_zero_sec;
@@ -1293,13 +1309,13 @@ time_init_1(int argc, VALUE *argv, VALUE time)
1293 1309 vtm.min = NIL_P(v[4]) ? 0 : obj2long(v[4]);
1294 1310
1295 1311 vtm.sec = 0;
1296   - vtm.subsec = INT2FIX(0);
  1312 + vtm.subsecx = INT2FIX(0);
1297 1313 if (!NIL_P(v[5])) {
1298 1314 VALUE sec = num_exact(v[5]);
1299 1315 VALUE subsec;
1300 1316 divmodv(sec, INT2FIX(1), &sec, &subsec);
1301 1317 vtm.sec = NUM2INT(sec);
1302   - vtm.subsec = subsec;
  1318 + vtm.subsecx = rb_time_magnify(subsec);
1303 1319 }
1304 1320
1305 1321 vtm.isdst = -1;
@@ -1319,17 +1335,17 @@ time_init_1(int argc, VALUE *argv, VALUE time)
1319 1335 time_modify(time);
1320 1336 GetTimeval(time, tobj);
1321 1337 tobj->tm_got=0;
1322   - tobj->timev = INT2FIX(0);
  1338 + tobj->timexv = INT2FIX(0);
1323 1339
1324 1340 if (!NIL_P(vtm.utc_offset)) {
1325 1341 VALUE off = vtm.utc_offset;
1326 1342 vtm_add_offset(&vtm, neg(off));
1327 1343 vtm.utc_offset = Qnil;
1328   - tobj->timev = timegmv(&vtm);
  1344 + tobj->timexv = timegmxv(&vtm);
1329 1345 return time_set_utc_offset(time, off);
1330 1346 }
1331 1347 else {
1332   - tobj->timev = timelocalv(&vtm);
  1348 + tobj->timexv = timelocalxv(&vtm);
1333 1349 return time_localtime(time);
1334 1350 }
1335 1351 }
@@ -1409,23 +1425,23 @@ time_overflow_p(time_t *secp, long *nsecp)
1409 1425 *nsecp = nsec;
1410 1426 }
1411 1427
1412   -static VALUE nsec2timev(time_t sec, long nsec)
  1428 +static VALUE nsec2timexv(time_t sec, long nsec)
1413 1429 {
1414 1430 struct timespec ts;
1415 1431 time_overflow_p(&sec, &nsec);
1416 1432 ts.tv_sec = sec;
1417 1433 ts.tv_nsec = nsec;
1418   - return timespec2timev(&ts);
  1434 + return timespec2timexv(&ts);
1419 1435 }
1420 1436
1421 1437 static VALUE
1422   -time_new_internal(VALUE klass, VALUE timev)
  1438 +time_new_internal(VALUE klass, VALUE timexv)
1423 1439 {
1424 1440 VALUE time = time_s_alloc(klass);
1425 1441 struct time_object *tobj;
1426 1442
1427 1443 GetTimeval(time, tobj);
1428   - tobj->timev = num_exact(timev);
  1444 + tobj->timexv = num_exact(timexv);
1429 1445
1430 1446 return time;
1431 1447 }
@@ -1433,19 +1449,19 @@ time_new_internal(VALUE klass, VALUE timev)
1433 1449 VALUE
1434 1450 rb_time_new(time_t sec, long usec)
1435 1451 {
1436   - return time_new_internal(rb_cTime, nsec2timev(sec, usec * 1000));
  1452 + return time_new_internal(rb_cTime, nsec2timexv(sec, usec * 1000));
1437 1453 }
1438 1454
1439 1455 VALUE
1440 1456 rb_time_nano_new(time_t sec, long nsec)
1441 1457 {
1442   - return time_new_internal(rb_cTime, nsec2timev(sec, nsec));
  1458 + return time_new_internal(rb_cTime, nsec2timexv(sec, nsec));
1443 1459 }
1444 1460
1445 1461 VALUE
1446 1462 rb_time_num_new(VALUE timev, VALUE off)
1447 1463 {
1448   - VALUE time = time_new_internal(rb_cTime, timev);
  1464 + VALUE time = time_new_internal(rb_cTime, rb_time_magnify(timev));
1449 1465
1450 1466 if (!NIL_P(off)) {
1451 1467 off = utc_offset_arg(off);
@@ -1458,13 +1474,13 @@ rb_time_num_new(VALUE timev, VALUE off)
1458 1474 }
1459 1475
1460 1476 static VALUE
1461   -time_new_timev(VALUE klass, VALUE timev)
  1477 +time_new_timexv(VALUE klass, VALUE timexv)
1462 1478 {
1463 1479 VALUE time = time_s_alloc(klass);
1464 1480 struct time_object *tobj;
1465 1481
1466 1482 GetTimeval(time, tobj);
1467   - tobj->timev = timev;
  1483 + tobj->timexv = timexv;
1468 1484
1469 1485 return time;
1470 1486 }
@@ -1568,7 +1584,7 @@ rb_time_timeval(VALUE time)
1568 1584
1569 1585 if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) {
1570 1586 GetTimeval(time, tobj);
1571   - ts = timev2timespec(tobj->timev);
  1587 + ts = timexv2timespec(tobj->timexv);
1572 1588 t.tv_sec = (TYPEOF_TIMEVAL_TV_SEC)ts.tv_sec;
1573 1589 t.tv_usec = (TYPEOF_TIMEVAL_TV_USEC)(ts.tv_nsec / 1000);
1574 1590 return t;
@@ -1584,7 +1600,7 @@ rb_time_timespec(VALUE time)
1584 1600
1585 1601 if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) {
1586 1602 GetTimeval(time, tobj);
1587   - t = timev2timespec(tobj->timev);
  1603 + t = timexv2timespec(tobj->timexv);
1588 1604 return t;
1589 1605 }
1590 1606 return time_timespec(time, Qfalse);
@@ -1629,24 +1645,24 @@ time_s_now(VALUE klass)
1629 1645 static VALUE
1630 1646 time_s_at(int argc, VALUE *argv, VALUE klass)
1631 1647 {
1632   - VALUE time, t, timev;
  1648 + VALUE time, t, timexv;
1633 1649
1634 1650 if (rb_scan_args(argc, argv, "11", &time, &t) == 2) {
1635 1651 time = num_exact(time);
1636 1652 t = num_exact(t);
1637   - timev = add(time, quo(t, INT2FIX(1000000)));
1638   - t = time_new_timev(klass, timev);
  1653 + timexv = add(rb_time_magnify(time), mulquo(t, INT2FIX(TIME_SCALE), INT2FIX(1000000)));
  1654 + t = time_new_timexv(klass, timexv);
1639 1655 }
1640 1656 else if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) {
1641 1657 struct time_object *tobj, *tobj2;
1642 1658 GetTimeval(time, tobj);
1643   - t = time_new_timev(klass, tobj->timev);
  1659 + t = time_new_timexv(klass, tobj->timexv);
1644 1660 GetTimeval(t, tobj2);
1645 1661 TIME_COPY_GMT(tobj2, tobj);
1646 1662 }
1647 1663 else {
1648   - timev = num_exact(time);
1649   - t = time_new_timev(klass, timev);
  1664 + timexv = rb_time_magnify(num_exact(time));
  1665 + t = time_new_timexv(klass, timexv);
1650 1666 }
1651 1667
1652 1668 return t;
@@ -1681,26 +1697,29 @@ obj2vint(VALUE obj)
1681 1697 }
1682 1698
1683 1699 static long
1684   -obj2subsec(VALUE obj, VALUE *subsec)
  1700 +obj2subsecx(VALUE obj, VALUE *subsecx)
1685 1701 {
  1702 + VALUE subsec;
  1703 +
1686 1704 if (TYPE(obj) == T_STRING) {
1687 1705 obj = rb_str_to_inum(obj, 10, Qfalse);
1688   - *subsec = INT2FIX(0);
  1706 + *subsecx = INT2FIX(0);
1689 1707 return NUM2LONG(obj);
1690 1708 }
1691 1709
1692   - divmodv(num_exact(obj), INT2FIX(1), &obj, subsec);
  1710 + divmodv(num_exact(obj), INT2FIX(1), &obj, &subsec);
  1711 + *subsecx = rb_time_magnify(subsec);
1693 1712 return NUM2LONG(obj);
1694 1713 }
1695 1714
1696 1715 static long
1697   -usec2subsec(VALUE obj)
  1716 +usec2subsecx(VALUE obj)
1698 1717 {
1699 1718 if (TYPE(obj) == T_STRING) {
1700 1719 obj = rb_str_to_inum(obj, 10, Qfalse);
1701 1720 }
1702 1721
1703   - return quo(num_exact(obj), INT2FIX(1000000));
  1722 + return mulquo(num_exact(obj), INT2FIX(TIME_SCALE), INT2FIX(1000000));
1704 1723 }
1705 1724
1706 1725 static int
@@ -1748,7 +1767,7 @@ validate_vtm(struct vtm *vtm)
1748 1767 || (vtm->hour == 24 && (vtm->min > 0 || vtm->sec > 0))
1749 1768 || vtm->min < 0 || vtm->min > 59
1750 1769 || vtm->sec < 0 || vtm->sec > 60
1751   - || lt(vtm->subsec, INT2FIX(0)) || ge(vtm->subsec, INT2FIX(1))
  1770 + || lt(vtm->subsecx, INT2FIX(0)) || ge(vtm->subsecx, INT2FIX(TIME_SCALE))
1752 1771 || (!NIL_P(vtm->utc_offset) && (validate_utc_offset(vtm->utc_offset), 0)))
1753 1772 rb_raise(rb_eArgError, "argument out of range");
1754 1773 }
@@ -1764,7 +1783,7 @@ time_arg(int argc, VALUE *argv, struct vtm *vtm)
1764 1783 vtm->hour = 0;
1765 1784 vtm->min = 0;
1766 1785 vtm->sec = 0;
1767   - vtm->subsec = INT2FIX(0);
  1786 + vtm->subsecx = INT2FIX(0);
1768 1787 vtm->utc_offset = Qnil;
1769 1788 vtm->wday = 0;
1770 1789 vtm->yday = 0;
@@ -1811,11 +1830,11 @@ time_arg(int argc, VALUE *argv, struct vtm *vtm)
1811 1830
1812 1831 if (!NIL_P(v[6]) && argc == 7) {
1813 1832 vtm->sec = NIL_P(v[5])?0:obj2long(v[5]);
1814   - vtm->subsec = usec2subsec(v[6]);
  1833 + vtm->subsecx = usec2subsecx(v[6]);
1815 1834 }
1816 1835 else {
1817 1836 /* when argc == 8, v[6] is timezone, but ignored */
1818   - vtm->sec = NIL_P(v[5])?0:obj2subsec(v[5], &vtm->subsec);
  1837 + vtm->sec = NIL_P(v[5])?0:obj2subsecx(v[5], &vtm->subsecx);
1819 1838 }
1820 1839
1821 1840 validate_vtm(vtm);
@@ -2139,8 +2158,8 @@ vtmcmp(struct vtm *a, struct vtm *b)
2139 2158 return a->min < b->min ? -1 : 1;
2140 2159 else if (a->sec != b->sec)
2141 2160 return a->sec < b->sec ? -1 : 1;
2142   - else if (ne(a->subsec, b->subsec))
2143   - return lt(a->subsec, b->subsec) ? -1 : 1;
  2161 + else if (ne(a->subsecx, b->subsecx))
  2162 + return lt(a->subsecx, b->subsecx) ? -1 : 1;
2144 2163 else
2145 2164 return 0;
2146 2165 }
@@ -2172,9 +2191,9 @@ time_utc_or_local(int argc, VALUE *argv, int utc_p, VALUE klass)
2172 2191
2173 2192 time_arg(argc, argv, &vtm);
2174 2193 if (utc_p)
2175   - time = time_new_timev(klass, timegmv(&vtm));
  2194 + time = time_new_timexv(klass, timegmxv(&vtm));
2176 2195 else
2177   - time = time_new_timev(klass, timelocalv(&vtm));
  2196 + time = time_new_timexv(klass, timelocalxv(&vtm));
2178 2197 if (utc_p) return time_gmtime(time);
2179 2198 return time_localtime(time);
2180 2199 }
@@ -2267,7 +2286,7 @@ time_to_i(VALUE time)
2267 2286 struct time_object *tobj;
2268 2287
2269 2288 GetTimeval(time, tobj);
2270   - return div(tobj->timev, INT2FIX(1));
  2289 + return div(tobj->timexv, INT2FIX(TIME_SCALE));
2271 2290 }
2272 2291
2273 2292 /*
@@ -2291,7 +2310,7 @@ time_to_f(VALUE time)
2291 2310 struct time_object *tobj;
2292 2311
2293 2312 GetTimeval(time, tobj);
2294   - return rb_Float(tobj->timev);
  2313 + return rb_Float(rb_time_unmagnify(tobj->timexv));
2295 2314 }
2296 2315
2297 2316 /*
@@ -2315,7 +2334,7 @@ time_to_r(VALUE time)
2315 2334 struct time_object *tobj;
2316 2335
2317 2336 GetTimeval(time, tobj);
2318   - return tobj->timev;
  2337 + return rb_time_unmagnify(tobj->timexv);
2319 2338 }
2320 2339
2321 2340 /*
@@ -2336,7 +2355,7 @@ time_usec(VALUE time)
2336 2355 struct time_object *tobj;
2337 2356
2338 2357 GetTimeval(time, tobj);
2339   - return rb_to_int(mul(mod(tobj->timev, INT2FIX(1)), INT2FIX(1000000)));
  2358 + return rb_to_int(mulquo(mod(tobj->timexv, INT2FIX(TIME_SCALE)), INT2FIX(1000000), INT2FIX(TIME_SCALE)));
2340 2359 }
2341 2360
2342 2361 /*
@@ -2362,7 +2381,7 @@ time_nsec(VALUE time)
2362 2381 struct time_object *tobj;
2363 2382
2364 2383 GetTimeval(time, tobj);
2365   - return rb_to_int(mul(mod(tobj->timev, INT2FIX(1)), INT2FIX(1000000000)));
  2384 + return rb_to_int(mulquo(mod(tobj->timexv, INT2FIX(TIME_SCALE)), INT2FIX(1000000000), INT2FIX(TIME_SCALE)));
2366 2385 }
2367 2386
2368 2387 /*
@@ -2389,7 +2408,7 @@ time_subsec(VALUE time)
2389 2408 struct time_object *tobj;
2390 2409
2391 2410 GetTimeval(time, tobj);
2392   - return mod(tobj->timev, INT2FIX(1));
  2411 + return quo(mod(tobj->timexv, INT2FIX(TIME_SCALE)), INT2FIX(TIME_SCALE));
2393 2412 }
2394 2413
2395 2414 /*
@@ -2421,7 +2440,7 @@ time_cmp(VALUE time1, VALUE time2)
2421 2440 GetTimeval(time1, tobj1);
2422 2441 if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {
2423 2442 GetTimeval(time2, tobj2);
2424   - n = rb_cmpint(cmp(tobj1->timev, tobj2->timev), tobj1->timev, tobj2->timev);
  2443 + n = rb_cmpint(cmp(tobj1->timexv, tobj2->timexv), tobj1->timexv, tobj2->timexv);
2425 2444 }
2426 2445 else {
2427 2446 VALUE cmp;
@@ -2453,7 +2472,7 @@ time_eql(VALUE time1, VALUE time2)
2453 2472 GetTimeval(time1, tobj1);
2454 2473 if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {
2455 2474 GetTimeval(time2, tobj2);
2456   - return rb_equal(tobj1->timev, tobj2->timev);
  2475 + return rb_equal(tobj1->timexv, tobj2->timexv);
2457 2476 }
2458 2477 return Qfalse;
2459 2478 }
@@ -2500,7 +2519,7 @@ time_hash(VALUE time)
2500 2519 struct time_object *tobj;
2501 2520
2502 2521 GetTimeval(time, tobj);
2503   - return rb_hash(tobj->timev);
  2522 + return rb_hash(tobj->timexv);
2504 2523 }
2505 2524
2506 2525 /* :nodoc: */
@@ -2544,7 +2563,7 @@ time_localtime(VALUE time)
2544 2563 time_modify(time);
2545 2564 }
2546 2565
2547   - if (!localtimev(tobj->timev, &vtm))
  2566 + if (!localtimexv(tobj->timexv, &vtm))
2548 2567 rb_raise(rb_eArgError, "localtime error");
2549 2568 tobj->vtm = vtm;
2550 2569
@@ -2623,7 +2642,7 @@ time_gmtime(VALUE time)
2623 2642 time_modify(time);
2624 2643 }
2625 2644
2626   - if (!gmtimev(tobj->timev, &vtm))
  2645 + if (!gmtimexv(tobj->timexv, &vtm))
2627 2646 rb_raise(rb_eArgError, "gmtime error");
2628 2647 tobj->vtm = vtm;
2629 2648
@@ -2653,7 +2672,7 @@ time_fixoff(VALUE time)
2653 2672 else
2654 2673 off = INT2FIX(0);
2655 2674
2656   - if (!gmtimev(tobj->timev, &vtm))
  2675 + if (!gmtimexv(tobj->timexv, &vtm))
2657 2676 rb_raise(rb_eArgError, "gmtime error");
2658 2677
2659 2678 tobj->vtm = vtm;
@@ -2788,9 +2807,9 @@ time_add(struct time_object *tobj, VALUE offset, int sign)
2788 2807 VALUE result;
2789 2808 offset = num_exact(offset);
2790 2809 if (sign < 0)
2791   - result = time_new_timev(rb_cTime, sub(tobj->timev, offset));
  2810 + result = time_new_timexv(rb_cTime, sub(tobj->timexv, rb_time_magnify(offset)));
2792 2811 else
2793   - result = time_new_timev(rb_cTime, add(tobj->timev, offset));
  2812 + result = time_new_timexv(rb_cTime, add(tobj->timexv, rb_time_magnify(offset)));
2794 2813 if (TIME_UTC_P(tobj)) {
2795 2814 GetTimeval(result, tobj);
2796 2815 TIME_SET_UTC(tobj);
@@ -2846,7 +2865,7 @@ time_minus(VALUE time1, VALUE time2)
2846 2865 struct time_object *tobj2;
2847 2866
2848 2867 GetTimeval(time2, tobj2);
2849   - return rb_Float(sub(tobj->timev, tobj2->timev));
  2868 + return rb_Float(rb_time_unmagnify(sub(tobj->timexv, tobj2->timexv)));
2850 2869 }
2851 2870 return time_add(tobj, time2, -1);
2852 2871 }
@@ -2868,7 +2887,7 @@ time_succ(VALUE time)
2868 2887 struct time_object *tobj2;
2869 2888
2870 2889 GetTimeval(time, tobj);
2871   - time = time_new_timev(rb_cTime, add(tobj->timev, INT2FIX(1)));
  2890 + time = time_new_timexv(rb_cTime, add(tobj->timexv, INT2FIX(TIME_SCALE)));
2872 2891 GetTimeval(time, tobj2);
2873 2892 TIME_COPY_GMT(tobj2, tobj);
2874 2893 return time;
@@ -3351,7 +3370,7 @@ strftimev(const char *fmt, VALUE time)
3351 3370
3352 3371 GetTimeval(time, tobj);
3353 3372 MAKE_TM(time, tobj);
3354   - len = rb_strftime_alloc(&buf, fmt, &tobj->vtm, tobj->timev, TIME_UTC_P(tobj));
  3373 + len = rb_strftime_alloc(&buf, fmt, &tobj->vtm, rb_time_unmagnify(tobj->timexv), TIME_UTC_P(tobj));
3355 3374 str = rb_str_new(buf, len);
3356 3375 if (buf != buffer) xfree(buf);
3357 3376 return str;
@@ -3449,7 +3468,7 @@ time_strftime(VALUE time, VALUE format)
3449 3468
3450 3469 str = rb_str_new(0, 0);
3451 3470 while (p < pe) {
3452   - len = rb_strftime_alloc(&buf, p, &tobj->vtm, tobj->timev, TIME_UTC_P(tobj));
  3471 + len = rb_strftime_alloc(&buf, p, &tobj->vtm, rb_time_unmagnify(tobj->timexv), TIME_UTC_P(tobj));
3453 3472 rb_str_cat(str, buf, len);
3454 3473 p += strlen(p);
3455 3474 if (buf != buffer) {
@@ -3463,7 +3482,7 @@ time_strftime(VALUE time, VALUE format)
3463 3482 }
3464 3483 else {
3465 3484 len = rb_strftime_alloc(&buf, RSTRING_PTR(format),
3466   - &tobj->vtm, tobj->timev, TIME_UTC_P(tobj));
  3485 + &tobj->vtm, rb_time_unmagnify(tobj->timexv), TIME_UTC_P(tobj));
3467 3486 }
3468 3487 str = rb_str_new(buf, len);
3469 3488 if (buf != buffer) xfree(buf);
@@ -3487,11 +3506,11 @@ time_mdump(VALUE time)
3487 3506 struct vtm vtm;
3488 3507 long year;
3489 3508 long usec, nsec;
3490   - VALUE subsec, subnano, v;
  3509 + VALUE subsecx, nano, subnano, v;
3491 3510
3492 3511 GetTimeval(time, tobj);
3493 3512
3494   - gmtimev(tobj->timev, &vtm);
  3513 + gmtimexv(tobj->timexv, &vtm);
3495 3514
3496 3515 if (FIXNUM_P(vtm.year)) {
3497 3516 year = FIX2LONG(vtm.year);
@@ -3502,10 +3521,10 @@ time_mdump(VALUE time)
3502 3521 rb_raise(rb_eArgError, "year too big to marshal");
3503 3522 }
3504 3523
3505   - subsec = vtm.subsec;
  3524 + subsecx = vtm.subsecx;
3506 3525
3507   - subsec = mul(subsec, INT2FIX(1000000000));
3508   - divmodv(subsec, INT2FIX(1), &v, &subnano);
  3526 + nano = mulquo(subsecx, INT2FIX(1000000000), INT2FIX(TIME_SCALE));
  3527 + divmodv(nano, INT2FIX(1), &v, &subnano);
3509 3528 nsec = FIX2LONG(v);
3510 3529 usec = nsec / 1000;
3511 3530 nsec = nsec % 1000;
@@ -3589,7 +3608,7 @@ time_mload(VALUE time, VALUE str)
3589 3608 struct vtm vtm;
3590 3609 int i, gmt;
3591 3610 long nsec;
3592   - VALUE timev, submicro, subnano;
  3611 + VALUE timexv, submicro, subnano;
3593 3612
3594 3613 time_modify(time);
3595 3614
@@ -3622,7 +3641,7 @@ time_mload(VALUE time, VALUE str)
3622 3641 sec = p;
3623 3642 usec = s;
3624 3643 nsec = usec * 1000;
3625   - timev = add(TIMET2NUM(sec), quo(LONG2FIX(usec), LONG2FIX(1000000)));
  3644 + timexv = add(rb_time_magnify(TIMET2NUM(sec)), mulquo(LONG2FIX(usec), INT2FIX(TIME_SCALE), LONG2FIX(1000000)));
3626 3645 }
3627 3646 else {
3628 3647 p &= ~(1UL<<31);
@@ -3661,18 +3680,18 @@ time_mload(VALUE time, VALUE str)
3661 3680 end_submicro: ;
3662 3681 }
3663 3682
3664   - vtm.subsec = quo(LONG2FIX(nsec), LONG2FIX(1000000000));
  3683 + vtm.subsecx = mulquo(LONG2FIX(nsec), INT2FIX(TIME_SCALE), LONG2FIX(1000000000));
3665 3684 if (subnano != Qnil) {
3666 3685 subnano = num_exact(subnano);
3667   - vtm.subsec = add(vtm.subsec, quo(subnano, LONG2FIX(1000000000)));
  3686 + vtm.subsecx = add(vtm.subsecx, mulquo(subnano, INT2FIX(TIME_SCALE), LONG2FIX(1000000000)));
3668 3687 }
3669   - timev = timegmv(&vtm);
  3688 + timexv = timegmxv(&vtm);
3670 3689 }
3671 3690
3672 3691 GetTimeval(time, tobj);
3673 3692 tobj->tm_got = 0;
3674 3693 if (gmt) TIME_SET_UTC(tobj);
3675   - tobj->timev = timev;
  3694 + tobj->timexv = timexv;
3676 3695
3677 3696 return time;
3678 3697 }
4 timev.h
@@ -8,7 +8,7 @@ struct vtm {
8 8 int hour; /* 0..23 */
9 9 int min; /* 0..59 */
10 10 int sec; /* 0..60 */
11   - VALUE subsec; /* 0 <= subsec < 1. possibly Rational. */
  11 + VALUE subsecx; /* 0 <= subsecx < TIME_SCALE. possibly Rational. */
12 12 VALUE utc_offset; /* -3600 as -01:00 for example. possibly Rational. */
13 13 int wday; /* 0:Sunday, 1:Monday, ..., 6:Saturday */
14 14 int yday; /* 1..366 */
@@ -16,4 +16,6 @@ struct vtm {
16 16 const char *zone; /* "JST", "EST", "EDT", etc. */
17 17 };
18 18
  19 +#define TIME_SCALE 1000000000
  20 +
19 21 #endif

0 comments on commit 8b32a1d

Please sign in to comment.
Something went wrong with that request. Please try again.