Permalink
Browse files

Time utc_offset can be Rational

  • Loading branch information...
dubek committed May 9, 2012
1 parent 3f87515 commit e6f3309d6739110eccaf3fabdb44fb393dd33587
View
@@ -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
@@ -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)
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);

0 comments on commit e6f3309

Please sign in to comment.