From c632332053caaf0f08ccb9bc26183a4bc7c3f2c2 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 8 Jul 2019 17:22:01 +0200 Subject: Use decoded time math to be able to parse intervals --- lisp/calendar/iso8601.el | 15 +++++++++------ lisp/calendar/time-date.el | 10 ++++++++-- test/lisp/calendar/iso8601-tests.el | 14 +++++--------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/lisp/calendar/iso8601.el b/lisp/calendar/iso8601.el index 79e1403802a..5619067a433 100644 --- a/lisp/calendar/iso8601.el +++ b/lisp/calendar/iso8601.el @@ -261,13 +261,16 @@ Return the number of minutes." (t (signal 'wrong-type-argument string)))) (unless end - (setq end (decode-time (time-add (encode-time start) - (encode-time duration)) - (decoded-time-zone start)))) + (setq end (decoded-time-add start duration))) (unless start - (setq start (decode-time (time-subtract (encode-time end) - (encode-time duration)) - (decoded-time-zone end)))) + (setq start (decoded-time-add end + ;; We negate the duration so that + ;; we get a subtraction. + (mapcar (lambda (elem) + (if (numberp elem) + (- elem) + elem)) + duration)))) (list start end (or duration (decode-time (time-subtract (encode-time end) diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el index 4fbb3c59476..35c89a2ceac 100644 --- a/lisp/calendar/time-date.el +++ b/lisp/calendar/time-date.el @@ -386,7 +386,10 @@ decreased to be valid (\"add one month\" to January 31st will yield a result of February 28th (or 29th, depending on the leap year status). -Fields are added in a most to least significant order." +Fields are added in a most to least significant order. + +When changing the time bits in TIME (i.e., second/minute/hour), +changes in daylight saving time are not taken into account." (let ((time (copy-sequence time)) seconds) ;; Years are simple. @@ -399,7 +402,7 @@ Fields are added in a most to least significant order." (setf (decoded-time-month time) (mod new 12)) (cl-incf (decoded-time-year time) (/ new 12)))) - ;; Adjust for month length. + ;; Adjust for month length (as described in the doc string). (setf (decoded-time-day time) (min (date-days-in-month (decoded-time-year time) (decoded-time-month time)) @@ -427,6 +430,7 @@ Fields are added in a most to least significant order." time)) (defun decoded-time--alter-month (time increase) + "Increase or decrease the month in TIME by 1." (if increase (progn (cl-incf (decoded-time-month time)) @@ -439,6 +443,7 @@ Fields are added in a most to least significant order." (cl-decf (decoded-time-year time))))) (defun decoded-time--alter-day (time increase) + "Increase or decrease the day in TIME by 1." (if increase (progn (cl-incf (decoded-time-day time)) @@ -455,6 +460,7 @@ Fields are added in a most to least significant order." (decoded-time-month time)))))) (defun decoded-time--alter-second (time seconds increase) + "Increase or decrease the time in TIME by SECONDS." (let ((old (+ (* (or (decoded-time-hour time) 0) 3600) (* (or (decoded-time-minute time) 0) 60) (or (decoded-time-second time) 0)))) diff --git a/test/lisp/calendar/iso8601-tests.el b/test/lisp/calendar/iso8601-tests.el index b33f38f03fd..29f599bc338 100644 --- a/test/lisp/calendar/iso8601-tests.el +++ b/test/lisp/calendar/iso8601-tests.el @@ -98,16 +98,12 @@ (0 30 15 11 5 2008 nil nil 0) ;; Hm... can't really use decode-time for time differences... (0 30 2 14 3 1971 0 nil 0)))) - (should - (equal (iso8601-parse-interval "2007-03-01T13:00:00Z/P1Y2M10DT2H30M") - '((0 0 13 1 3 2007 nil nil 0) - ;; Well, that's wrong... - (0 47 14 10 4 38 6 nil 0) - (0 30 2 10 2 1 nil nil nil)))) + (should (equal (iso8601-parse-interval "2007-03-01T13:00:00Z/P1Y2M10DT2H30M") + '((0 0 13 1 3 2007 nil nil 0) + (0 30 15 11 5 2008 nil nil 0) + (0 30 2 10 2 1 nil nil nil)))) (should (equal (iso8601-parse-interval "P1Y2M10DT2H30M/2008-05-11T15:30:00Z") - ;; I think I have to add decoded-time math functions, - ;; really. - '((0 43 13 1 4 3977 5 nil 0) + '((0 0 13 1 3 2007 nil nil 0) (0 30 15 11 5 2008 nil nil 0) (0 30 2 10 2 1 nil nil nil))))) -- cgit v1.2.1