How to get unix epoch in milliseconds in Common Lisp

unix epoch in milliseconds is equal to milliseconds from 00:00:00.000 on 1st of January 1970 to a point of time. Obtaining unix epoch, for now, is obvious for GNU Coreutils' date. For example:

$ date +%s
1629132447

Obtaining unix epoch in milliseconds is a bit more complicated. I did this.

$ date +%s%N | awk '{ print substr($0,0,13) }'
1629132562414

I had to use awk to chop the string because %N is for nanoseconds, which is too fine-grained in this case.

In Common Lisp, it is even more complex, since Common Lisp uses Universal Time, which is not unix compatible.

First, we can obtain Universal Time in second for 00:00:00.000 on 1st of January 1970 by this command.

(encode-universal-time 0 0 0 1 1 1970 0)

In the rest of the code, I will use a Common Lisp package – local-time. Given I have a timestamp tm from local-time, which I may obtain it like this.

(setq tm (local-time:now))

To get unix epoch, my code converts local-time's timestamp to Universal Time and subtracts Universal Time of 00:00:00.000 on 1st of January 1970 from it.

(- (local-time:timestamp-to-universal tm)
   (encode-universal-time 0 0 0 1 1 1970 0))

Instead of using this long code, local-time has timestamp-to-unix, so we can use it instead.

(local-time:timestamp-to-unix tm)

Since we want timestamp in milliseconds, my program multiplies timestamp above, which is in second with 1000.

(* 1000 (local-time:timestamp-to-unix tm))

local-time can provide a timestamp in microseconds, and we need to add it to the timestamp above.

(+ (* 1000 (local-time:timestamp-to-unix tm))
   (local-time:timestamp-millisecond tm))

And that is it.