Permalink
Browse files

Support offsets as strings for compatibility with stdlib (Fixes #37)

  • Loading branch information...
1 parent 80f1561 commit 98b331d27318d0e6b3e70f5f73c85662d9fa019a @jeremyevans committed Sep 2, 2011
Showing with 32 additions and 9 deletions.
  1. +14 −9 ext/date_ext/datetime.c
  2. +14 −0 spec/datetime/constructor_spec.rb
  3. +4 −0 spec/datetime/conversions_spec.rb
View
@@ -512,6 +512,15 @@ VALUE rhrdt__new_offset(VALUE self, double offset) {
return rhrdt__from_jd_nanos(rb_obj_class(self), dt->jd, dt->nanos - (dt->offset - offset_min)*RHR_NANOS_PER_MINUTE, (short)offset_min);
}
+/* Handle both string timezones and numeric offsets in
+ * constructors and new_offset */
+double rhrdt__constructor_offset(VALUE self, VALUE offset) {
+ if (TYPE(offset) == T_STRING) {
+ return NUM2LONG(rhrd_s_zone_to_diff(self, offset))/RHR_SECONDS_PER_DAYD;
+ }
+ return NUM2DBL(offset);
+}
+
/* Class methods */
/* call-seq:
@@ -618,7 +627,7 @@ static VALUE rhrdt_s_civil(int argc, VALUE *argv, VALUE klass) {
return rdt;
case 8:
case 7:
- offset = NUM2DBL(argv[6]);
+ offset = rhrdt__constructor_offset(klass, argv[6]);
case 6:
second = NUM2LONG(argv[5]);
case 5:
@@ -672,7 +681,7 @@ static VALUE rhrdt_s_commercial(int argc, VALUE *argv, VALUE klass) {
switch(argc) {
case 8:
case 7:
- offset = NUM2DBL(argv[6]);
+ offset = rhrdt__constructor_offset(klass, argv[6]);
case 6:
second = NUM2LONG(argv[5]);
case 5:
@@ -727,7 +736,7 @@ static VALUE rhrdt_s_jd(int argc, VALUE *argv, VALUE klass) {
return rdt;
case 6:
case 5:
- offset = NUM2DBL(argv[4]);
+ offset = rhrdt__constructor_offset(klass, argv[4]);
case 4:
second = NUM2LONG(argv[3]);
case 3:
@@ -842,7 +851,7 @@ static VALUE rhrdt_s_ordinal(int argc, VALUE *argv, VALUE klass) {
switch(argc) {
case 7:
case 6:
- offset = NUM2DBL(argv[5]);
+ offset = rhrdt__constructor_offset(klass, argv[5]);
case 5:
second = NUM2LONG(argv[4]);
case 4:
@@ -1378,11 +1387,7 @@ static VALUE rhrdt_new_offset(int argc, VALUE *argv, VALUE self) {
offset = 0;
break;
case 1:
- if (RTEST(rb_obj_is_kind_of(argv[0], rb_cString))) {
- offset = NUM2LONG(rhrd_s_zone_to_diff(self, argv[0]))/RHR_SECONDS_PER_DAYD;
- } else {
- offset = NUM2DBL(argv[0]);
- }
+ offset= rhrdt__constructor_offset(rb_obj_class(self), argv[0]);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments: %i for 1", argc);
@@ -149,4 +149,18 @@
c.new!.should be_kind_of(c)
c.new.should be_kind_of(c)
end
+
+ it "should handle strings for the offset" do
+ DateTime.jd(2008, 0, 0, 0, 'Z').should == DateTime.jd(2008, 0, 0, 0, 0)
+ DateTime.civil(2008, 1, 1, 0, 0, 0, 'Z').should == DateTime.civil(2008, 1, 1, 0, 0, 0, 0)
+ DateTime.commercial(2008, 1, 1, 0, 0, 0, 'Z').should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0)
+ DateTime.ordinal(2008, 1, 0, 0, 0, 'Z').should == DateTime.ordinal(2008, 1, 0, 0, 0, 0)
+ DateTime.new(2008, 1, 1, 0, 0, 0, 'Z').should == DateTime.new(2008, 1, 1, 0, 0, 0, 0)
+
+ DateTime.jd(2008, 0, 0, 0, '+1200').should == DateTime.jd(2008, 0, 0, 0, 0.5)
+ DateTime.civil(2008, 1, 1, 0, 0, 0, '+1200').should == DateTime.civil(2008, 1, 1, 0, 0, 0, 0.5)
+ DateTime.commercial(2008, 1, 1, 0, 0, 0, '+1200').should == DateTime.commercial(2008, 1, 1, 0, 0, 0, 0.5)
+ DateTime.ordinal(2008, 1, 0, 0, 0, '+1200').should == DateTime.ordinal(2008, 1, 0, 0, 0, 0.5)
+ DateTime.new(2008, 1, 1, 0, 0, 0, '+1200').should == DateTime.new(2008, 1, 1, 0, 0, 0, 0.5)
+ end
end
@@ -5,6 +5,10 @@
DateTime.new(2008, 1, 1).new_offset(0.5).to_s.should == DateTime.new(2008, 1, 1, 12, 0, 0, 0.5).to_s
end
+ it "#new_offset should work with strings" do
+ DateTime.new(2008, 1, 1).new_offset('+12:00').to_s.should == DateTime.new(2008, 1, 1, 12, 0, 0, 0.5).to_s
+ end
+
it "#new_offset result should be equal to the receiver" do
DateTime.new(2008, 1, 1).new_offset(0.5).should == DateTime.new(2008, 1, 1)
end

0 comments on commit 98b331d

Please sign in to comment.