summaryrefslogtreecommitdiff
path: root/lisp/calendar
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2019-08-05 17:38:53 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2019-08-05 18:37:29 -0700
commitb06917a4912a60402025286d07d4a195749245c4 (patch)
treeae737916ce6c0296bfb88e3ba43df5c2b1ef0048 /lisp/calendar
parent89c63b3522b62c0fd725f0b348927a2069238452 (diff)
downloademacs-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.el2
-rw-r--r--lisp/calendar/iso8601.el14
-rw-r--r--lisp/calendar/parse-time.el10
-rw-r--r--lisp/calendar/time-date.el14
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)