From: naruse@... Date: 2015-11-08T06:44:20+00:00 Subject: [ruby-dev:49334] [Ruby trunk - Feature #11558] Time related C APIs Issue #11558 has been updated by Yui NARUSE. とりあえず特に異論の無かった下記を入れようかと思います。 ```diff diff --git a/include/ruby/intern.h b/include/ruby/intern.h index af6b75d..3fb1637 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 11c76a5..da8cf25 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; @@ -2306,6 +2312,23 @@ rb_time_nano_new(time_t sec, long nsec) } VALUE +rb_time_timespec_new(const struct timespec *ts, int offset) +{ + VALUE time = time_new_timew(rb_cTime, nsec2timew(ts->tv_sec, ts->tv_nsec)); + if (offset) { + struct time_object *tobj; + if (offset < -86400 || 86400 < offset) + rb_raise(rb_eArgError, "utc_offset out of range"); + GetTimeval(time, tobj); + tobj->tm_got = 0; + tobj->gmt = 2; + tobj->vtm.utc_offset = INT2FIX(offset); + tobj->vtm.zone = NULL; + } + return time; +} + +VALUE rb_time_num_new(VALUE timev, VALUE off) { VALUE time = time_new_timew(rb_cTime, rb_time_magnify(v2w(timev))); ``` ---------------------------------------- Feature #11558: Time related C APIs https://bugs.ruby-lang.org/issues/11558#change-54755 * Author: Yui NARUSE * Status: Open * Priority: Normal * Assignee: ---------------------------------------- Time関連のC APIを追加して欲しいです。 具体的には以下のようなものが欲しいです。 struct timespecとoffsetを取って、Timeを返してください。 VALUE rb_time_timespec_new(const struct timespec *ts, int offset); 趣旨としては、[秒, ナノ秒, offset]からTimeを作って欲しいと言うことです。 (rb_time_num_new(Rational, offset)とかだと手間かかる上に遅い) 現在時刻をstruct timespecで欲しいです。 void timespec_now(struct timespec *ts); 既存の非公開APIを公開してください。 struct tm * localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long *gmtoff, const char **zone); time_t timegm_noleapsecond(struct tm *tm); void tm_add_offset(struct tm *tm, long diff); https://github.com/nurse/strptime/blob/v0.1.1/ext/strptime/ruby_time.c -- https://bugs.ruby-lang.org/