diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb index 2a56836..7a85145 100644 --- a/test/ruby/test_time.rb +++ b/test/ruby/test_time.rb @@ -40,6 +40,14 @@ class TestTime < Test::Unit::TestCase assert_equal([2001,2,28,23,59,30,-43200], [t.year, t.month, t.mday, t.hour, t.min, t.sec, t.gmt_offset], bug4090) end + def test_elapsed + assert_operator Time.now.elapsed, :>, 0 + now = Time.now + lap1 = now.elapsed + lap2 = now.elapsed + assert_operator lap2, :>, lap1 + end + def test_time_add() assert_equal(Time.utc(2000, 3, 21, 3, 30) + 3 * 3600, Time.utc(2000, 3, 21, 6, 30)) diff --git a/time.c b/time.c index c0fca66..1265673 100644 --- a/time.c +++ b/time.c @@ -3726,6 +3726,45 @@ time_minus(VALUE time1, VALUE time2) } /* + * call-seq: + * time.elapsed -> integer + * + * Elapsed amount of time (in nanoseconds) since _time_ was created. + * + * t = Time.now #=> 2007-11-19 08:23:10 -0600 + * t.elapsed #=> 3022418000 + */ + +static VALUE +time_elapsed(VALUE self) +{ + struct time_object *tobj; + struct timespec ts; + wideval_t timew; + + GetTimeval(self, tobj); + +#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 + + timew = timespec2timew(&ts); + + return rb_to_int(w2v(wsub(timew, tobj->timew))); +} + +/* * call-seq: * time.succ -> new_time * @@ -4947,6 +4986,7 @@ Init_Time(void) rb_define_method(rb_cTime, "+", time_plus, 1); rb_define_method(rb_cTime, "-", time_minus, 1); + rb_define_method(rb_cTime, "elapsed", time_elapsed, 0); rb_define_method(rb_cTime, "succ", time_succ, 0); rb_define_method(rb_cTime, "round", time_round, -1);