Subject: bug#74869: [PATCH] Add predicates for decoded times and time deltas

From: Richard Lawrence <[email-masked]>
Date: Sat, 14 Dec 2024 17:11:41 +0100

Tags: patch

This is a rough draft of a patch to add two new predicates related to
decoded times: `decoded-time-p', which checks that a value is a decoded
time (as documented in `decode-time'), and
`decoded-time-delta-p', which checks that a value is a time delta (as
documented in `decoded-time-add').

Some questions:

1) Should these functions go in simple.el? I put them there because that
is where the structure definition for decoded-time is. (The definition
does not generate a predicate automatically because it uses :type but
not :named; see Info node `(cl)Structures'.) But at least
`decoded-time-delta-p' might be better off in time-date.el, which is
where `decoded-time-add' is defined.

2) Should `decoded-time-p' also check the weekday slot of decoded times?
See the FIXME comment in the middle of the function: `make-decoded-time'
neither sets this slot nor provides an argument to let the caller set
it. This is apparently intentional: there is a comment in the
definition of `make-decoded-time',

  ;; Do not set decoded-time-weekday or decoded-time-dst,
  ;; as encode-time can infer them well enough when unknown.

but if the slot is not meant to be set I don't understand why it's
there. It would be useful, for iCalendar purposes, to have the weekday
slot automatically calculated from the date values when a decoded time
is constructed. I'm not sure if this use was just not envisioned, or if
there was a more substantial reason not to do it in make-decoded-time.

Hopefully I got the commit message right this time, but please let me
know if that needs tweaking too...

Best,
Richard

>From a9075f0dc459c1b3b0c3d2e4b7eb33553d7adac9 Mon Sep 17 00:00:00 2001
From: Richard Lawrence <[email-masked]>
Date: Sat, 14 Dec 2024 16:36:45 +0100
Subject: [PATCH] Add predicates for decoded times and time deltas

* lisp/simple.el (decoded-time-p): Add predicate for decoded
times.
* lisp/simple.el (decoded-time-delta-p): Add predicate for time
deltas.
---
 lisp/simple.el | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/lisp/simple.el b/lisp/simple.el
index f2ee4a5df67..ac06a49402f 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -11228,6 +11228,41 @@ capitalize-dwim
 the number of seconds east of Greenwich.")
   )
 
+(defun decoded-time-p (val)
+  "Return non-nil if VAL is a decoded time.
+See `decode-time' for the expected format of VAL."
+  (and (listp val)
+       (length= val 9
+       ;; TODO: according to `decode-time', sec can also be a "Lisp
+       ;; timestamp"...is there a predicate for that?
+       (cl-typep (decoded-time-second val) '(integer 0 60))
+       (cl-typep (decoded-time-minute val) '(integer 0 59))
+       (cl-typep (decoded-time-hour val) '(integer 0 23))
+       (cl-typep (decoded-time-day val) '(integer 1 31))
+       ;; FIXME: the weekday slot value should ideally be automatically
+       ;; calculated from month, day, and year on construction, like:
+       ;;   (calendar-day-of-week (list month day year))
+       ;; `make-decoded-time' does not do this at present, and also has no
+       ;; option to set the weekday slot.
+       ;; (cl-typep (decoded-time-weekday val) '(integer 0 6))
+       (cl-typep (decoded-time-month val) '(integer 1 12))
+       (cl-typep (decoded-time-year val) 'integer)
+       (cl-typep (decoded-time-dst val) '(member t nil -1))
+       (cl-typep (decoded-time-zone val) '(or integer null)))))
+
+(defun decoded-time-delta-p (val)
+  "Return non-nil if VAL is a decoded time delta of the sort required by
+`decoded-time-add'."
+  (and (listp val)
+       (length= val 9)
+       ;; weekday, dst, zone can be ignored
+       (cl-typep (decoded-time-second val) '(or null integer))
+       (cl-typep (decoded-time-minute val) '(or null integer))
+       (cl-typep (decoded-time-hour val) '(or null integer))
+       (cl-typep (decoded-time-day val) '(or null integer))
+       (cl-typep (decoded-time-month val) '(or null integer))
+       (cl-typep (decoded-time-year val) '(or null integer))))
+
 ;; Document that decoded-time-dst is problematic on 6-element lists.
 ;; It should return -1 indicating unknown DST, but currently returns
 ;; nil indicating standard time.
-- 
2.39.5