e$BA0$K$A$g$C$H=q$-$^$7$?$,!"e(BTime#round
e$B$rDI2C$9$k$N$O$I$&$G$7$g$&!#e(B
e$B$3$l$O!"ICL$K~$N;~9o$r4]$a$k%a%=%C%I$G$9!#e(B
e$B$A$g$&$Ie(B [ruby-core:28602] e$B$K$b$"$j$^$7$?$,!“e(B
Time e$B%*%V%8%’%/%HFb$K8m:9$r4^$`CM$rF~$l$F$7$^$&$3$H$,$”$j$^$9!#e(B
e$B$^$!!";~9o$K8m:9$,$"$k$N$OB,Dj$N$3$H$b9M$($k$H$7$+$?$,$J$$$H;W$&$N$G$9$,!“e(B
e$B8m:9$N$”$k;~9o$r6a;w$9$kCM$rI=<($9$k$3$H$,Fq$7$$$H$$$&LdBj$,$"$j$^$9!#e(B
strftime e$B$Ne(B %N e$B$O!">.?tE@0J2<$NIC?t$rI=<($9$k$b$N$J$N$G!"e(B
e$B;EMM>e!“4]$a$k$N$O:$Fq$G!”@Z$j<N$F$K$;$6$k$rF@$^$;$s!#e(B
e$B4]$a$k$H!"IC$X$N7+$j>e$,$j$,@8$8$?;~$K$I$&$9$k$+$H$$$&LdBj$,@8$8$^$9!#e(B
%N e$B$@$1$G$J$/!"e(Busec e$B$de(B nsec
e$B$bF1MM$JM}M3$G@Z$j<N$F$G$9!#e(B
e$B$3$N$?$a!"$?$H$($Pe(B 0.9999999 e$BIC$rI=<($9$k$He(B
0e$BIC$K$J$C$F!“e(B
1e$BIC$r4|BT$7$F$$$k?M$K$O!”$&$^$/F0$+$J$$$h$&$K8+$($k$3$H$K$J$j$^$9!#e(B
e$B$3$3$G!“e(BTime#round e$B$r;H$&$H!”>.?tE@0J2<$r;M<N8^F~$7$?e(B
Time e$B%*%V%8%’%/%H$rF@$i$l$^$9!#e(B
% ./ruby -e ’
t = Time.utc(1999,12,31, 23,59,59,876543)
p t, t.subsec
t = t.round
p t, t.subsec’
1999-12-31 23:59:59 UTC
(876543/1000000)
2000-01-01 00:00:00 UTC
0
e$B$^$?!“e(BInteger#round
e$B$HF1MM$K!”>JN,2DG=$J0z?t$G7e?t$r;XDj$9$k$3$H$,$G$-$^$9!#e(B
e$B$3$l$K$h$j!"IC$r>.?tE@0J2<e(B3e$B7e$G4]$a$FI=<($7$?$1$l$P!"e(B
strftime e$B$NA0$Ke(B round(3) e$B$r8F$V$3$H$G<B8=$G$-$^$9!#e(B
% ./ruby -e ’
t = Time.utc(1999,12,31, 23,59,59,876543)
p t, t.subsec, t.strftime("%T.%3N")
t = t.round(3)
p t, t.subsec, t.strftime("%T.%3N")
’
1999-12-31 23:59:59 UTC
(876543/1000000)
“23:59:59.876”
1999-12-31 23:59:59 UTC
(877/1000)
“23:59:59.877”
e$B$I$&$G$7$g$&e(B?
% svn diff --diff-cmd diff -x ‘-u -p’
Index: time.c
— time.c (revision 26871)
+++ time.c (working copy)
@@ -2997,6 +2997,64 @@ rb_time_succ(VALUE time)
#define time_succ rb_time_succ
+/*
-
- call-seq:
-
- time.round([ndigits]) => new_time
-
-
- Rounds sub seconds to a given precision in decimal digits (0
digits by default).
- Rounds sub seconds to a given precision in decimal digits (0
-
- It returns a new time object.
-
- ndigits should be zero or positive integer.
-
-
-
require 'time'
-
-
-
-
t = Time.utc(1999,12,31, 23,59,59)
-
-
-
p((t + 0.4).round.iso8601(3)) #=> "1999-12-31T23:59:59.000Z"
-
-
-
p((t + 0.49).round.iso8601(3)) #=> "1999-12-31T23:59:59.000Z"
-
-
-
p((t + 0.5).round.iso8601(3)) #=> "2000-01-01T00:00:00.000Z"
-
-
-
p((t + 1.4).round.iso8601(3)) #=> "2000-01-01T00:00:00.000Z"
-
-
-
p((t + 1.49).round.iso8601(3)) #=> "2000-01-01T00:00:00.000Z"
-
-
-
p((t + 1.5).round.iso8601(3)) #=> "2000-01-01T00:00:01.000Z"
-
-
-
-
t = Time.utc(1999,12,31, 23,59,59)
-
-
-
p (t + 0.123456789).round(4).iso8601(6) #=>
-
“1999-12-31T23:59:59.123500Z”
- */
+static VALUE
+time_round(int argc, VALUE *argv, VALUE time)
+{
- VALUE ndigits, v, a, b, den;
- long nd;
- struct time_object *tobj;
- rb_scan_args(argc, argv, “01”, &ndigits);
- if (NIL_P(ndigits))
-
ndigits = INT2FIX(0);
- else
-
ndigits = rb_to_int(ndigits);
- nd = NUM2LONG(ndigits);
- if (nd < 0)
- rb_raise(rb_eArgError, “negative ndigits given”);
- GetTimeval(time, tobj);
- v = rb_time_unmagnify(tobj->timexv);
- a = INT2FIX(1);
- b = INT2FIX(10);
- while (0 < nd) {
-
if (nd & 1)
-
a = mul(a, b);
-
b = mul(b, b);
-
nd = nd >> 1;
- }
- den = quo(INT2FIX(1), a);
- v = mod(v, den);
- if (lt(v, quo(den, INT2FIX(2))))
-
return time_add(tobj, v, -1);
- else
-
return time_add(tobj, sub(den, v), 1);
+}
/*
-
call-seq:
@@ -3918,6 +3976,8 @@ Init_Time(void)
rb_define_method(rb_cTime, “-”, time_minus, 1);rb_define_method(rb_cTime, “succ”, time_succ, 0);
- rb_define_method(rb_cTime, “round”, time_round, -1);
- rb_define_method(rb_cTime, “sec”, time_sec, 0);
rb_define_method(rb_cTime, “min”, time_min, 0);
rb_define_method(rb_cTime, “hour”, time_hour, 0);
Index: test/ruby/test_time.rb
===================================================================
— test/ruby/test_time.rb (revision 26871)
+++ test/ruby/test_time.rb (working copy)
@@ -576,4 +576,37 @@ class TestTime < Test::Unit::TestCase
assert_kind_of(Rational, Time.new(2000,1,1,0,0,Rational(4,3)).to_r)
assert_kind_of(Rational, Time.utc(1970).to_r)
end - def test_round
- t = Time.utc(1999,12,31, 23,59,59)
- t2 = (t+0.4).round
- assert_equal([59,59,23, 31,12,1999, 5,365,false,“UTC”], t2.to_a)
- assert_equal(0, t2.subsec)
- t2 = (t+0.49).round
- assert_equal([59,59,23, 31,12,1999, 5,365,false,“UTC”], t2.to_a)
- assert_equal(0, t2.subsec)
- t2 = (t+0.5).round
- assert_equal([0,0,0, 1,1,2000, 6,1,false,“UTC”], t2.to_a)
- assert_equal(0, t2.subsec)
- t2 = (t+1.4).round
- assert_equal([0,0,0, 1,1,2000, 6,1,false,“UTC”], t2.to_a)
- assert_equal(0, t2.subsec)
- t2 = (t+1.49).round
- assert_equal([0,0,0, 1,1,2000, 6,1,false,“UTC”], t2.to_a)
- assert_equal(0, t2.subsec)
- t2 = (t+1.5).round
- assert_equal([1,0,0, 1,1,2000, 6,1,false,“UTC”], t2.to_a)
- assert_equal(0, t2.subsec)
- t2 = (t+0.123456789).round(4)
- assert_equal([59,59,23, 31,12,1999, 5,365,false,“UTC”], t2.to_a)
- assert_equal(Rational(1235,10000), t2.subsec)
- off = 0.0
- 100.times {|i|
-
t2 = (t+off).round(1)
-
assert_equal(Rational(i % 10, 10), t2.subsec)
-
off += 0.1
- }
- end
end