Skip to content

Commit

Permalink
Time utc_offset can be Rational
Browse files Browse the repository at this point in the history
  • Loading branch information
dubek committed May 10, 2012
1 parent 3f87515 commit e6f3309
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 12 deletions.
10 changes: 9 additions & 1 deletion kernel/common/time18.rb
Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion kernel/common/time19.rb
Expand Up @@ -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)
Expand Down
2 changes: 0 additions & 2 deletions spec/tags/19/ruby/core/time/getlocal_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/tags/19/ruby/core/time/localtime_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions 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
15 changes: 12 additions & 3 deletions vm/builtin/time.cpp
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion vm/builtin/time.hpp
Expand Up @@ -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);
Expand Down

0 comments on commit e6f3309

Please sign in to comment.