Parts of org-agenda do not handle time ranges spanning multiple days correctly. This is exarcabated when setting org-agenda-default-appointment-duration , which adds an incorrect end time to the entries corresponding to the start and end date. To reproduce:
(prog (find-file "test.org") (insert "* Entry\n<2024-05-30 Thu 14:00>--<2024-05-31 Fri 16:00>") (save-buffer) (setq org-agenda-default-appointment-duration 30) ;; optional (org-agenda-file-to-front) (org-agenda-list) ;; Or, for ease of debugging (with-current-buffer "test.org" (setq date '(5 30 2024)) ;; Or 31 (org-agenda-get-blocks)) ) At the moment I use the following workaround, which would benefit from some feedback. >From 48192b14d3d5739467df7c41ac4e1e9c94f81ee4 Mon Sep 17 00:00:00 2001 From: hrdl <g...@hrdl.eu> Date: Wed, 29 May 2024 17:43:53 +0200 Subject: [PATCH] org-agenda: handle multi-day time ranges * lisp/org-agenda.el: (org-agenda-format-item, org-agenda-get-blocks): Handle start and end dates of multi-day time ranges --- lisp/org-agenda.el | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index 10f25be8a..2e4c01e50 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -6871,9 +6871,9 @@ scheduled items with an hour specification like [h]h:mm." ((and (= d1 d0) (= d2 d0)) (concat "<" start-time ">--<" end-time ">")) ((= d1 d0) - (concat "<" start-time ">")) + (concat "<" start-time ">--")) ((= d2 d0) - (concat "<" end-time ">"))) + (concat "--<" end-time ">"))) remove-re)))) (org-add-props txt props 'face face @@ -7013,21 +7013,24 @@ Any match of REMOVE-RE will be removed from TXT." ;; Normalize the time(s) to 24 hour. (when s1 (setq s1 (org-get-time-of-day s1 t))) (when s2 (setq s2 (org-get-time-of-day s2 t))) + ;; Possibly swap time(s) if this is an end timestamp of a multi-date time span + (when (and s1 (not s2) (string-prefix-p "--" dotime)) + (cl-rotatef s1 s2)) ;; Try to set s2 if s1 and ;; `org-agenda-default-appointment-duration' are set - (when (and s1 (not s2) org-agenda-default-appointment-duration) + (when (and s1 (not s2) (not (string-suffix-p "--" dotime)) org-agenda-default-appointment-duration) (setq s2 (org-duration-from-minutes (+ (org-duration-to-minutes s1 t) org-agenda-default-appointment-duration) nil t))) ;; Compute the duration - (when s2 + (when (and s1 s2) (setq duration (- (org-duration-to-minutes s2) (org-duration-to-minutes s1)))) ;; Format S1 and S2 for display. (when s1 (setq s1 (format "%5s" (org-get-time-of-day s1 'overtime)))) - (when s2 (setq s2 (org-get-time-of-day s2 'overtime)))) + (when s2 (setq s2 (format "%5s" (org-get-time-of-day s2 'overtime))))) (when (string-match org-tag-group-re txt) ;; Tags are in the string (if (or (eq org-agenda-remove-tags t) @@ -7065,14 +7068,17 @@ Any match of REMOVE-RE will be removed from TXT." ""))) (if (equal "" s) "" (concat s org-agenda-breadcrumbs-separator)))))) (setq time (cond (s2 (concat - (org-agenda-time-of-day-to-ampm-maybe s1) + (if s1 (org-agenda-time-of-day-to-ampm-maybe s1) + (make-string (if org-agenda-timegrid-use-ampm 7 5) ? )) "-" (org-agenda-time-of-day-to-ampm-maybe s2) (when org-agenda-timegrid-use-ampm " "))) (s1 (concat (org-agenda-time-of-day-to-ampm-maybe s1) - (if org-agenda-timegrid-use-ampm - (concat time-grid-trailing-characters " ") - time-grid-trailing-characters))) + (if (string-suffix-p "--" dotime) + (concat "-" (make-string (if org-agenda-timegrid-use-ampm 7 5) ? )) + (if org-agenda-timegrid-use-ampm + (concat time-grid-trailing-characters " ") + time-grid-trailing-characters)))) (t "")) category (if (symbolp category) (symbol-name category) category) level (or with-level "")) -- 2.45.1 Emacs : GNU Emacs 29.3 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.41, cairo version 1.18.0) Package: Org mode version 9.6.15 (release_9.6.15 @ /usr/share/emacs/29.3/lisp/org/)