When try to print timedelta as below:

#+BEGIN_SRC elisp :results output
(print (time-subtract
    (parse-time-string "2018-10-20 08:50:36.343")
    (parse-time-string "2018-10-20 08:47:43.029")))

: (-7 3 0 0)

The output format looks wired:

  1. The seconds is negative.
  2. Output format not readable, I wish it's "00:02:53.314".
  • parse-time-string will decode integer seconds, so you'll need to parse fractional seconds separately. – Juancho Oct 20 '18 at 16:47
  • 1
    I think you want to feed those values to format-time-string. – wvxvw Oct 21 '18 at 13:04

#'time-subtract's docstring says "See ‘current-time-string’ for the various forms of a time value." #'current-time-string specifies times to be in this format:

If SPECIFIED-TIME is given, it is a time to format instead of the current time. The argument should have the form (HIGH LOW . IGNORED).

However, #'parse-time-string says this:

Parse the time-string STRING into (SEC MIN HOUR DAY MON YEAR DOW DST TZ).

So one shouldn't pass this value into #'time-subtract. But there is #'date-to-time:

ELISP> (date-to-time "2018-10-20 08:50:36.343")
(23499 9372)

And we can pass these values to #'time-subtract:

ELISP> (time-subtract (date-to-time "2018-10-20 08:50:36.343") 
                      (date-to-time "2018-10-20 08:47:43.029"))
(0 173)

This makes sense; 8:50:36 is exactly 173 seconds after 8:47:43! Cool! Note that this throws away the milliseconds in the timestamps. This is a limitation of how Emacs deals with time.

Now let's get it into the output format you want: 00:02:53.314. We can use #'format-time-string to do so:

ELISP> (format-time-string "%H:%M:%S"
                           (time-subtract (date-to-time "2018-10-20 08:50:36.343")
                                          (date-to-time "2018-10-20 08:47:43.029"))

Note that you have to give the third argument ZONE to #'format-time-string, or it will format it in your local time zone. Passing t there formats it in UTC. This is definitely confusing.


That way it seems to produce something reasonable:

#+BEGIN_SRC elisp :results output
(print (time-subtract
    (parse-iso8601-time-string "2018-10-20 08:50:36")
    (parse-iso8601-time-string "2018-10-20 08:47:43")))


: : (0 173)

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.