@defun time-less-p t1 t2
This returns @code{t} if time value @var{t1} is less than time value
@var{t2}.
+The result is @code{nil} if either argument is a NaN.
+@end defun
+
+@defun time-equal t1 t2
+This returns @code{t} if @var{t1} and @var{t2} are equal time values.
+The result is @code{nil} if either argument is a NaN.
@end defun
@defun time-subtract t1 t2
This returns the time difference @var{t1} @minus{} @var{t2} between
-two time values, as a time value. If you need the difference in units
+two time values, as a time value. However, the result is a float
+if either argument is a float infinity or NaN@.
+If you need the difference in units
of elapsed seconds, use @code{float-time} (@pxref{Time of Day,
float-time}) to convert the result into seconds.
@end defun
@defun time-add t1 t2
This returns the sum of two time values, as a time value.
+However, the result is a float if either argument is a float infinity or NaN@.
One argument should represent a time difference rather than a point in time,
either as a list or as a single number of elapsed seconds.
Here is how to add a number of seconds to a time value:
}
static Lisp_Object
-time_arith (Lisp_Object a, Lisp_Object b,
- struct lisp_time (*op) (struct lisp_time, struct lisp_time))
+time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
{
+ if (FLOATP (a) && !isfinite (XFLOAT_DATA (a)))
+ {
+ double da = XFLOAT_DATA (a);
+ double db = XFLOAT_DATA (Ffloat_time (b));
+ return make_float (subtract ? da - db : da + db);
+ }
+ if (FLOATP (b) && !isfinite (XFLOAT_DATA (b)))
+ return subtract ? make_float (-XFLOAT_DATA (b)) : b;
+
int alen, blen;
struct lisp_time ta = lisp_time_struct (a, &alen);
struct lisp_time tb = lisp_time_struct (b, &blen);
- struct lisp_time t = op (ta, tb);
+ struct lisp_time t = (subtract ? time_subtract : time_add) (ta, tb);
if (FIXNUM_OVERFLOW_P (t.hi))
time_overflow ();
Lisp_Object val = Qnil;
See `current-time-string' for the various forms of a time value. */)
(Lisp_Object a, Lisp_Object b)
{
- return time_arith (a, b, time_add);
+ return time_arith (a, b, false);
}
DEFUN ("time-subtract", Ftime_subtract, Stime_subtract, 2, 2, 0,
See `current-time-string' for the various forms of a time value. */)
(Lisp_Object a, Lisp_Object b)
{
- return time_arith (a, b, time_subtract);
+ return time_arith (a, b, true);
+}
+
+/* Return negative, 0, positive if a < b, a == b, a > b respectively.
+ Return positive if either a or b is a NaN; this is good enough
+ for the current callers. */
+static int
+time_cmp (Lisp_Object a, Lisp_Object b)
+{
+ if ((FLOATP (a) && !isfinite (XFLOAT_DATA (a)))
+ || (FLOATP (b) && !isfinite (XFLOAT_DATA (b))))
+ {
+ double da = FLOATP (a) ? XFLOAT_DATA (a) : 0;
+ double db = FLOATP (b) ? XFLOAT_DATA (b) : 0;
+ return da < db ? -1 : da != db;
+ }
+
+ int alen, blen;
+ struct lisp_time ta = lisp_time_struct (a, &alen);
+ struct lisp_time tb = lisp_time_struct (b, &blen);
+ return (ta.hi != tb.hi ? (ta.hi < tb.hi ? -1 : 1)
+ : ta.lo != tb.lo ? (ta.lo < tb.lo ? -1 : 1)
+ : ta.us != tb.us ? (ta.us < tb.us ? -1 : 1)
+ : ta.ps < tb.ps ? -1 : ta.ps != tb.ps);
}
DEFUN ("time-less-p", Ftime_less_p, Stime_less_p, 2, 2, 0,
See `current-time-string' for the various forms of a time value. */)
(Lisp_Object t1, Lisp_Object t2)
{
- int t1len, t2len;
- struct lisp_time a = lisp_time_struct (t1, &t1len);
- struct lisp_time b = lisp_time_struct (t2, &t2len);
- return ((a.hi != b.hi ? a.hi < b.hi
- : a.lo != b.lo ? a.lo < b.lo
- : a.us != b.us ? a.us < b.us
- : a.ps < b.ps)
- ? Qt : Qnil);
+ return time_cmp (t1, t2) < 0 ? Qt : Qnil;
+}
+
+DEFUN ("time-equal", Ftime_equal, Stime_equal, 2, 2, 0,
+ doc: /* Return non-nil if T1 and T2 are equal time values. */)
+ (Lisp_Object t1, Lisp_Object t2)
+{
+ return time_cmp (t1, t2) == 0 ? Qt : Qnil;
}
defsubr (&Scurrent_time);
defsubr (&Stime_add);
defsubr (&Stime_subtract);
+ defsubr (&Stime_equal);
defsubr (&Stime_less_p);
defsubr (&Sget_internal_run_time);
defsubr (&Sformat_time_string);