Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Time accepts a Rational offset #1714

Merged
merged 2 commits into from

3 participants

@dubek

Add support for Rational (sub-second) offset for Time instances.

Since I didn't want to play around with Rational objects in the C++ code (how is done anyhow?), I split the offset into two integers - seconds and nanoseconds, and pass them to the C++ code (vm/builtin/time.cpp).

(I submitted this earlier as pull request 1713 which I closed because it didn't pass the 1.8 tests.)

@travisbot

This pull request passes (merged e6f3309 into 62d48b1).

@abyx abyx merged commit 15c5b3e into rubinius:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
10 kernel/common/time18.rb
@@ -44,7 +44,15 @@ def self.from_array(sec, min, hour, mday, month, year, nsec, is_dst, from_gmt, u
sec = sec.kind_of?(String) ? sec.to_i : Rubinius::Type.coerce_to(sec || 0, Integer, :to_int)
- from_array(sec, min, hour, mday, month, year, nsec || 0, is_dst, from_gmt, utc_offset)
+ if utc_offset
+ utc_offset_sec = utc_offset.to_i
+ utc_offset_nsec = ((utc_offset % 1.0) * 1_000_000_000 + 0.5).to_i
+ else
+ utc_offset_sec = 0
+ utc_offset_nsec = 0
+ end
+
+ from_array(sec, min, hour, mday, month, year, nsec || 0, is_dst, from_gmt, utc_offset, utc_offset_sec, utc_offset_nsec)
end
def inspect
View
10 kernel/common/time19.rb
@@ -51,7 +51,15 @@ def self.from_array(sec, min, hour, mday, month, year, nsec, is_dst, from_gmt, u
sec += nsec / 1_000_000_000
nsec %= 1_000_000_000
- from_array(sec, min, hour, mday, month, year, nsec, is_dst, from_gmt, utc_offset)
+ if utc_offset
+ utc_offset_sec = utc_offset.to_i
+ utc_offset_nsec = ((utc_offset % 1.0) * 1_000_000_000 + 0.5).to_i
+ else
+ utc_offset_sec = 0
+ utc_offset_nsec = 0
+ end
+
+ from_array(sec, min, hour, mday, month, year, nsec, is_dst, from_gmt, utc_offset, utc_offset_sec, utc_offset_nsec)
end
def self.new(year=undefined, month=nil, day=nil, hour=nil, minute=nil, second=nil, utc_offset=nil)
View
7 spec/ruby/core/time/shared/gmt_offset.rb
@@ -25,4 +25,11 @@
Time.local(2010,4,4,3,0,0).send(@method).should == 12*60*60
end
end
+
+ ruby_version_is "1.9" do
+ it "returns offset as Rational" do
+ Time.new(2010,4,4,1,59,59,7245).send(@method).should == 7245
+ Time.new(2010,4,4,1,59,59,7245.5).send(@method).should == Rational(14491,2)
+ end
+ end
end
View
2  spec/tags/19/ruby/core/time/getlocal_tags.txt
@@ -1,2 +0,0 @@
-fails:Time#getlocal returns a Time with a UTC offset of the specified number of Rational seconds
-fails:Time#getlocal with an argument that responds to #to_r coerces using #to_r
View
2  spec/tags/19/ruby/core/time/localtime_tags.txt
@@ -1,2 +0,0 @@
-fails:Time#localtime returns a Time with a UTC offset of the specified number of Rational seconds
-fails:Time#localtime with an argument that responds to #to_r coerces using #to_r
View
2  spec/tags/19/ruby/core/time/new_tags.txt
@@ -1,3 +1 @@
-fails:Time.new with a utc_offset argument returns a Time with a UTC offset of the specified number of Rational seconds
-fails:Time.new with a utc_offset argument with an argument that responds to #to_r coerces using #to_r
unstable(fails on 32-bit linux):Time.new accepts various year ranges
View
15 vm/builtin/time.cpp
@@ -96,7 +96,8 @@ namespace rubinius {
Time* Time::from_array(STATE, Object* self,
Fixnum* sec, Fixnum* min, Fixnum* hour,
Fixnum* mday, Fixnum* mon, Fixnum* year, Fixnum* nsec,
- Fixnum* isdst, Object* from_gmt, Object* offset) {
+ Fixnum* isdst, Object* from_gmt, Object* offset,
+ Fixnum* offset_sec, Fixnum* offset_nsec) {
struct tm tm;
tm.tm_sec = sec->to_native();
@@ -158,8 +159,16 @@ namespace rubinius {
obj->nanoseconds_ = nsec->to_native();
obj->is_gmt(state, CBOOL(from_gmt) ? cTrue : cFalse);
- if(Fixnum* off = try_as<Fixnum>(offset)) {
- obj->seconds_ -= off->to_native();
+ if(!offset->nil_p()) {
+ obj->seconds_ -= offset_sec->to_native();
+ obj->nanoseconds_ -= offset_nsec->to_native();
+
+ // Deal with underflow wrapping
+ if(obj->nanoseconds_ < 0) {
+ obj->seconds_ += NDIV(obj->nanoseconds_, 1000000000);
+ obj->nanoseconds_ = NMOD(obj->nanoseconds_, 1000000000);
+ }
+
obj->offset(state, offset);
}
View
2  vm/builtin/time.hpp
@@ -42,7 +42,7 @@ namespace rubinius {
static Time* now(STATE, Object* self);
// Rubinius.primitive :time_s_from_array
- static Time* from_array(STATE, Object* self, Fixnum* sec, Fixnum* min, Fixnum* hour, Fixnum* mday, Fixnum* mon, Fixnum* year, Fixnum* nsec, Fixnum* isdst, Object* from_gmt, Object* offset);
+ static Time* from_array(STATE, Object* self, Fixnum* sec, Fixnum* min, Fixnum* hour, Fixnum* mday, Fixnum* mon, Fixnum* year, Fixnum* nsec, Fixnum* isdst, Object* from_gmt, Object* offset, Fixnum* offset_sec, Fixnum* offset_nsec);
// Rubinius.primitive :time_s_dup
static Time* dup(STATE, Object* self, Time* other);
Something went wrong with that request. Please try again.