On 05/05/2022 22:22, Max Nikulin wrote:
On 04/05/2022 16:56, Ihor Radchenko wrote:
Max Nikulin writes:
Resetting timezone to UTC should be fixed in timestamps generated by a
testing helper function. I was disappointed that `mapcar' can not be
used with multiple lists, but I have found an old function created
namely for zeroing nils in timestamps.
Most of the changes are rather trivial. Some code I do not like though
or unsure that I chose a proper approach.
+ (defmacro org-encode-time (&rest time)
+ (pcase (length time) ; Emacs-29 since d75e2c12eb
+ (1 `(encode-time ,@time))
+ ((or 6 9) `(encode-time (list ,@time)))
+ (_ (error "`org-encode-time' may be called with 1, 6, or 9 arguments but
%d given"
+ (length time)))))
Should it be something like the following?
(signal 'wrong-type-argument (list '(1 6 9) (length time)))
or even
(signal 'wrong-type-argument
(list '(lambda (n-args) (memq n-args) '(1 6 9)) (length time)))
Usually "wrong type argument" errors give no clue even related to called
function til enabling enter debugger on error and realizing how to
reproduce the problem.
diff --git a/lisp/org-clock.el b/lisp/org-clock.el
index 9f80dea04..da5c310b7 100644
--- a/lisp/org-clock.el
+++ b/lisp/org-clock.el
@@ -2866,20 +2866,21 @@ a number of clock tables."
;; Compute NEXT, which is the end of the current clock table,
;; according to step.
(let* ((next
- (apply #'encode-time
- (pcase-let
- ((`(,_ ,_ ,_ ,d ,m ,y ,dow . ,_) (decode-time start)))
- (pcase step
- (`day (list 0 0 org-extend-today-until (1+ d) m y))
- (`week
- (let ((offset (if (= dow week-start) 7
- (mod (- week-start dow) 7))))
- (list 0 0 org-extend-today-until (+ d offset) m
y)))
- (`semimonth (list 0 0 0
- (if (< d 16) 16 1)
- (if (< d 16) m (1+ m)) y))
- (`month (list 0 0 0 month-start (1+ m) y))
- (`year (list 0 0 org-extend-today-until 1 1 (1+
y)))))))
+ ;; In Emacs-27 and Emacs-28 `encode-time' does not support 6
elements
+ ;; list argument so `org-encode-time' can not be outside of
`pcase'.
+ (pcase-let
+ ((`(,_ ,_ ,_ ,d ,m ,y ,dow . ,_) (decode-time start)))
+ (pcase step
+ (`day (org-encode-time 0 0 org-extend-today-until (1+ d) m
y))
+ (`week
+ (let ((offset (if (= dow week-start) 7
+ (mod (- week-start dow) 7))))
+ (org-encode-time 0 0 org-extend-today-until (+ d offset)
m y)))
+ (`semimonth (org-encode-time 0 0 0
+ (if (< d 16) 16 1)
+ (if (< d 16) m (1+ m)) y))
+ (`month (org-encode-time 0 0 0 month-start (1+ m) y))
+ (`year (org-encode-time 0 0 org-extend-today-until 1 1 (1+
y))))))
(table-begin (line-beginning-position 0))
(step-time
;; Write clock table between START and NEXT.
I do not like repeating of `org-encode-time' but do not see another way
till Emacs-29 will become the lowest supported version.
diff --git a/lisp/org.el b/lisp/org.el
index 165c83609..3288bb7b8 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -14472,14 +14474,15 @@ When SUPPRESS-TMP-DELAY is non-nil, suppress delays
like
(setcar (cdr time0) (+ (nth 1 time0)
(if (> n 0) (- rem) (- dm rem))))))
(setq time
- (apply #'encode-time
- (or (car time0) 0)
- (+ (if (eq timestamp? 'minute) n 0) (nth 1 time0))
- (+ (if (eq timestamp? 'hour) n 0) (nth 2 time0))
- (+ (if (eq timestamp? 'day) n 0) (nth 3 time0))
- (+ (if (eq timestamp? 'month) n 0) (nth 4 time0))
- (+ (if (eq timestamp? 'year) n 0) (nth 5 time0))
- (nthcdr 6 time0)))
+ (org-encode-time
+ (apply #'list
+ (or (car time0) 0)
+ (+ (if (eq timestamp? 'minute) n 0) (nth 1 time0))
+ (+ (if (eq timestamp? 'hour) n 0) (nth 2 time0))
+ (+ (if (eq timestamp? 'day) n 0) (nth 3 time0))
+ (+ (if (eq timestamp? 'month) n 0) (nth 4 time0))
+ (+ (if (eq timestamp? 'year) n 0) (nth 5 time0))
+ (nthcdr 6 time0))))
(when (and (memq timestamp? '(hour minute))
extra
(string-match "-\\([012][0-9]\\):\\([0-5][0-9]\\)" extra))
I am tempting to write something like
(let* ((ts (copy-sequence time0))
(ord (memq timestamp? '(year month day hour minute)))
(field (and ord (nthcdr (length ord) ts))))
(when field
(setcar field (+ (car field) n)))
(org-encode-time ts))
but I am afraid it will make the code rather obscure.
@@ -19276,12 +19279,14 @@ return an active timestamp."
"Convert TIMESTAMP object into an Emacs internal time value.
Use end of date range or time range when END is non-nil.
Otherwise, use its start."
- (apply #'encode-time 0
- (mapcar
- (lambda (prop) (or (org-element-property prop timestamp) 0))
- (if end '(:minute-end :hour-end :day-end :month-end :year-end)
- '(:minute-start :hour-start :day-start :month-start
- :year-start)))))
+ (org-encode-time
+ (append '(0)
+ (mapcar
+ (lambda (prop) (or (org-element-property prop timestamp) 0))
+ (if end '(:minute-end :hour-end :day-end :month-end :year-end)
+ '(:minute-start :hour-start :day-start :month-start
+ :year-start)))
+ '(nil -1 nil))))
(defun org-timestamp-has-time-p (timestamp)
"Non-nil when TIMESTAMP has a time specified."
Hardly may be considered as an example of elegant code.