unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* The format of time values in lisp/calendar/time-date.el.
@ 2005-03-14 14:51 Lute Kamstra
  2005-03-14 23:43 ` Richard Stallman
  0 siblings, 1 reply; 3+ messages in thread
From: Lute Kamstra @ 2005-03-14 14:51 UTC (permalink / raw)


The various function in time-date.el seem to use different formats for
their arguments.  According to the node Time Calculations in the Lisp
Manual, the following functions should use the format (HIGH LOW MICRO)
to specify HIGH * 65536 + LOW + MICRO / 1000000 seconds:

- time-less-p
- time-subtract
- time-add
- time-to-days
- time-to-day-in-year

However, in reality:

- time-less-p expects (HIGH LOW) for its arguments
- time-subtract expects (HIGH LOW) for its arguments and returns (HIGH
  LOW) as well
- time-add expects either (HIGH LOW MICRO), (HIGH LOW), or (HIGH .
  LOW) and returns (HIGH LOW MICRO).
- time-to-days and time-to-day-in-year use decode-time on its argument.
  decode-time expects (HIGH LOW . IGNORED) or (HIGH . LOW).

Was there an evolution in format from (HIGH . LOW), via (HIGH LOW), to
(HIGH LOW MICRO)?

Shall I fix time-less-p and time-subtract to deal with (HIGH LOW
MICRO) arguments as well?

Should they deal with (HIGH . LOW) too?

What about the return value of time-subtract (and time-add): should it
be backward compatible in the sense that it returns (HIGH LOW) if both
its arguments are of that format?

Lute.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: The format of time values in lisp/calendar/time-date.el.
  2005-03-14 14:51 The format of time values in lisp/calendar/time-date.el Lute Kamstra
@ 2005-03-14 23:43 ` Richard Stallman
  2005-03-16 17:01   ` Lute Kamstra
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Stallman @ 2005-03-14 23:43 UTC (permalink / raw)
  Cc: emacs-devel

    Was there an evolution in format from (HIGH . LOW), via (HIGH LOW), to
    (HIGH LOW MICRO)?

Yes.  Both (HIGH LOW) and (HIGH LOW MICRO) are valid now.
It is useful to accept (HIGH . LOW) as well.

    Shall I fix time-less-p and time-subtract to deal with (HIGH LOW
    MICRO) arguments as well?

Yes, please do.

    Should they deal with (HIGH . LOW) too?

It would not be a bad thing.

    What about the return value of time-subtract (and time-add): should it
    be backward compatible in the sense that it returns (HIGH LOW) if both
    its arguments are of that format?

Yes.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: The format of time values in lisp/calendar/time-date.el.
  2005-03-14 23:43 ` Richard Stallman
@ 2005-03-16 17:01   ` Lute Kamstra
  0 siblings, 0 replies; 3+ messages in thread
From: Lute Kamstra @ 2005-03-16 17:01 UTC (permalink / raw)
  Cc: emacs-devel

Richard Stallman <rms@gnu.org> writes:

>     Was there an evolution in format from (HIGH . LOW), via (HIGH LOW), to
>     (HIGH LOW MICRO)?
>
> Yes.  Both (HIGH LOW) and (HIGH LOW MICRO) are valid now.
> It is useful to accept (HIGH . LOW) as well.
>
>     Shall I fix time-less-p and time-subtract to deal with (HIGH LOW
>     MICRO) arguments as well?
>
> Yes, please do.
>
>     Should they deal with (HIGH . LOW) too?
>
> It would not be a bad thing.
>
>     What about the return value of time-subtract (and time-add): should it
>     be backward compatible in the sense that it returns (HIGH LOW) if both
>     its arguments are of that format?
>
> Yes.

Done.  Any objections to this patch?

Lute.


Index: lisp/ChangeLog
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/ChangeLog,v
retrieving revision 1.7106
diff -c -r1.7106 ChangeLog
*** lisp/ChangeLog	16 Mar 2005 13:21:20 -0000	1.7106
--- lisp/ChangeLog	16 Mar 2005 16:54:07 -0000
***************
*** 1,3 ****
--- 1,12 ----
+ 2005-03-16  Lute Kamstra  <lute@gnu.org>
+ 
+ 	* calendar/time-date.el: Add comment on time value formats.  Don't
+ 	require parse-time.
+ 	(time-to-seconds, time-less-p, time-since, time-subtract)
+ 	(time-add, time-to-number-of-days): Deal with all three formats of
+ 	time values.
+ 	(days-to-time): Return a valid time value when arg is huge.
+ 
  2005-03-16  Glenn Morris  <gmorris@ast.cam.ac.uk>
  
  	* calendar/diary-lib.el (mark-diary-entries): Use new optional
Index: lisp/calendar/time-date.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/calendar/time-date.el,v
retrieving revision 1.9
diff -c -r1.9 time-date.el
*** lisp/calendar/time-date.el	4 Sep 2004 13:13:48 -0000	1.9
--- lisp/calendar/time-date.el	16 Mar 2005 16:51:28 -0000
***************
*** 1,5 ****
  ;;; time-date.el --- date and time handling functions
! ;; Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
  
  ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
  ;;	Masanobu Umeda <umerin@mse.kyutech.ac.jp>
--- 1,5 ----
  ;;; time-date.el --- date and time handling functions
! ;; Copyright (C) 1998, 1999, 2000, 2004, 2005 Free Software Foundation, Inc.
  
  ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
  ;;	Masanobu Umeda <umerin@mse.kyutech.ac.jp>
***************
*** 24,32 ****
  
  ;;; Commentary:
  
! ;;; Code:
  
! (require 'parse-time)
  
  (autoload 'timezone-make-date-arpa-standard "timezone")
  
--- 24,41 ----
  
  ;;; Commentary:
  
! ;; Time values come in three formats.  The oldest format is a cons
! ;; cell of the form (HIGH . LOW).  This format is obsolete, but still
! ;; supported.  The two other formats are the lists (HIGH LOW) and
! ;; (HIGH LOW MICRO).  The first two formats specify HIGH * 2^16 + LOW
! ;; seconds; the third format specifies HIGH * 2^16 + LOW + MICRO /
! ;; 1000000 seconds.  We should have 0 <= MICRO < 1000000 and 0 <= LOW
! ;; < 2^16.  If the time value represents a point in time, then HIGH is
! ;; nonnegative.  If the time value is a time difference, then HIGH can
! ;; be negative as well.  See `time-subtract' for an example of how to
! ;; deal with these three formats.
  
