diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2019-08-05 17:38:53 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2019-08-05 18:37:29 -0700 |
commit | b06917a4912a60402025286d07d4a195749245c4 (patch) | |
tree | ae737916ce6c0296bfb88e3ba43df5c2b1ef0048 /lisp/calendar | |
parent | 89c63b3522b62c0fd725f0b348927a2069238452 (diff) | |
download | emacs-b06917a4912a60402025286d07d4a195749245c4.tar.gz |
decode-time now returns subsec too
The list that decode-time returns now contains an extra
trailing component that counts the subseconds part of the
original timestamp (Bug#36549).
This builds on a suggestion by Lars Ingebrigtsen in:
https://lists.gnu.org/r/emacs-devel/2019-07/msg00734.html
* doc/lispref/os.texi (Time Conversion):
* doc/misc/emacs-mime.texi (time-date):
* etc/NEWS: Document this.
* lisp/calendar/icalendar.el (icalendar--decode-isodatetime):
* lisp/calendar/iso8601.el (iso8601-parse)
(iso8601-parse-time, iso8601-parse-duration)
(iso8601--decoded-time):
* lisp/calendar/parse-time.el (parse-time-string):
* lisp/calendar/time-date.el (make-decoded-time)
(decoded-time-set-defaults):
* lisp/org/org.el (org-fix-decoded-time)
(org-parse-time-string):
* src/timefns.c (Fdecode_time):
Generate subsec member for decoded time.
* lisp/calendar/time-date.el (decoded-time-add)
Add the decoded subsec too.
* lisp/simple.el (decoded-time): New subsec member.
* src/data.c (Frem): Simplify zero-check to match that of new Fmod.
(integer_mod): New function, with most of the guts of the old Fmod.
Remove redundant zero-check.
(Fmod): Use it.
* src/timefns.c (Fencode_time): Handle new subsec member
or (with the obsolescent calling convention) subsec arg.
It defaults to 0.
* test/lisp/calendar/icalendar-tests.el:
(icalendar--decode-isodatetime):
* test/lisp/calendar/iso8601-tests.el (test-iso8601-date-years)
(test-iso8601-date-dates, test-iso8601-date-obsolete)
(test-iso8601-date-weeks, test-iso8601-date-ordinals)
(test-iso8601-time, test-iso8601-combined)
(test-iso8601-duration, test-iso8601-intervals)
(standard-test-dates, standard-test-time-of-day-fractions)
(standard-test-time-of-day-beginning-of-day)
(standard-test-time-of-day-utc)
(standard-test-time-of-day-zone)
(standard-test-date-and-time-of-day, standard-test-interval):
* test/lisp/calendar/parse-time-tests.el (parse-time-tests):
* test/src/timefns-tests.el (format-time-string-with-zone)
(encode-time-dst-numeric-zone):
Adjust to match new behavior.
Diffstat (limited to 'lisp/calendar')
-rw-r--r-- | lisp/calendar/icalendar.el | 2 | ||||
-rw-r--r-- | lisp/calendar/iso8601.el | 14 | ||||
-rw-r--r-- | lisp/calendar/parse-time.el | 10 | ||||
-rw-r--r-- | lisp/calendar/time-date.el | 14 |
4 files changed, 30 insertions, 10 deletions
diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el index c2688705e30..84f579ad44e 100644 --- a/lisp/calendar/icalendar.el +++ b/lisp/calendar/icalendar.el @@ -644,7 +644,7 @@ FIXME: multiple comma-separated values should be allowed!" ;; create the decoded date-time ;; FIXME!?! (let ((decoded-time (list second minute hour day month year - nil -1 zone))) + nil -1 zone 0))) (condition-case nil (decode-time (encode-time decoded-time)) (error diff --git a/lisp/calendar/iso8601.el b/lisp/calendar/iso8601.el index 30352c7e75f..51f5dff9091 100644 --- a/lisp/calendar/iso8601.el +++ b/lisp/calendar/iso8601.el @@ -129,7 +129,8 @@ well as variants like \"2008W32\" (week number) and (let ((time (iso8601-parse-time time-string))) (setf (decoded-time-hour date) (decoded-time-hour time)) (setf (decoded-time-minute date) (decoded-time-minute time)) - (setf (decoded-time-second date) (decoded-time-second time)))) + (setf (decoded-time-second date) (decoded-time-second time)) + (setf (decoded-time-subsec date) (decoded-time-subsec time)))) ;; The time zone is optional. (when zone-string (setf (decoded-time-zone date) @@ -236,6 +237,8 @@ well as variants like \"2008W32\" (week number) and (iso8601--decoded-time :hour hour :minute (or minute 0) :second (or second 0) + ;; FIXME: Support subsec. + :subsec 0 :zone (and zone (* 60 (iso8601-parse-zone zone))))))))) @@ -274,7 +277,9 @@ Return the number of minutes." :day (or (match-string 3 string) 0) :hour (or (match-string 5 string) 0) :minute (or (match-string 6 string) 0) - :second (or (match-string 7 string) 0))) + :second (or (match-string 7 string) 0) + ;; FIXME: Support subsec. + :subsec 0)) ;; PnW: Weeks. ((iso8601--match iso8601--duration-week-match string) (let ((weeks (string-to-number (match-string 1 string)))) @@ -336,7 +341,7 @@ Return the number of minutes." (cl-defun iso8601--decoded-time (&key second minute hour day month year - dst zone) + dst zone subsec) (list (iso8601--value second) (iso8601--value minute) (iso8601--value hour) @@ -345,7 +350,8 @@ Return the number of minutes." (iso8601--value year) nil dst - zone)) + zone + subsec)) (defun iso8601--encode-time (time) "Like `encode-time', but fill in nil values in TIME." diff --git a/lisp/calendar/parse-time.el b/lisp/calendar/parse-time.el index e28df97918e..9af93b5b1ee 100644 --- a/lisp/calendar/parse-time.el +++ b/lisp/calendar/parse-time.el @@ -27,7 +27,7 @@ ;; Emacs. However, parsing time strings is still largely a matter of ;; heuristics and no common interface has been designed. -;; `parse-time-string' parses a time in a string and returns a list of 9 +;; `parse-time-string' parses a time in a string and returns a list of ;; values, just like `decode-time', where unspecified elements in the ;; string are returned as nil (except unspecfied DST is returned as -1). ;; `encode-time' may be applied on these values to obtain an internal @@ -148,7 +148,7 @@ letters, digits, plus or minus signs or colons." ;;;###autoload (defun parse-time-string (string) - "Parse the time-string STRING into (SEC MIN HOUR DAY MON YEAR DOW DST TZ). + "Parse the time in STRING into (SEC MIN HOUR DAY MON YEAR DOW DST TZ SUBSEC). STRING should be something resembling an RFC 822 (or later) date-time, e.g., \"Fri, 25 Mar 2016 16:24:56 +0100\", but this function is somewhat liberal in what format it accepts, and will attempt to @@ -156,7 +156,7 @@ return a \"likely\" value even for somewhat malformed strings. The values returned are identical to those of `decode-time', but any unknown values other than DST are returned as nil, and an unknown DST value is returned as -1." - (let ((time (list nil nil nil nil nil nil nil -1 nil)) + (let ((time (list nil nil nil nil nil nil nil -1 nil nil)) (temp (parse-time-tokenize (downcase string)))) (while temp (let ((parse-time-elt (pop temp)) @@ -193,6 +193,10 @@ unknown DST value is returned as -1." (funcall this))) parse-time-val))) (setf (nth (pop slots) time) new-val)))))))) + ;; FIXME: Currently parse-time-string does not parse subseconds. + ;; So if seconds were found, set subseconds to zero. + (when (nth 0 time) + (setf (nth 9 time) 0)) time)) (defun parse-iso8601-time-string (date-string) diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el index 7505332011b..c22f4414201 100644 --- a/lisp/calendar/time-date.el +++ b/lisp/calendar/time-date.el @@ -423,6 +423,13 @@ changes in daylight saving time are not taken into account." (setq seconds (+ (* (or (decoded-time-hour delta) 0) 3600) (* (or (decoded-time-minute delta) 0) 60) (or (decoded-time-second delta) 0))) + (when (decoded-time-subsec delta) + (let* ((subsec (time-convert (time-add (decoded-time-subsec time) + (decoded-time-subsec delta)) + t)) + (s (time-convert subsec 'integer))) + (setq seconds (+ seconds s)) + (setf (decoded-time-subsec time) (time-subtract subsec s)))) ;; Time zone adjustments are basically the same as time adjustments. (setq seconds (+ seconds (or (decoded-time-zone delta) 0))) @@ -494,9 +501,9 @@ changes in daylight saving time are not taken into account." (cl-defun make-decoded-time (&key second minute hour day month year - dst zone) + dst zone subsec) "Return a `decoded-time' structure with only the keywords given filled out." - (list second minute hour day month year nil dst zone)) + (list second minute hour day month year nil dst zone subsec)) (defun decoded-time-set-defaults (time &optional default-zone) "Set any nil values in `decoded-time' TIME to default values. @@ -526,6 +533,9 @@ TIME is modified and returned." (when (and (not (decoded-time-zone time)) default-zone) (setf (decoded-time-zone time) 0)) + + (unless (decoded-time-subsec time) + (setf (decoded-time-subsec time) 0)) time) (provide 'time-date) |