From cb0f4f00b328a561e49538bbf0f90050eac1ba20 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 4 Dec 2021 10:33:32 -0800 Subject: [PATCH] Fix (date-to-time "2021-12-04") This should complete the fix for Bug#52209. * lisp/calendar/time-date.el (date-to-time): Apply decoded-time-set-defaults only to the output of (parse-time-string date), and only when the output has a year (to avoid confusion when dates lack years). There is no point applying it after timezone-make-date-arpa-standard since the latter fills in all the blanks. And the former code mistakenly called encode-time on an already-encoded time. This goes back to the code a couple of days ago, except with changed behavior (to fix Bug#52209) only when timezone-make-date-arpa-standard is not called. * test/lisp/calendar/time-date-tests.el (test-date-to-time) (test-days-between): New tests. --- doc/lispref/os.texi | 3 ++- etc/NEWS | 4 +++ lisp/calendar/time-date.el | 38 +++++++++++---------------- test/lisp/calendar/time-date-tests.el | 7 +++++ 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index e420644cd8..b4efc44b03 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -1724,7 +1724,8 @@ Time Parsing corresponding Lisp timestamp. The argument @var{string} should represent a date-time, and should be in one of the forms recognized by @code{parse-time-string} (see below). This function assumes Universal -Time if @var{string} lacks explicit time zone information. +Time if @var{string} lacks explicit time zone information, +and assumes earliest values if @var{string} lacks month, day, or time. The operating system limits the range of time and zone values. @end defun diff --git a/etc/NEWS b/etc/NEWS index ac1787d7f8..2b4eaaf8a1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1084,6 +1084,10 @@ cookies set by web pages on disk. ** New variable 'help-buffer-under-preparation'. This variable is bound to t during the preparation of a "*Help*" buffer. ++++ +** 'date-to-time' now assumes earliest values if its argument lacks +month, day, or time. For example, (date-to-time "2021-12-04") now +assumes a time of 00:00 instead of signaling an error. * Changes in Emacs 29.1 on Non-Free Operating Systems diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el index 8a6ee0f270..37a16d3b98 100644 --- a/lisp/calendar/time-date.el +++ b/lisp/calendar/time-date.el @@ -153,28 +153,22 @@ 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." - ;; 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 - (let ((time (parse-time-string date))) - (prog1 time - ;; Cause an error if data `parse-time-string' returns is invalid. - (setq time (encode-time time)))) - (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))))))))))) + (condition-case err + (let ((parsed (parse-time-string date))) + (when (decoded-time-year parsed) + (decoded-time-set-defaults parsed)) + (encode-time parsed)) + (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))))))))) ;;;###autoload (defalias 'time-to-seconds 'float-time) diff --git a/test/lisp/calendar/time-date-tests.el b/test/lisp/calendar/time-date-tests.el index 4568947c0b..d5269804ad 100644 --- a/test/lisp/calendar/time-date-tests.el +++ b/test/lisp/calendar/time-date-tests.el @@ -41,6 +41,13 @@ test-obsolete-encode-time-value (encode-time-value 1 2 3 4 3)) '(1 2 3 4)))) +(ert-deftest test-date-to-time () + (should (equal (format-time-string "%F %T" (date-to-time "2021-12-04")) + "2021-12-04 00:00:00"))) + +(ert-deftest test-days-between () + (should (equal (days-between "2021-10-22" "2020-09-29") 388))) + (ert-deftest test-leap-year () (should-not (date-leap-year-p 1999)) (should-not (date-leap-year-p 1900)) -- 2.32.0