I think @d125q has the right solution for you, but let me explain what's happening. Firstly
date-to-day doesn't like your input. Via it's docstring (
C-h f date-to-day)
Return the absolute date of DATE, a date-time string.
The absolute date is the number of days elapsed since the imaginary
Gregorian date Sunday, December 31, 1 BC.
;; *scratch* buffer
Oops. Something is wrong, we should have a 365250 day difference there. So what's 730119 days to years? 2000. What's 2000 years since December 31, 1 BC? December 31, 1999.
Now breaking down the call stack for
date-to-day we have something like
;; date-to-day stack
(time-to-days ((encode-time (parse-time-string
So, using our innermost function
;; try our given input
"31 Dec 1999 19:00:00 -0500"
;; be more precise with our input
"13 Aug 2023 20:00:00 -0400"
(format-time-string "%FT%T%z" (days-to-time (date-to-day "2023-08-14")))
;; correct date based on our input to format-time-string
We've corrected our output, but it's still unexpectedly too far in to the future. This leads us to the second problem, our mis-application of
format-time-string. From its docstring (
C-h f format-time-string)
This function treats seconds as time since the epoch of 1970-01-01 00:00:00 UTC
Oops. We've calculated seconds (as in integer list) from December 31, 1 BC (
date-to-day) and fed it to a function that does its calculations beginning on January 01, 1970. Obviously, we're going to be a just few (thousand) years off.
So, I see a couple of options,
- use @d125q's excellent and concise solution (or something based on
- rewrite your function using functions that only operate on
the UNIX epoch (meh)
- keep doing what you're doing but account for the
difference in time (ugh)