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