How can I convert a Unix time to an Org-mode local timestamp?

For example (convert 1523473110) should return <2018-04-11 Wed 15:58:30>.

I found org-timestamp--to-internal-time, but that uses "Emacs internal time" and it's going the wrong way anyway.

Is such functionality already available in Emacs, or would I have to write it manually?

  • For those forum participants who are like me and needed to know what a Unix timestamp is, here is the Googled answer: "A Unix timestamp (or epoch time) is the number of seconds that have elapsed since January 1, 1970 00:00 UTC."
    – lawlist
    Apr 11, 2018 at 20:45
  • @lawlist I've gone and added a link to the question to make it easier. :) Apr 11, 2018 at 20:55
  • Using (format-time-string "<%Y-%m-%d %a %H:%M:%S>" (seconds-to-time 1523473110)) gives me <2018-04-11 Wed 11:58:30>, rather than <2018-04-11 Wed 15:58:30>. I am uncertain why there is a difference between what the original poster expects as a result (i.e., mentioned in the question above), versus what is returned by the aforementioned snippet -- the difference is 4 hours. As far as I am aware, Emacs should be correct ...
    – lawlist
    Apr 12, 2018 at 1:33
  • 1
    @lawlist: Timezone difference probably.
    – NickD
    Apr 12, 2018 at 3:09

2 Answers 2


As lawlist mentioned in the comment, running the following in your own Emacs will return what you want

(format-time-string "<%Y-%m-%d %a %H:%M:%S>" (seconds-to-time 1523473110))
;; => "<2018-04-12 Thu 02:58:30>"

;; => (28800 "CST")

As you can see my timezone is +08:00 or CST or Asia/Shanghai, you can also specific a timezone for format-time-string, here is mine

(format-time-string "<%Y-%m-%d %a %H:%M:%S>" (seconds-to-time 1523473110)
                    (* 8 3600))
;; => "<2018-04-12 Thu 02:58:30>"

and here is yours

(format-time-string "<%Y-%m-%d %a %H:%M:%S>" (seconds-to-time 1523473110)
                    (* -3 3600))
;; => "<2018-04-11 Wed 15:58:30>"

You can use the function org-insert-time-stamp:

org-insert-time-stamp is a compiled Lisp function in ‘org.el’.

(org-insert-time-stamp TIME &optional WITH-HM INACTIVE PRE POST EXTRA)

Insert a date stamp for the date given by the internal TIME.
See ‘format-time-string’ for the format of TIME.
WITH-HM means use the stamp format that includes the time of the day.
INACTIVE means use square brackets instead of angular ones, so that the
stamp will not contribute to the agenda.
PRE and POST are optional strings to be inserted before and after the
The command returns the inserted time stamp.

For example:

  (org-insert-time-stamp (string-to-number (car (process-lines "date" "+%s")))


  (call-process "date" nil t nil "+%s")
  (org-insert-time-stamp (read (point-min-marker)) t))

both give

"<2018-04-11 Wed 22:25>"

You can play around with the precise formatting via either the defconst org-time-stamp-formats:

org-time-stamp-formats is a variable defined in ‘org.el’.
Its value is ("<%Y-%m-%d %a>" . "<%Y-%m-%d %a %H:%M>")

  This variable may be risky if used as a file-local variable.

Formats for ‘format-time-string’ which are used for time stamps.

or by passing a format-time-string-style format string as the EXTRA argument. To add seconds to the resulting timestamp, for example, you can write:

  (call-process "date" nil t nil "+%s")
  (org-insert-time-stamp (read (point-min-marker)) t nil nil nil ":%S"))

which gives:

"<2018-04-11 Wed 22:36:23>"

but I would be wary of how robust Org is in the face of exotic timestamp formats.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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