It turns out that the timestamp-down sorting function ignores the hours/minutes in the timestamp and only looks at the date.

It took me a lot of time to figure that out! Do you think it'd be good to add this information to the documentation? Currently docs for tsia-down only says "Sort by inactive timestamp, late first.". I think we could change it to "Sort by inactive timestamp, late first. Ignores the hours/minutes of the timestamp"

I've managed to achieve this using a custom sorting function:

(defun parse-date-string (s)
  "Parse a date string of the form \"[YYYY-MM-DD weekday HH:MM]\" and return a 
time value.
If S is nil or does not match the expected format, return nil."
  (when s
    (if (string-match
         "\\[\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+[^ 
\t\n]+\\s-+\\([0-9]+\\):\\([0-9]+\\)\\]"
         s)
        (let* ((year  (string-to-number (match-string 1 s)))
               (month (string-to-number (match-string 2 s)))
               (day   (string-to-number (match-string 3 s)))
               (hour  (string-to-number (match-string 4 s)))
               (min   (string-to-number (match-string 5 s))))
          ;; Encode with seconds=0; note that months and days are 1-indexed.
          (encode-time 0 min hour day month year))
      nil)))

(defun compare-date-strings (s1 s2)
  "Compare two date strings formatted as \"[YYYY-MM-DD weekday HH:MM]\".
If one argument is nil, return the other. If both are nil, return nil.
If both strings are non-nil and can be parsed, return the string corresponding
to the later date (including hour and minute)."
  (cond
   ((and (null s1) (null s2)) nil)
   ((null s1) nil)
   ((null s2) t)
   (t (let ((t1 (parse-date-string s1))
            (t2 (parse-date-string s2)))
        (cond
         ((and t1 t2)
          (if (time-less-p t1 t2) nil t))
         (t
          ;; If only one parses, return the one that did.
          (or (and t1 t) (and t2 nil))))))))

(defun full-timestamp-sorting (a b)
  "Return non-nil if A's date of TYPE is earlier than B's.
A and B are Org headline entries."
  (let ((result (compare-date-strings
                 (cdr (assoc "TIMESTAMP_IA" (org-entry-properties 
(get-text-property 0 'org-marker a))))
                 (cdr (assoc "TIMESTAMP_IA" (org-entry-properties 
(get-text-property 0 'org-marker b)))))))
    (if result 1 -1)
    ))


(setq org-agenda-custom-commands (("a" "Agenda view" agenda #1=""
  ((org-agenda-span 'day) (org-agenda-files '("~/org/main.org"))) nil)
 ("h" "Tasks on hold" todo "HOLD"
  ((org-agenda-files '("~/org/main.org"))))
 ("i" "Inbox" todo "TODO"
  ((org-agenda-files my-all-inboxes)
   (org-overriding-columns-format "%TIMESTAMP_IA %25ITEM ")
   (org-agenda-sorting-strategy '(user-defined-down))
   (org-agenda-include-inactive-timestamps t)
   (org-agenda-cmp-user-defined 'full-timestamp-sorting)))
  nil)))

Reply via email to