Time* Time::specific(STATE, Object* self, Integer* sec, Integer* nsec, Object* gmt) { Time* tm = state->new_object<Time>(as<Class>(self)); if(sizeof(time_t) == sizeof(long long)) { tm->seconds_ = sec->to_long_long(); tm->nanoseconds_ = nsec->to_long_long(); } else { tm->seconds_ = sec->to_native(); tm->nanoseconds_ = nsec->to_native(); } // Do a little overflow cleanup. if(tm->nanoseconds_ >= 1000000000) { tm->seconds_ += tm->nanoseconds_ / 1000000000; tm->nanoseconds_ %= 1000000000; } if(tm->nanoseconds_ < 0) { tm->seconds_ += NDIV(tm->nanoseconds_, 1000000000); tm->nanoseconds_ = NMOD(tm->nanoseconds_, 1000000000); } if(LANGUAGE_18_ENABLED(state)) { tm->nanoseconds_ -= (tm->nanoseconds_ % 1000); } tm->is_gmt(state, CBOOL(gmt) ? cTrue : cFalse); return tm; }
Time* Time::specific(STATE, Object* self, Integer* sec, Integer* nsec, Object* gmt, Object* offset) { Time* tm = state->new_object_dirty<Time>(as<Class>(self)); tm->seconds_ = sec->to_long_long(); tm->nanoseconds_ = nsec->to_native(); // Do a little overflow cleanup. if(tm->nanoseconds_ >= 1000000000) { tm->seconds_ += tm->nanoseconds_ / 1000000000; tm->nanoseconds_ %= 1000000000; } if(tm->nanoseconds_ < 0) { tm->seconds_ += NDIV(tm->nanoseconds_, 1000000000); tm->nanoseconds_ = NMOD(tm->nanoseconds_, 1000000000); } tm->decomposed(state, nil<Array>()); tm->is_gmt(state, RBOOL(CBOOL(gmt))); tm->offset(state, offset); tm->zone(state, nil<String>()); return tm; }
Time* Time::specific(STATE, Integer* sec, Integer* usec, Object* gmt) { Time* tm = state->new_object<Time>(G(time_class)); if(sizeof(time_t) == sizeof(long long)) { tm->seconds_ = sec->to_long_long(); tm->microseconds_ = usec->to_long_long(); } else { tm->seconds_ = sec->to_native(); tm->microseconds_ = usec->to_native(); } // Do a little overflow cleanup. if(tm->microseconds_ >= 1000000) { tm->seconds_ += tm->microseconds_ / 1000000; tm->microseconds_ %= 1000000; } if(tm->microseconds_ < 0) { tm->seconds_ += NDIV(tm->microseconds_,1000000); tm->microseconds_ = NMOD(tm->microseconds_, 1000000); } tm->is_gmt(state, RTEST(gmt) ? Qtrue : Qfalse); return tm; }
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* offset_sec, Fixnum* offset_nsec) { struct tm64 tm; tm.tm_sec = sec->to_native(); if(tm.tm_sec < 0 || tm.tm_sec > 60) { Exception::argument_error(state, "sec must be in 0..60"); } tm.tm_min = min->to_native(); if(tm.tm_min < 0 || tm.tm_min > 60) { Exception::argument_error(state, "min must be in 0..60"); } tm.tm_hour = hour->to_native(); if(tm.tm_hour < 0 || tm.tm_hour > 24) { Exception::argument_error(state, "hour must be in 0..24"); } tm.tm_mday = mday->to_native(); if(tm.tm_mday < 1 || tm.tm_mday > 31) { Exception::argument_error(state, "mday must be in 1..31"); } tm.tm_mon = mon->to_native() - 1; if(tm.tm_mon < 0 || tm.tm_mon > 11) { Exception::argument_error(state, "mon must be in 0..11"); } tm.tm_wday = -1; tm.tm_gmtoff = 0; tm.tm_zone = 0; tm.tm_year = year->to_long_long(); tm.tm_isdst = isdst->to_native(); time64_t seconds = -1; if(CBOOL(from_gmt) || !offset->nil_p()) { seconds = ::timegm64(&tm); } else { tzset(); seconds = ::timelocal64(&tm); } Time* obj = state->new_object_dirty<Time>(as<Class>(self)); obj->seconds_ = seconds; obj->nanoseconds_ = nsec->to_native(); obj->is_gmt(state, RBOOL(CBOOL(from_gmt))); if(!offset->nil_p()) { obj->seconds_ -= offset_sec->to_long_long(); 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); } else { obj->offset(state, nil<Fixnum>()); } obj->decomposed(state, nil<Array>()); obj->zone(state, nil<String>()); return obj; }