bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#52209: 28.0.60; [PATCH] date-to-time fails on pure dates


From: Bob Rogers
Subject: bug#52209: 28.0.60; [PATCH] date-to-time fails on pure dates
Date: Tue, 30 Nov 2021 15:55:41 -0500

   In the emacs-28 branch at 0dd3883def:

   Imagine my surprise when evaluating

        (days-between "2021-10-22" "2020-09-29")

returned zero.  The root cause is that passing any date string without a
time to date-to-time produces the same return value:

        (date-to-time "2021-10-22") => (14445 17280)
        (date-to-time "2020-09-29") => (14445 17280)

But:

        (date-to-time "2020-09-29 23:15") => (24435 63540)

There are really two bugs here (or maybe three, depending on how you
look at it):

   1.  If parsing throws an error that is not an overflow, it passes the
date through timezone-make-date-arpa-standard to try to fix some cases
that parse-time-string can't handle.  But the condition-case is also
wrapped around the encode-time call, which gets a wrong-type-argument
error when it sees nil time values for HH:MM, so the fallback gets used
for something other than a parsing error.

   2.  When timezone-make-date-arpa-standard gets something it can't
handle, it "canonicalizes" the value to "31 Dec 1999 19:00:00 -0500",
which is the source of the constant result.  That may be worth another
bug report, but I'm not sure of its charter; maybe that's correct
behavior in context.

   The attached patch adds decoded-time-set-defaults, moves that and the
encode-time call outside the condition-case, and disables the fallback
to timezone-make-date-arpa-standard if the date appears not to have a
time value.  And I can now tell you there are 388 days between
2020-09-29 and 2021-10-22.

                                        -- Bob Rogers
                                           http://www.rgrjr.com/

diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el
index 155c34927f..6407138953 100644
--- a/lisp/calendar/time-date.el
+++ b/lisp/calendar/time-date.el
@@ -153,19 +153,25 @@ date-to-time
   "Parse a string DATE that represents a date-time and return a time value.
 DATE should be in one of the forms recognized by `parse-time-string'.
 If DATE lacks timezone information, GMT is assumed."
-  (condition-case err
-      (encode-time (parse-time-string date))
-    (error
-     (let ((overflow-error '(error "Specified time is not representable")))
-       (if (equal err overflow-error)
-          (signal (car err) (cdr err))
-        (condition-case err
-            (encode-time (parse-time-string
-                          (timezone-make-date-arpa-standard date)))
-          (error
-           (if (equal err overflow-error)
-               (signal (car err) (cdr err))
-             (error "Invalid date: %s" date)))))))))
+  ;; Pass the result of parsing through decoded-time-set-defaults
+  ;; because encode-time signals if HH:MM:SS are not filled in.
+  (encode-time
+    (decoded-time-set-defaults
+      (condition-case err
+          (parse-time-string date)
+        (error
+         (let ((overflow-error '(error "Specified time is not representable")))
+           (if (or (equal err overflow-error)
+                   ;; timezone-make-date-arpa-standard misbehaves if
+                   ;; not given at least HH:MM as part of the date.
+                   (not (string-match ":" date)))
+               (signal (car err) (cdr err))
+             (condition-case err
+                 (parse-time-string (timezone-make-date-arpa-standard date))
+               (error
+                (if (equal err overflow-error)
+                    (signal (car err) (cdr err))
+                  (error "Invalid date: %s" date)))))))))))
 
 ;;;###autoload
 (defalias 'time-to-seconds 'float-time)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]