Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rubinius/rubinius
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6e9bf802e161
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: c700fb393010
Choose a head ref
  • 2 commits
  • 5 files changed
  • 1 contributor

Commits on Feb 11, 2016

  1. Copy the full SHA
    df6783d View commit details
  2. Copy the full SHA
    c700fb3 View commit details
Showing with 67 additions and 0 deletions.
  1. +1 −0 spec/ruby/optional/capi/ext/rubyspec.h
  2. +14 −0 spec/ruby/optional/capi/ext/time_spec.c
  3. +30 −0 spec/ruby/optional/capi/time_spec.rb
  4. +19 −0 vm/capi/time.cpp
  5. +3 −0 vm/include/capi/ruby/ruby.h
1 change: 1 addition & 0 deletions spec/ruby/optional/capi/ext/rubyspec.h
Original file line number Diff line number Diff line change
@@ -639,6 +639,7 @@
#define HAVE_RB_TIME_INTERVAL 1
#define HAVE_RB_TIME_TIMEVAL 1
#define HAVE_RB_TIME_TIMESPEC 1
#define HAVE_RB_TIME_TIMESPEC_NEW 1
#endif

/* Util */
14 changes: 14 additions & 0 deletions spec/ruby/optional/capi/ext/time_spec.c
Original file line number Diff line number Diff line change
@@ -63,6 +63,16 @@ static VALUE time_spec_rb_time_timespec(VALUE self, VALUE time) {
}
#endif

#ifdef HAVE_RB_TIME_TIMESPEC_NEW
static VALUE time_spec_rb_time_timespec_new(VALUE self, VALUE sec, VALUE nsec, VALUE offset) {
struct timespec ts;
ts.tv_sec = NUM2TIMET(sec);
ts.tv_nsec = NUM2LONG(nsec);

return rb_time_timespec_new(&ts, NUM2INT(offset));
}
#endif

#ifdef HAVE_TIMET2NUM
static VALUE time_spec_TIMET2NUM(VALUE self) {
time_t t = 10;
@@ -101,6 +111,10 @@ void Init_time_spec() {
#ifdef HAVE_RB_TIME_TIMESPEC
rb_define_method(cls, "rb_time_timespec", time_spec_rb_time_timespec, 1);
#endif

#ifdef HAVE_RB_TIME_TIMESPEC_NEW
rb_define_method(cls, "rb_time_timespec_new", time_spec_rb_time_timespec_new, 3);
#endif
}

#ifdef __cplusplus
30 changes: 30 additions & 0 deletions spec/ruby/optional/capi/time_spec.rb
Original file line number Diff line number Diff line change
@@ -252,4 +252,34 @@
nsec.should == t.nsec
end
end

describe "rb_time_timespec_new" do
it "returns a time object with the given timespec and UTC offset" do
@s.rb_time_timespec_new(1447087832, 476451125, 32400).should == Time.at(1447087832, 476451.125).localtime(32400)
end

describe "when offset given is within range of -86400 and 86400 (exclusive)" do
it "sets time's is_gmt to false" do
@s.rb_time_timespec_new(1447087832, 476451125, 0).gmt?.should be_false
end

it "sets time's offset to the offset given" do
@s.rb_time_timespec_new(1447087832, 476451125, 86399).gmtoff.should == 86399
end
end

it "returns time object in UTC if offset given equals INT_MAX - 1" do
@s.rb_time_timespec_new(1447087832, 476451125, 0x7ffffffe).utc?.should be_true
end

it "returns time object in localtime if offset given equals INT_MAX" do
@s.rb_time_timespec_new(1447087832, 476451125, 0x7fffffff).should == Time.at(1447087832, 476451.125).localtime
@s.rb_time_timespec_new(1447087832, 476451125, 0x7fffffff).gmtoff.should == Time.now.gmtoff
end

it "raises an ArgumentError if offset passed is not within range of -86400 and 86400 (exclusive)" do
lambda { @s.rb_time_timespec_new(1447087832, 476451125, 86400) }.should raise_error(ArgumentError)
lambda { @s.rb_time_timespec_new(1447087832, 476451125, -86400) }.should raise_error(ArgumentError)
end
end
end
19 changes: 19 additions & 0 deletions vm/capi/time.cpp
Original file line number Diff line number Diff line change
@@ -106,4 +106,23 @@ extern "C" {
struct timespec ts = capi_time_num_timespec(env, time);
return ts;
}

VALUE rb_time_timespec_new(const struct timespec *ts, int offset) {
NativeMethodEnvironment* env = NativeMethodEnvironment::get();

Time* time = Time::at(env->state(), ts->tv_sec, ts->tv_nsec);

if(-86400 < offset && offset < 86400) { /* fixed offset */
time->offset(env->state(), Fixnum::from(offset));
time->is_gmt(env->state(), cFalse);
time->zone(env->state(), cNil);
} else if(offset == INT_MAX) { /* localtime */
} else if(offset == INT_MAX - 1) { /* UTC */
time->is_gmt(env->state(), cTrue);
} else {
rb_raise(rb_eArgError, "utc_offset out of range");
}

return env->get_handle(time);
}
}
3 changes: 3 additions & 0 deletions vm/include/capi/ruby/ruby.h
Original file line number Diff line number Diff line change
@@ -2148,6 +2148,9 @@ struct RTypedData {
struct timeval rb_time_timeval(VALUE time);
struct timespec rb_time_timespec(VALUE time);

/** Returns a time object with UTC/localtime/fixed offset */
VALUE rb_time_timespec_new(const struct timespec *ts, int offset);

#define HAVE_RB_TIME_NEW 1
#define HAVE_RB_TIME_NANO_NEW 1
#define HAVE_RB_TIME_NUM_NEW 1