diff --git a/ChangeLog b/ChangeLog index c4bc28f62a..5697e3edb7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Tue Nov 10 11:25:29 2015 NARUSE, Yui + + * time.c (rb_timespec_now): added. + + * time.c (rb_time_timespec_new): added. + Tue Nov 10 06:17:17 2015 Eric Wong * variable.c (rb_autoload_load): allow recursive calls diff --git a/NEWS b/NEWS index dc7babe03a..704d58206d 100644 --- a/NEWS +++ b/NEWS @@ -209,6 +209,11 @@ with all sufficient information, see the ChangeLog file. class is already defined but its superclass does not match the given superclass, as well as definitions in ruby level. +* rb_timespec_now() is added to fetch current datetime as struct timespec. + +* rb_time_timespec_new() is added to create a time object with epoch, + nanosecond, and UTC/localtime/time offset arguments. + === Build system updates === Implementation changes diff --git a/include/ruby/intern.h b/include/ruby/intern.h index af6b75d6d4..3fb1637593 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -919,8 +919,10 @@ VALUE rb_mutex_unlock(VALUE mutex); VALUE rb_mutex_sleep(VALUE self, VALUE timeout); VALUE rb_mutex_synchronize(VALUE mutex, VALUE (*func)(VALUE arg), VALUE arg); /* time.c */ +void rb_timespec_now(struct timespec *); VALUE rb_time_new(time_t, long); VALUE rb_time_nano_new(time_t, long); +VALUE rb_time_timespec_new(const struct timespec *, int); VALUE rb_time_num_new(VALUE, VALUE); struct timeval rb_time_interval(VALUE num); struct timeval rb_time_timeval(VALUE time); diff --git a/time.c b/time.c index 11331a3147..aad4cb4ad1 100644 --- a/time.c +++ b/time.c @@ -1892,6 +1892,25 @@ timew2timespec_exact(wideval_t timew, struct timespec *ts) return ts; } +void +rb_timespec_now(struct timespec *ts) +{ +#ifdef HAVE_CLOCK_GETTIME + if (clock_gettime(CLOCK_REALTIME, ts) == -1) { + rb_sys_fail("clock_gettime"); + } +#else + { + struct timeval tv; + if (gettimeofday(&tv, 0) < 0) { + rb_sys_fail("gettimeofday"); + } + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * 1000; + } +#endif +} + static VALUE time_init_0(VALUE time) { @@ -1903,20 +1922,7 @@ time_init_0(VALUE time) tobj->gmt = 0; tobj->tm_got=0; tobj->timew = WINT2FIXWV(0); -#ifdef HAVE_CLOCK_GETTIME - if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { - rb_sys_fail("clock_gettime"); - } -#else - { - struct timeval tv; - if (gettimeofday(&tv, 0) < 0) { - rb_sys_fail("gettimeofday"); - } - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000; - } -#endif + rb_timespec_now(&ts); tobj->timew = timespec2timew(&ts); return time; @@ -2299,12 +2305,41 @@ rb_time_new(time_t sec, long usec) return time_new_timew(rb_cTime, timew); } +/* returns localtime time object */ VALUE rb_time_nano_new(time_t sec, long nsec) { return time_new_timew(rb_cTime, nsec2timew(sec, nsec)); } +/** + * Returns a time object with UTC/localtime/fixed offset + * + * offset is -86400 < fixoff < 86400 or INT_MAX (UTC) or INT_MAX-1 (localtime) + */ +VALUE +rb_time_timespec_new(const struct timespec *ts, int offset) +{ + struct time_object *tobj; + VALUE time = time_new_timew(rb_cTime, nsec2timew(ts->tv_sec, ts->tv_nsec)); + + if (-86400 < offset && offset < 86400) { /* fixoff */ + GetTimeval(time, tobj); + TIME_SET_FIXOFF(tobj, INT2FIX(offset)); + } + else if (offset == INT_MAX) { /* UTC */ + GetTimeval(time, tobj); + TIME_SET_UTC(tobj); + } + else if (offset == INT_MAX-1) { /* localtime */ + } + else { + rb_raise(rb_eArgError, "utc_offset out of range"); + } + + return time; +} + VALUE rb_time_num_new(VALUE timev, VALUE off) {