Example #1
0
  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;
  }
Example #2
0
  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;
  }
Example #3
0
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;
}
Example #4
0
  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;
  }