1

I am attempting to calculate some time differences in org time strings using time-subtract.

(time-subtract (org-parse-time-string "2018-04-16 Mon 14:00") 
               (org-parse-time-string "2018-04-14 Sat 13:00"))

=> (0 0 1 2)

This seems to make sense. The two times are different by two days and one hour.

(time-subtract (org-parse-time-string "2018-04-16 Mon 14:00") 
               (org-parse-time-string "2018-04-11 Wed 18:00"))

=> (-1 65535 999996 5)

This one doesn't come out as neatly. I would expect (0 0 1 5).

Here is the documentation for time-subtract.

time-subtract is a built-in function in ‘C source code’.

(time-subtract A B)

Return the difference between two time values A and B, as a time value.
Use ‘float-time’ to convert the difference into elapsed seconds.
A nil value for either argument stands for the current time.
See ‘current-time-string’ for the various forms of a time value.

If I try float-time on the two examples above, I get 1.000002e-06 and -3.999994078185409e-06, which implies to me that I'm doing something wrong.

The documentation on current-time-string does not appear to be helpful. In particular it does not define the four fields producted by time-subtract.

What is going on here? How can I get a consistent time difference between two org-mode timestamps?

  • This doesn't explain the erratic behavior, but I did end up getting a consistent time difference by using (time-to-seconds (apply 'encode-time (org-parse-time-string …))) instead of time-subtract. – Matthew Piziak Apr 16 '18 at 18:25
  • 4
    org-parse-time-string, like parse-time-string and decode-time, returns a list (SEC MIN HOUR DAY MON YEAR DOW DST TZ). This is not a valid argument to time-subtract, which expects what Emacs calls a "time value", namely a list (HIGH LOW USEC PICO). See (elisp) Time of Day, (elisp) Time Conversion, and (elisp) Time Parsing. – Basil Apr 16 '18 at 18:46
1
(time-subtract
 (apply #'encode-time (org-parse-time-string "2018-04-16 Mon 14:00")) 
 (apply #'encode-time (org-parse-time-string "2018-04-11 Wed 18:00")))
;; => (6 24384)

(time-to-seconds '(6 24384))
;; => 417600.0

(format-seconds "%Y, %D, %H, %M, %z%S" 417600.0)
;; => "4 days, 20 hours, 0 minutes, 0 seconds"

Emacs can represent a timestamp in different forms, for example, 12 hours after Unix epoch, or 1970-01-01T12:00:00Z

;; 1. Seconds as a float number
(* 12.0 3600)
;; => 43200.0

;; 2. Seconds as a list
;; (SEC-HIGH SEC-LOW MICROSEC PICOSEC)
;; HIGH * 2**16 + LOW + MICRO * 10**-6 + PICO * 10**-12
(0 43200 0 0)

;; 3. Calendar
(SEC MINUTE HOUR DAY MONTH YEAR DOW DST UTCOFF)
(0   0      12   1   1     1970 4   nil 0)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.