summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-29 19:06:29 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-29 19:06:29 +0000
commit8b32a1de29b09e4bbd9671db7172dac245611105 (patch)
treeb79ce0e8916f16fabf218546fc1af49b8049c6ea
parent4a9bca2496f66b44b9fff0377443715a03c6ddc7 (diff)
* 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
-rw-r--r--ChangeLog10
-rw-r--r--time.c309
-rw-r--r--timev.h4
3 files changed, 177 insertions, 146 deletions
diff --git a/ChangeLog b/ChangeLog
index 808c4e7d6a..33848903a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Sun Aug 30 03:59:43 2009 Tanaka Akira <akr@fsij.org>
+
+ * 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.
+
Sun Aug 30 03:17:25 2009 Tanaka Akira <akr@fsij.org>
* time.c (init_leap_second_info): use TIMET_MAX.
diff --git a/time.c b/time.c
index 599abe2b2e..e67a7bc5f7 100644
--- a/time.c
+++ b/time.c
@@ -66,7 +66,7 @@ static int tmcmp(struct tm *a, struct tm *b);
static int vtmcmp(struct vtm *a, struct vtm *b);
static const char *find_time_t(struct tm *tptr, int utc_p, time_t *tp);
-static struct vtm *localtimev(VALUE timev, struct vtm *result);
+static struct vtm *localtimexv(VALUE timexv, struct vtm *result);
static int leap_year_p(long y);
#define leap_year_v_p(y) leap_year_p(NUM2LONG(mod(v, INT2FIX(400))))
@@ -133,6 +133,8 @@ quo(VALUE x, VALUE y)
return ret;
}
+#define mulquo(x,y,z) ((y == z) ? x : quo(mul(x,y),z))
+
static void
divmodv(VALUE n, VALUE d, VALUE *q, VALUE *r)
{
@@ -180,6 +182,18 @@ num_exact(VALUE v)
return v;
}
+static VALUE
+rb_time_magnify(VALUE v)
+{
+ return mul(v, INT2FIX(TIME_SCALE));
+}
+
+static VALUE
+rb_time_unmagnify(VALUE v)
+{
+ return quo(v, INT2FIX(TIME_SCALE));
+}
+
static const int common_year_yday_offset[] = {
-1,
-1 + 31,
@@ -219,7 +233,7 @@ static const int leap_year_days_in_month[] = {
};
static VALUE
-timegmv_noleapsecond(struct vtm *vtm)
+timegmxv_noleapsecond(struct vtm *vtm)
{
VALUE year1900;
VALUE q400, r400;
@@ -255,7 +269,7 @@ timegmv_noleapsecond(struct vtm *vtm)
ret = add(ret, mul(LONG2NUM(days_in400), INT2FIX(86400)));
ret = add(ret, mul(q400, INT2FIX(97*86400)));
ret = add(ret, mul(year1900, INT2FIX(365*86400)));
- ret = add(ret, vtm->subsec);
+ ret = add(rb_time_magnify(ret), vtm->subsecx);
return ret;
}
@@ -282,16 +296,17 @@ zone_str(const char *s)
}
static void
-gmtimev_noleapsecond(VALUE timev, struct vtm *vtm)
+gmtimexv_noleapsecond(VALUE timexv, struct vtm *vtm)
{
VALUE v;
int i, n, x, y;
const int *yday_offset;
int wday;
+ VALUE timev;
vtm->isdst = 0;
- divmodv(timev, INT2FIX(1), &timev, &vtm->subsec);
+ divmodv(timexv, INT2FIX(TIME_SCALE), &timev, &vtm->subsecx);
divmodv(timev, INT2FIX(86400), &timev, &v);
wday = NUM2INT(mod(timev, INT2FIX(7)));
@@ -521,7 +536,7 @@ init_leap_second_info()
time_t now;
struct tm *tm, result;
struct vtm vtm;
- VALUE timev;
+ VALUE timexv;
now = time(NULL);
gmtime(&now);
tm = gmtime_with_leapsecond(&now, &result);
@@ -541,19 +556,19 @@ init_leap_second_info()
vtm.hour = result.tm_hour;
vtm.min = result.tm_min;
vtm.sec = result.tm_sec;
- vtm.subsec = INT2FIX(0);
+ vtm.subsecx = INT2FIX(0);
vtm.utc_offset = INT2FIX(0);
- timev = timegmv_noleapsecond(&vtm);
+ timexv = timegmxv_noleapsecond(&vtm);
- number_of_leap_seconds_known = NUM2INT(sub(TIMET2NUM(known_leap_seconds_limit), timev));
+ number_of_leap_seconds_known = NUM2INT(sub(TIMET2NUM(known_leap_seconds_limit), rb_time_unmagnify(timexv)));
}
}
static VALUE
-timegmv(struct vtm *vtm)
+timegmxv(struct vtm *vtm)
{
- VALUE timev;
+ VALUE timexv;
struct tm tm;
time_t t;
const char *errmsg;
@@ -561,14 +576,14 @@ timegmv(struct vtm *vtm)
/* The first leap second is 1972-06-30 23:59:60 UTC.
* No leap seconds before. */
if (RTEST(gt(INT2FIX(1972), vtm->year)))
- return timegmv_noleapsecond(vtm);
+ return timegmxv_noleapsecond(vtm);
init_leap_second_info();
- timev = timegmv_noleapsecond(vtm);
+ timexv = timegmxv_noleapsecond(vtm);
- if (RTEST(lt(TIMET2NUM(known_leap_seconds_limit), timev))) {
- return add(timev, INT2NUM(number_of_leap_seconds_known));
+ if (RTEST(lt(rb_time_magnify(TIMET2NUM(known_leap_seconds_limit)), timexv))) {
+ return add(timexv, rb_time_magnify(INT2NUM(number_of_leap_seconds_known)));
}
tm.tm_year = NUM2LONG(vtm->year) - 1900;
@@ -582,30 +597,31 @@ timegmv(struct vtm *vtm)
errmsg = find_time_t(&tm, 1, &t);
if (errmsg)
rb_raise(rb_eArgError, "%s", errmsg);
- return add(TIMET2NUM(t), vtm->subsec);
+ return add(rb_time_magnify(TIMET2NUM(t)), vtm->subsecx);
}
static struct vtm *
-gmtimev(VALUE timev, struct vtm *result)
+gmtimexv(VALUE timexv, struct vtm *result)
{
time_t t;
struct tm tm;
- VALUE subsec;
+ VALUE subsecx;
+ VALUE timev;
- if (RTEST(lt(timev, INT2FIX(0)))) {
- gmtimev_noleapsecond(timev, result);
+ if (RTEST(lt(timexv, INT2FIX(0)))) {
+ gmtimexv_noleapsecond(timexv, result);
return result;
}
init_leap_second_info();
- if (RTEST(lt(LONG2NUM(known_leap_seconds_limit), timev))) {
- timev = sub(timev, INT2NUM(number_of_leap_seconds_known));
- gmtimev_noleapsecond(timev, result);
+ if (RTEST(lt(rb_time_magnify(LONG2NUM(known_leap_seconds_limit)), timexv))) {
+ timexv = sub(timexv, rb_time_magnify(INT2NUM(number_of_leap_seconds_known)));
+ gmtimexv_noleapsecond(timexv, result);
return result;
}
- divmodv(timev, INT2FIX(1), &timev, &subsec);
+ divmodv(timexv, INT2FIX(TIME_SCALE), &timev, &subsecx);
t = NUM2TIMET(timev);
if (!gmtime_with_leapsecond(&t, &tm))
@@ -617,7 +633,7 @@ gmtimev(VALUE timev, struct vtm *result)
result->hour = tm.tm_hour;
result->min = tm.tm_min;
result->sec = tm.tm_sec;
- result->subsec = subsec;
+ result->subsecx = subsecx;
result->utc_offset = INT2FIX(0);
result->wday = tm.tm_wday;
result->yday = tm.tm_yday+1;
@@ -760,7 +776,7 @@ guess_local_offset(struct vtm *vtm_utc)
else
vtm2.year = INT2FIX(compat_common_month_table[vtm_utc->mon-1][wday]);
- timev = timegmv(&vtm2);
+ timev = rb_time_unmagnify(timegmxv(&vtm2));
t = NUM2TIMET(timev);
if (localtime_with_gmtoff(&t, &tm, &gmtoff))
return LONG2FIX(gmtoff);
@@ -796,12 +812,12 @@ small_vtm_sub(struct vtm *vtm1, struct vtm *vtm2)
}
static VALUE
-timelocalv(struct vtm *vtm)
+timelocalxv(struct vtm *vtm)
{
time_t t;
struct tm tm;
VALUE v;
- VALUE timev1, timev2;
+ VALUE timexv1, timexv2;
struct vtm vtm1, vtm2;
int n;
@@ -827,54 +843,54 @@ timelocalv(struct vtm *vtm)
if (find_time_t(&tm, 0, &t))
goto no_localtime;
- return add(TIMET2NUM(t), vtm->subsec);
+ return add(rb_time_magnify(TIMET2NUM(t)), vtm->subsecx);
no_localtime:
- timev1 = timegmv(vtm);
+ timexv1 = timegmxv(vtm);
- if (!localtimev(timev1, &vtm1))
- rb_raise(rb_eArgError, "localtimev error");
+ if (!localtimexv(timexv1, &vtm1))
+ rb_raise(rb_eArgError, "localtimexv error");
n = vtmcmp(vtm, &vtm1);
if (n == 0) {
- timev1 = sub(timev1, INT2FIX(12*3600));
- if (!localtimev(timev1, &vtm1))
- rb_raise(rb_eArgError, "localtimev error");
+ timexv1 = sub(timexv1, rb_time_magnify(INT2FIX(12*3600)));
+ if (!localtimexv(timexv1, &vtm1))
+ rb_raise(rb_eArgError, "localtimexv error");
n = 1;
}
if (n < 0) {
- timev2 = timev1;
+ timexv2 = timexv1;
vtm2 = vtm1;
- timev1 = sub(timev1, INT2FIX(24*3600));
- if (!localtimev(timev1, &vtm1))
- rb_raise(rb_eArgError, "localtimev error");
+ timexv1 = sub(timexv1, rb_time_magnify(INT2FIX(24*3600)));
+ if (!localtimexv(timexv1, &vtm1))
+ rb_raise(rb_eArgError, "localtimexv error");
}
else {
- timev2 = add(timev1, INT2FIX(24*3600));
- if (!localtimev(timev2, &vtm2))
- rb_raise(rb_eArgError, "localtimev error");
+ timexv2 = add(timexv1, rb_time_magnify(INT2FIX(24*3600)));
+ if (!localtimexv(timexv2, &vtm2))
+ rb_raise(rb_eArgError, "localtimexv error");
}
- timev1 = add(timev1, small_vtm_sub(vtm, &vtm1));
- timev2 = add(timev2, small_vtm_sub(vtm, &vtm2));
+ timexv1 = add(timexv1, rb_time_magnify(small_vtm_sub(vtm, &vtm1)));
+ timexv2 = add(timexv2, rb_time_magnify(small_vtm_sub(vtm, &vtm2)));
- if (eq(timev1, timev2))
- return timev1;
+ if (eq(timexv1, timexv2))
+ return timexv1;
- if (!localtimev(timev1, &vtm1))
- rb_raise(rb_eArgError, "localtimev error");
+ if (!localtimexv(timexv1, &vtm1))
+ rb_raise(rb_eArgError, "localtimexv error");
if (vtm->hour != vtm1.hour || vtm->min != vtm1.min || vtm->sec != vtm1.sec)
- return timev2;
+ return timexv2;
- if (!localtimev(timev2, &vtm2))
- rb_raise(rb_eArgError, "localtimev error");
+ if (!localtimexv(timexv2, &vtm2))
+ rb_raise(rb_eArgError, "localtimexv error");
if (vtm->hour != vtm2.hour || vtm->min != vtm2.min || vtm->sec != vtm2.sec)
- return timev1;
+ return timexv1;
if (vtm->isdst)
- return lt(vtm1.utc_offset, vtm2.utc_offset) ? timev2 : timev1;
+ return lt(vtm1.utc_offset, vtm2.utc_offset) ? timexv2 : timexv1;
else
- return lt(vtm1.utc_offset, vtm2.utc_offset) ? timev1 : timev2;
+ return lt(vtm1.utc_offset, vtm2.utc_offset) ? timexv1 : timexv2;
}
static struct tm *
@@ -913,10 +929,10 @@ localtime_with_gmtoff(const time_t *t, struct tm *result, long *gmtoff)
}
static struct vtm *
-localtimev(VALUE timev, struct vtm *result)
+localtimexv(VALUE timexv, struct vtm *result)
{
- VALUE subsec, offset;
- divmodv(timev, INT2FIX(1), &timev, &subsec);
+ VALUE timev, subsecx, offset;
+ divmodv(timexv, INT2FIX(TIME_SCALE), &timev, &subsecx);
if (le(TIMET2NUM(TIMET_MIN), timev) &&
le(timev, TIMET2NUM(TIMET_MAX))) {
@@ -932,7 +948,7 @@ localtimev(VALUE timev, struct vtm *result)
result->hour = tm.tm_hour;
result->min = tm.tm_min;
result->sec = tm.tm_sec;
- result->subsec = subsec;
+ result->subsecx = subsecx;
result->wday = tm.tm_wday;
result->yday = tm.tm_yday+1;
result->isdst = tm.tm_isdst;
@@ -954,12 +970,12 @@ localtimev(VALUE timev, struct vtm *result)
}
}
- if (!gmtimev(timev, result))
+ if (!gmtimexv(timexv, result))
return NULL;
offset = guess_local_offset(result);
- if (!gmtimev(add(timev, offset), result))
+ if (!gmtimexv(add(timexv, rb_time_magnify(offset)), result))
return NULL;
result->utc_offset = offset;
@@ -968,7 +984,7 @@ localtimev(VALUE timev, struct vtm *result)
}
struct time_object {
- VALUE timev;
+ VALUE timexv;
struct vtm vtm;
int gmt;
int tm_got;
@@ -1004,9 +1020,9 @@ time_mark(void *ptr)
{
struct time_object *tobj = ptr;
if (!tobj) return;
- rb_gc_mark(tobj->timev);
+ rb_gc_mark(tobj->timexv);
rb_gc_mark(tobj->vtm.year);
- rb_gc_mark(tobj->vtm.subsec);
+ rb_gc_mark(tobj->vtm.subsecx);
rb_gc_mark(tobj->vtm.utc_offset);
}
@@ -1024,7 +1040,7 @@ time_s_alloc(VALUE klass)
obj = Data_Make_Struct(klass, struct time_object, time_mark, time_free, tobj);
tobj->tm_got=0;
- tobj->timev = INT2FIX(0);
+ tobj->timexv = INT2FIX(0);
return obj;
}
@@ -1038,27 +1054,27 @@ time_modify(VALUE time)
}
static VALUE
-timespec2timev(struct timespec *ts)
+timespec2timexv(struct timespec *ts)
{
- VALUE timev;
+ VALUE timexv;
- timev = TIMET2NUM(ts->tv_sec);
+ timexv = rb_time_magnify(TIMET2NUM(ts->tv_sec));
if (ts->tv_nsec)
- timev = add(timev, quo(LONG2NUM(ts->tv_nsec), INT2FIX(1000000000)));
- return timev;
+ timexv = add(timexv, mulquo(LONG2NUM(ts->tv_nsec), INT2FIX(TIME_SCALE), INT2FIX(1000000000)));
+ return timexv;
}
static struct timespec
-timev2timespec(VALUE timev)
+timexv2timespec(VALUE timexv)
{
- VALUE subsec;
+ VALUE timev, subsecx;
struct timespec ts;
- divmodv(timev, INT2FIX(1), &timev, &subsec);
+ divmodv(timexv, INT2FIX(TIME_SCALE), &timev, &subsecx);
if (lt(timev, TIMET2NUM(TIMET_MIN)) || lt(TIMET2NUM(TIMET_MAX), timev))
rb_raise(rb_eArgError, "time out of system range");
ts.tv_sec = NUM2TIMET(timev);
- ts.tv_nsec = NUM2LONG(mul(subsec, INT2FIX(1000000000)));
+ ts.tv_nsec = NUM2LONG(mulquo(subsecx, INT2FIX(1000000000), INT2FIX(TIME_SCALE)));
return ts;
}
@@ -1078,7 +1094,7 @@ time_init_0(VALUE time)
time_modify(time);
GetTimeval(time, tobj);
tobj->tm_got=0;
- tobj->timev = INT2FIX(0);
+ tobj->timexv = INT2FIX(0);
#ifdef HAVE_CLOCK_GETTIME
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
rb_sys_fail("clock_gettime");
@@ -1093,7 +1109,7 @@ time_init_0(VALUE time)
ts.tv_nsec = tv.tv_usec * 1000;
}
#endif
- tobj->timev = timespec2timev(&ts);
+ tobj->timexv = timespec2timexv(&ts);
return time;
}
@@ -1148,13 +1164,13 @@ vtm_add_offset(struct vtm *vtm, VALUE off)
day = 0;
if (!rb_equal(subsec, INT2FIX(0))) {
- vtm->subsec = add(vtm->subsec, subsec);
- if (lt(vtm->subsec, INT2FIX(0))) {
- vtm->subsec = add(vtm->subsec, INT2FIX(1));
+ vtm->subsecx = add(vtm->subsecx, rb_time_magnify(subsec));
+ if (lt(vtm->subsecx, INT2FIX(0))) {
+ vtm->subsecx = add(vtm->subsecx, INT2FIX(TIME_SCALE));
sec -= 1;
}
- if (le(INT2FIX(1), vtm->subsec)) {
- vtm->subsec = sub(vtm->subsec, INT2FIX(1));
+ if (le(INT2FIX(TIME_SCALE), vtm->subsecx)) {
+ vtm->subsecx = sub(vtm->subsecx, INT2FIX(TIME_SCALE));
sec += 1;
}
goto not_zero_sec;
@@ -1293,13 +1309,13 @@ time_init_1(int argc, VALUE *argv, VALUE time)
vtm.min = NIL_P(v[4]) ? 0 : obj2long(v[4]);
vtm.sec = 0;
- vtm.subsec = INT2FIX(0);
+ vtm.subsecx = INT2FIX(0);
if (!NIL_P(v[5])) {
VALUE sec = num_exact(v[5]);
VALUE subsec;
divmodv(sec, INT2FIX(1), &sec, &subsec);
vtm.sec = NUM2INT(sec);
- vtm.subsec = subsec;
+ vtm.subsecx = rb_time_magnify(subsec);
}
vtm.isdst = -1;
@@ -1319,17 +1335,17 @@ time_init_1(int argc, VALUE *argv, VALUE time)
time_modify(time);
GetTimeval(time, tobj);
tobj->tm_got=0;
- tobj->timev = INT2FIX(0);
+ tobj->timexv = INT2FIX(0);
if (!NIL_P(vtm.utc_offset)) {
VALUE off = vtm.utc_offset;
vtm_add_offset(&vtm, neg(off));
vtm.utc_offset = Qnil;
- tobj->timev = timegmv(&vtm);
+ tobj->timexv = timegmxv(&vtm);
return time_set_utc_offset(time, off);
}
else {
- tobj->timev = timelocalv(&vtm);
+ tobj->timexv = timelocalxv(&vtm);
return time_localtime(time);
}
}
@@ -1409,23 +1425,23 @@ time_overflow_p(time_t *secp, long *nsecp)
*nsecp = nsec;
}
-static VALUE nsec2timev(time_t sec, long nsec)
+static VALUE nsec2timexv(time_t sec, long nsec)
{
struct timespec ts;
time_overflow_p(&sec, &nsec);
ts.tv_sec = sec;
ts.tv_nsec = nsec;
- return timespec2timev(&ts);
+ return timespec2timexv(&ts);
}
static VALUE
-time_new_internal(VALUE klass, VALUE timev)
+time_new_internal(VALUE klass, VALUE timexv)
{
VALUE time = time_s_alloc(klass);
struct time_object *tobj;
GetTimeval(time, tobj);
- tobj->timev = num_exact(timev);
+ tobj->timexv = num_exact(timexv);
return time;
}
@@ -1433,19 +1449,19 @@ time_new_internal(VALUE klass, VALUE timev)
VALUE
rb_time_new(time_t sec, long usec)
{
- return time_new_internal(rb_cTime, nsec2timev(sec, usec * 1000));
+ return time_new_internal(rb_cTime, nsec2timexv(sec, usec * 1000));
}
VALUE
rb_time_nano_new(time_t sec, long nsec)
{
- return time_new_internal(rb_cTime, nsec2timev(sec, nsec));
+ return time_new_internal(rb_cTime, nsec2timexv(sec, nsec));
}
VALUE
rb_time_num_new(VALUE timev, VALUE off)
{
- VALUE time = time_new_internal(rb_cTime, timev);
+ VALUE time = time_new_internal(rb_cTime, rb_time_magnify(timev));
if (!NIL_P(off)) {
off = utc_offset_arg(off);
@@ -1458,13 +1474,13 @@ rb_time_num_new(VALUE timev, VALUE off)
}
static VALUE
-time_new_timev(VALUE klass, VALUE timev)
+time_new_timexv(VALUE klass, VALUE timexv)
{
VALUE time = time_s_alloc(klass);
struct time_object *tobj;
GetTimeval(time, tobj);
- tobj->timev = timev;
+ tobj->timexv = timexv;
return time;
}
@@ -1568,7 +1584,7 @@ rb_time_timeval(VALUE time)
if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) {
GetTimeval(time, tobj);
- ts = timev2timespec(tobj->timev);
+ ts = timexv2timespec(tobj->timexv);
t.tv_sec = (TYPEOF_TIMEVAL_TV_SEC)ts.tv_sec;
t.tv_usec = (TYPEOF_TIMEVAL_TV_USEC)(ts.tv_nsec / 1000);
return t;
@@ -1584,7 +1600,7 @@ rb_time_timespec(VALUE time)
if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) {
GetTimeval(time, tobj);
- t = timev2timespec(tobj->timev);
+ t = timexv2timespec(tobj->timexv);
return t;
}
return time_timespec(time, Qfalse);
@@ -1629,24 +1645,24 @@ time_s_now(VALUE klass)
static VALUE
time_s_at(int argc, VALUE *argv, VALUE klass)
{
- VALUE time, t, timev;
+ VALUE time, t, timexv;
if (rb_scan_args(argc, argv, "11", &time, &t) == 2) {
time = num_exact(time);
t = num_exact(t);
- timev = add(time, quo(t, INT2FIX(1000000)));
- t = time_new_timev(klass, timev);
+ timexv = add(rb_time_magnify(time), mulquo(t, INT2FIX(TIME_SCALE), INT2FIX(1000000)));
+ t = time_new_timexv(klass, timexv);
}
else if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) {
struct time_object *tobj, *tobj2;
GetTimeval(time, tobj);
- t = time_new_timev(klass, tobj->timev);
+ t = time_new_timexv(klass, tobj->timexv);
GetTimeval(t, tobj2);
TIME_COPY_GMT(tobj2, tobj);
}
else {
- timev = num_exact(time);
- t = time_new_timev(klass, timev);
+ timexv = rb_time_magnify(num_exact(time));
+ t = time_new_timexv(klass, timexv);
}
return t;
@@ -1681,26 +1697,29 @@ obj2vint(VALUE obj)
}
static long
-obj2subsec(VALUE obj, VALUE *subsec)
+obj2subsecx(VALUE obj, VALUE *subsecx)
{
+ VALUE subsec;
+
if (TYPE(obj) == T_STRING) {
obj = rb_str_to_inum(obj, 10, Qfalse);
- *subsec = INT2FIX(0);
+ *subsecx = INT2FIX(0);
return NUM2LONG(obj);
}
- divmodv(num_exact(obj), INT2FIX(1), &obj, subsec);
+ divmodv(num_exact(obj), INT2FIX(1), &obj, &subsec);
+ *subsecx = rb_time_magnify(subsec);
return NUM2LONG(obj);
}
static long
-usec2subsec(VALUE obj)
+usec2subsecx(VALUE obj)
{
if (TYPE(obj) == T_STRING) {
obj = rb_str_to_inum(obj, 10, Qfalse);
}
- return quo(num_exact(obj), INT2FIX(1000000));
+ return mulquo(num_exact(obj), INT2FIX(TIME_SCALE), INT2FIX(1000000));
}
static int
@@ -1748,7 +1767,7 @@ validate_vtm(struct vtm *vtm)
|| (vtm->hour == 24 && (vtm->min > 0 || vtm->sec > 0))
|| vtm->min < 0 || vtm->min > 59
|| vtm->sec < 0 || vtm->sec > 60
- || lt(vtm->subsec, INT2FIX(0)) || ge(vtm->subsec, INT2FIX(1))
+ || lt(vtm->subsecx, INT2FIX(0)) || ge(vtm->subsecx, INT2FIX(TIME_SCALE))
|| (!NIL_P(vtm->utc_offset) && (validate_utc_offset(vtm->utc_offset), 0)))
rb_raise(rb_eArgError, "argument out of range");
}
@@ -1764,7 +1783,7 @@ time_arg(int argc, VALUE *argv, struct vtm *vtm)
vtm->hour = 0;
vtm->min = 0;
vtm->sec = 0;
- vtm->subsec = INT2FIX(0);
+ vtm->subsecx = INT2FIX(0);
vtm->utc_offset = Qnil;
vtm->wday = 0;
vtm->yday = 0;
@@ -1811,11 +1830,11 @@ time_arg(int argc, VALUE *argv, struct vtm *vtm)
if (!NIL_P(v[6]) && argc == 7) {
vtm->sec = NIL_P(v[5])?0:obj2long(v[5]);
- vtm->subsec = usec2subsec(v[6]);
+ vtm->subsecx = usec2subsecx(v[6]);
}
else {
/* when argc == 8, v[6] is timezone, but ignored */
- vtm->sec = NIL_P(v[5])?0:obj2subsec(v[5], &vtm->subsec);
+ vtm->sec = NIL_P(v[5])?0:obj2subsecx(v[5], &vtm->subsecx);
}
validate_vtm(vtm);
@@ -2139,8 +2158,8 @@ vtmcmp(struct vtm *a, struct vtm *b)
return a->min < b->min ? -1 : 1;
else if (a->sec != b->sec)
return a->sec < b->sec ? -1 : 1;
- else if (ne(a->subsec, b->subsec))
- return lt(a->subsec, b->subsec) ? -1 : 1;
+ else if (ne(a->subsecx, b->subsecx))
+ return lt(a->subsecx, b->subsecx) ? -1 : 1;
else
return 0;
}
@@ -2172,9 +2191,9 @@ time_utc_or_local(int argc, VALUE *argv, int utc_p, VALUE klass)
time_arg(argc, argv, &vtm);
if (utc_p)
- time = time_new_timev(klass, timegmv(&vtm));
+ time = time_new_timexv(klass, timegmxv(&vtm));
else
- time = time_new_timev(klass, timelocalv(&vtm));
+ time = time_new_timexv(klass, timelocalxv(&vtm));
if (utc_p) return time_gmtime(time);
return time_localtime(time);
}
@@ -2267,7 +2286,7 @@ time_to_i(VALUE time)
struct time_object *tobj;
GetTimeval(time, tobj);
- return div(tobj->timev, INT2FIX(1));
+ return div(tobj->timexv, INT2FIX(TIME_SCALE));
}
/*
@@ -2291,7 +2310,7 @@ time_to_f(VALUE time)
struct time_object *tobj;
GetTimeval(time, tobj);
- return rb_Float(tobj->timev);
+ return rb_Float(rb_time_unmagnify(tobj->timexv));
}
/*
@@ -2315,7 +2334,7 @@ time_to_r(VALUE time)
struct time_object *tobj;
GetTimeval(time, tobj);
- return tobj->timev;
+ return rb_time_unmagnify(tobj->timexv);
}
/*
@@ -2336,7 +2355,7 @@ time_usec(VALUE time)
struct time_object *tobj;
GetTimeval(time, tobj);
- return rb_to_int(mul(mod(tobj->timev, INT2FIX(1)), INT2FIX(1000000)));
+ return rb_to_int(mulquo(mod(tobj->timexv, INT2FIX(TIME_SCALE)), INT2FIX(1000000), INT2FIX(TIME_SCALE)));
}
/*
@@ -2362,7 +2381,7 @@ time_nsec(VALUE time)
struct time_object *tobj;
GetTimeval(time, tobj);
- return rb_to_int(mul(mod(tobj->timev, INT2FIX(1)), INT2FIX(1000000000)));
+ return rb_to_int(mulquo(mod(tobj->timexv, INT2FIX(TIME_SCALE)), INT2FIX(1000000000), INT2FIX(TIME_SCALE)));
}
/*
@@ -2389,7 +2408,7 @@ time_subsec(VALUE time)
struct time_object *tobj;
GetTimeval(time, tobj);
- return mod(tobj->timev, INT2FIX(1));
+ return quo(mod(tobj->timexv, INT2FIX(TIME_SCALE)), INT2FIX(TIME_SCALE));
}
/*
@@ -2421,7 +2440,7 @@ time_cmp(VALUE time1, VALUE time2)
GetTimeval(time1, tobj1);
if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {
GetTimeval(time2, tobj2);
- n = rb_cmpint(cmp(tobj1->timev, tobj2->timev), tobj1->timev, tobj2->timev);
+ n = rb_cmpint(cmp(tobj1->timexv, tobj2->timexv), tobj1->timexv, tobj2->timexv);
}
else {
VALUE cmp;
@@ -2453,7 +2472,7 @@ time_eql(VALUE time1, VALUE time2)
GetTimeval(time1, tobj1);
if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {
GetTimeval(time2, tobj2);
- return rb_equal(tobj1->timev, tobj2->timev);
+ return rb_equal(tobj1->timexv, tobj2->timexv);
}
return Qfalse;
}
@@ -2500,7 +2519,7 @@ time_hash(VALUE time)
struct time_object *tobj;
GetTimeval(time, tobj);
- return rb_hash(tobj->timev);
+ return rb_hash(tobj->timexv);
}
/* :nodoc: */
@@ -2544,7 +2563,7 @@ time_localtime(VALUE time)
time_modify(time);
}
- if (!localtimev(tobj->timev, &vtm))
+ if (!localtimexv(tobj->timexv, &vtm))
rb_raise(rb_eArgError, "localtime error");
tobj->vtm = vtm;
@@ -2623,7 +2642,7 @@ time_gmtime(VALUE time)
time_modify(time);
}
- if (!gmtimev(tobj->timev, &vtm))
+ if (!gmtimexv(tobj->timexv, &vtm))
rb_raise(rb_eArgError, "gmtime error");
tobj->vtm = vtm;
@@ -2653,7 +2672,7 @@ time_fixoff(VALUE time)
else
off = INT2FIX(0);
- if (!gmtimev(tobj->timev, &vtm))
+ if (!gmtimexv(tobj->timexv, &vtm))
rb_raise(rb_eArgError, "gmtime error");
tobj->vtm = vtm;
@@ -2788,9 +2807,9 @@ time_add(struct time_object *tobj, VALUE offset, int sign)
VALUE result;
offset = num_exact(offset);
if (sign < 0)
- result = time_new_timev(rb_cTime, sub(tobj->timev, offset));
+ result = time_new_timexv(rb_cTime, sub(tobj->timexv, rb_time_magnify(offset)));
else
- result = time_new_timev(rb_cTime, add(tobj->timev, offset));
+ result = time_new_timexv(rb_cTime, add(tobj->timexv, rb_time_magnify(offset)));
if (TIME_UTC_P(tobj)) {
GetTimeval(result, tobj);
TIME_SET_UTC(tobj);
@@ -2846,7 +2865,7 @@ time_minus(VALUE time1, VALUE time2)
struct time_object *tobj2;
GetTimeval(time2, tobj2);
- return rb_Float(sub(tobj->timev, tobj2->timev));
+ return rb_Float(rb_time_unmagnify(sub(tobj->timexv, tobj2->timexv)));
}
return time_add(tobj, time2, -1);
}
@@ -2868,7 +2887,7 @@ time_succ(VALUE time)
struct time_object *tobj2;
GetTimeval(time, tobj);
- time = time_new_timev(rb_cTime, add(tobj->timev, INT2FIX(1)));
+ time = time_new_timexv(rb_cTime, add(tobj->timexv, INT2FIX(TIME_SCALE)));
GetTimeval(time, tobj2);
TIME_COPY_GMT(tobj2, tobj);
return time;
@@ -3351,7 +3370,7 @@ strftimev(const char *fmt, VALUE time)
GetTimeval(time, tobj);
MAKE_TM(time, tobj);
- len = rb_strftime_alloc(&buf, fmt, &tobj->vtm, tobj->timev, TIME_UTC_P(tobj));
+ len = rb_strftime_alloc(&buf, fmt, &tobj->vtm, rb_time_unmagnify(tobj->timexv), TIME_UTC_P(tobj));
str = rb_str_new(buf, len);
if (buf != buffer) xfree(buf);
return str;
@@ -3449,7 +3468,7 @@ time_strftime(VALUE time, VALUE format)
str = rb_str_new(0, 0);
while (p < pe) {
- len = rb_strftime_alloc(&buf, p, &tobj->vtm, tobj->timev, TIME_UTC_P(tobj));
+ len = rb_strftime_alloc(&buf, p, &tobj->vtm, rb_time_unmagnify(tobj->timexv), TIME_UTC_P(tobj));
rb_str_cat(str, buf, len);
p += strlen(p);
if (buf != buffer) {
@@ -3463,7 +3482,7 @@ time_strftime(VALUE time, VALUE format)
}
else {
len = rb_strftime_alloc(&buf, RSTRING_PTR(format),
- &tobj->vtm, tobj->timev, TIME_UTC_P(tobj));
+ &tobj->vtm, rb_time_unmagnify(tobj->timexv), TIME_UTC_P(tobj));
}
str = rb_str_new(buf, len);
if (buf != buffer) xfree(buf);
@@ -3487,11 +3506,11 @@ time_mdump(VALUE time)
struct vtm vtm;
long year;
long usec, nsec;
- VALUE subsec, subnano, v;
+ VALUE subsecx, nano, subnano, v;
GetTimeval(time, tobj);
- gmtimev(tobj->timev, &vtm);
+ gmtimexv(tobj->timexv, &vtm);
if (FIXNUM_P(vtm.year)) {
year = FIX2LONG(vtm.year);
@@ -3502,10 +3521,10 @@ time_mdump(VALUE time)
rb_raise(rb_eArgError, "year too big to marshal");
}
- subsec = vtm.subsec;
+ subsecx = vtm.subsecx;
- subsec = mul(subsec, INT2FIX(1000000000));
- divmodv(subsec, INT2FIX(1), &v, &subnano);
+ nano = mulquo(subsecx, INT2FIX(1000000000), INT2FIX(TIME_SCALE));
+ divmodv(nano, INT2FIX(1), &v, &subnano);
nsec = FIX2LONG(v);
usec = nsec / 1000;
nsec = nsec % 1000;
@@ -3589,7 +3608,7 @@ time_mload(VALUE time, VALUE str)
struct vtm vtm;
int i, gmt;
long nsec;
- VALUE timev, submicro, subnano;
+ VALUE timexv, submicro, subnano;
time_modify(time);
@@ -3622,7 +3641,7 @@ time_mload(VALUE time, VALUE str)
sec = p;
usec = s;
nsec = usec * 1000;
- timev = add(TIMET2NUM(sec), quo(LONG2FIX(usec), LONG2FIX(1000000)));
+ timexv = add(rb_time_magnify(TIMET2NUM(sec)), mulquo(LONG2FIX(usec), INT2FIX(TIME_SCALE), LONG2FIX(1000000)));
}
else {
p &= ~(1UL<<31);
@@ -3661,18 +3680,18 @@ time_mload(VALUE time, VALUE str)
end_submicro: ;
}
- vtm.subsec = quo(LONG2FIX(nsec), LONG2FIX(1000000000));
+ vtm.subsecx = mulquo(LONG2FIX(nsec), INT2FIX(TIME_SCALE), LONG2FIX(1000000000));
if (subnano != Qnil) {
subnano = num_exact(subnano);
- vtm.subsec = add(vtm.subsec, quo(subnano, LONG2FIX(1000000000)));
+ vtm.subsecx = add(vtm.subsecx, mulquo(subnano, INT2FIX(TIME_SCALE), LONG2FIX(1000000000)));
}
- timev = timegmv(&vtm);
+ timexv = timegmxv(&vtm);
}
GetTimeval(time, tobj);
tobj->tm_got = 0;
if (gmt) TIME_SET_UTC(tobj);
- tobj->timev = timev;
+ tobj->timexv = timexv;
return time;
}
diff --git a/timev.h b/timev.h
index 6fa4f86415..631fcf3e1d 100644
--- a/timev.h
+++ b/timev.h
@@ -8,7 +8,7 @@ struct vtm {
int hour; /* 0..23 */
int min; /* 0..59 */
int sec; /* 0..60 */
- VALUE subsec; /* 0 <= subsec < 1. possibly Rational. */
+ VALUE subsecx; /* 0 <= subsecx < TIME_SCALE. possibly Rational. */
VALUE utc_offset; /* -3600 as -01:00 for example. possibly Rational. */
int wday; /* 0:Sunday, 1:Monday, ..., 6:Saturday */
int yday; /* 1..366 */
@@ -16,4 +16,6 @@ struct vtm {
const char *zone; /* "JST", "EST", "EDT", etc. */
};
+#define TIME_SCALE 1000000000
+
#endif