! ;;; Code:
  
  (autoload 'timezone-make-date-arpa-standard "timezone")
  
***************
*** 49,81 ****
  (defun time-to-seconds (time)
    "Convert time value TIME to a floating point number.
  You can use `float-time' instead."
!   (+ (* (car time) 65536.0)
!      (cadr time)
!      (/ (or (nth 2 time) 0) 1000000.0)))
  
  ;;;###autoload
  (defun seconds-to-time (seconds)
    "Convert SECONDS (a floating point number) to a time value."
!   (list (floor seconds 65536)
! 	(floor (mod seconds 65536))
  	(floor (* (- seconds (ffloor seconds)) 1000000))))
  
  ;;;###autoload
  (defun time-less-p (t1 t2)
    "Say whether time value T1 is less than time value T2."
!   (or (< (car t1) (car t2))
!       (and (= (car t1) (car t2))
! 	   (< (nth 1 t1) (nth 1 t2)))))
  
  ;;;###autoload
  (defun days-to-time (days)
    "Convert DAYS into a time value."
    (let* ((seconds (* 1.0 days 60 60 24))
! 	 (rest (expt 2 16))
! 	 (ms (condition-case nil (floor (/ seconds rest))
! 	       (range-error (expt 2 16)))))
!     (list ms (condition-case nil (round (- seconds (* ms rest)))
! 	       (range-error (expt 2 16))))))
  
  ;;;###autoload
  (defun time-since (time)
--- 58,104 ----
  (defun time-to-seconds (time)
    "Convert time value TIME to a floating point number.
  You can use `float-time' instead."
!   (+ (* 1.0 (pop time) #x10000)
!      (if (consp time) (pop time) time)
!      (/ (if (numberp (car-safe time))
! 	    (car time)
! 	  0)
! 	1000000.0)))
  
  ;;;###autoload
  (defun seconds-to-time (seconds)
    "Convert SECONDS (a floating point number) to a time value."
!   (list (floor seconds #x10000)
! 	(floor (mod seconds #x10000))
  	(floor (* (- seconds (ffloor seconds)) 1000000))))
  
  ;;;###autoload
  (defun time-less-p (t1 t2)
    "Say whether time value T1 is less than time value T2."
!   (let* ((high1 (pop t1))
! 	 (low1 (if (consp t1) (pop t1) t1))
! 	 (micro1 (if (numberp (car-safe t1))
! 		     (car t1)
! 		   0))
! 	 (high2 (pop t2))
! 	 (low2 (if (consp t2) (pop t2) t2))
! 	 (micro2 (if (numberp (car-safe t2))
! 		     (car t2)
! 		   0)))
!     (or (< high1 high2)
! 	(and (= high1 high2)
! 	     (or (< low1 low2)
! 		 (and (= low1 low2)
! 		      (< micro1 micro2)))))))
  
  ;;;###autoload
  (defun days-to-time (days)
    "Convert DAYS into a time value."
    (let* ((seconds (* 1.0 days 60 60 24))
! 	 (high (condition-case nil (floor (/ seconds #x10000))
! 		 (range-error most-positive-fixnum))))
!     (list high (condition-case nil (floor (- seconds (* 1.0 high #x10000)))
! 		 (range-error #xffff)))))
  
  ;;;###autoload
  (defun time-since (time)
***************
*** 84,94 ****
    (when (stringp time)
      ;; Convert date strings to internal time.
      (setq time (date-to-time time)))
!   (let* ((current (current-time))
! 	 (rest (when (< (nth 1 current) (nth 1 time))
! 		 (expt 2 16))))
!     (list (- (+ (car current) (if rest -1 0)) (car time))
! 	  (- (+ (or rest 0) (nth 1 current)) (nth 1 time)))))
  
  ;;;###autoload
  (defalias 'subtract-time 'time-subtract)
--- 107,113 ----
    (when (stringp time)
      ;; Convert date strings to internal time.
      (setq time (date-to-time time)))
!   (time-subtract (current-time) time))
  
  ;;;###autoload
  (defalias 'subtract-time 'time-subtract)
***************
*** 97,133 ****
  (defun time-subtract (t1 t2)
    "Subtract two time values.
  Return the difference in the format of a time value."
!   (let ((borrow (< (cadr t1) (cadr t2))))
!     (list (- (car t1) (car t2) (if borrow 1 0))
! 	  (- (+ (if borrow 65536 0) (cadr t1)) (cadr t2)))))
  
  ;;;###autoload
  (defun time-add (t1 t2)
    "Add two time values.  One should represent a time difference."
!   (let ((high (car t1))
! 	(low (if (consp (cdr t1)) (nth 1 t1) (cdr t1)))
! 	(micro (if (numberp (car-safe (cdr-safe (cdr t1))))
! 		   (nth 2 t1)
! 		 0))
! 	(high2 (car t2))
! 	(low2 (if (consp (cdr t2)) (nth 1 t2) (cdr t2)))
! 	(micro2 (if (numberp (car-safe (cdr-safe (cdr t2))))
! 		    (nth 2 t2)
! 		  0)))
!     ;; Add
!     (setq micro (+ micro micro2))
!     (setq low (+ low low2))
!     (setq high (+ high high2))
! 
!     ;; Normalize
!     ;; `/' rounds towards zero while `mod' returns a positive number,
!     ;; so we can't rely on (= a (+ (* 100 (/ a 100)) (mod a 100))).
!     (setq low (+ low (/ micro 1000000) (if (< micro 0) -1 0)))
!     (setq micro (mod micro 1000000))
!     (setq high (+ high (/ low 65536) (if (< low 0) -1 0)))
!     (setq low (logand low 65535))
! 
!     (list high low micro)))
  
  ;;;###autoload
  (defun date-to-day (date)
--- 116,169 ----
  (defun time-subtract (t1 t2)
    "Subtract two time values.
  Return the difference in the format of a time value."
!   (let* ((high (- (pop t1) (pop t2)))
! 	 (low (- (if (consp t1) (pop t1) t1)
! 		 (if (consp t2) (pop t2) t2)))
! 	 (micro (- (if (numberp (car-safe t1))
! 		       (car t1)
! 		     0)
! 		   (if (numberp (car-safe t2))
! 		       (car t2)
! 		     0))))
!     (when (< micro 0)
!       (setq low (1- low)
! 	    micro (+ micro 1000000)))
!     (when (< low 0)
!       (setq high (1- high)
! 	    low (+ low #x10000)))
!     (cons high
! 	  (if (or (consp t1) (consp t2))
! 	      (cons low
! 		    (when (or (numberp (car-safe t1))
! 			      (numberp (car-safe t2)))
! 		      (list micro)))
! 	    low))))
  
  ;;;###autoload
  (defun time-add (t1 t2)
    "Add two time values.  One should represent a time difference."
!   (let* ((high (+ (pop t1) (pop t2)))
! 	 (low (+ (if (consp t1) (pop t1) t1)
! 		 (if (consp t2) (pop t2) t2)))
! 	 (micro (+ (if (numberp (car-safe t1))
! 		       (car t1)
! 		     0)
! 		   (if (numberp (car-safe t2))
! 		       (car t2)
! 		     0))))
!     (when (>= micro 1000000)
!       (setq low (1+ low)
! 	    micro (- micro 1000000)))
!     (when (>= low #x10000)
!       (setq high (1+ high)
! 	    low (- low #x10000)))
!     (cons high
! 	  (if (or (consp t1) (consp t2))
! 	      (cons low
! 		    (when (or (numberp (car-safe t1))
! 			      (numberp (car-safe t2)))
! 		      (list micro)))
! 	    low))))
  
  ;;;###autoload
  (defun date-to-day (date)
***************
*** 180,186 ****
  (defun time-to-number-of-days (time)
    "Return the number of days represented by TIME.
  The number of days will be returned as a floating point number."
!   (/ (+ (* 1.0 65536 (car time)) (cadr time)) (* 60 60 24)))
  
  ;;;###autoload
  (defun safe-date-to-time (date)
--- 216,222 ----
  (defun time-to-number-of-days (time)
    "Return the number of days represented by TIME.
  The number of days will be returned as a floating point number."
!   (/ (time-to-seconds time) (* 60 60 24)))
  
  ;;;###autoload
  (defun safe-date-to-time (date)

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2005-03-16 17:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-03-14 14:51 The format of time values in lisp/calendar/time-date.el Lute Kamstra
2005-03-14 23:43 ` Richard Stallman
2005-03-16 17:01   ` Lute Kamstra

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).