time.c:965
static VALUE
time_minus(time1, time2)
    VALUE time1, time2;
{
    struct time_object *tobj;
    time_t sec, usec;
    double f, d, v;

    GetTimeval(time1, tobj);
    if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {
	struct time_object *tobj2;

	GetTimeval(time2, tobj2);
	f = (double)tobj->tv.tv_sec - (double)tobj2->tv.tv_sec;
	f += ((double)tobj->tv.tv_usec - (double)tobj2->tv.tv_usec)*1e-6;
	/* XXX: should check float overflow on 64bit time_t platforms */

	return rb_float_new(f);
    }
    v = NUM2DBL(time2);
    d = modf(v, &f);
    sec = (time_t)f;
    if (f != (double)sec) {
	rb_raise(rb_eRangeError, "time - %f out of Time range", v);
    }
#ifndef NEGATIVE_TIME_T
    if (f > 0 && f >= tobj->tv.tv_sec) {
	rb_raise(rb_eArgError, "time must be positive");
    }
#endif
    usec = tobj->tv.tv_usec - (time_t)(d*1e6);
    sec = tobj->tv.tv_sec - (time_t)f;
#ifdef NEGATIVE_TIME_T
    if ((tobj->tv.tv_sec <= 0 && f >= 0 && sec > 0) ||
	(tobj->tv.tv_sec >= 0 && f <= 0 && sec < 0)) {
	rb_raise(rb_eRangeError, "time - %f out of Time range", v);
    }
#endif

    time2 = rb_time_new(sec, usec);
    if (tobj->gmt) {
	GetTimeval(time2, tobj);
	tobj->gmt = 1;
    }
    return time2;
}
