How to get milliseconds since Unix epoch?
With the GNU or ast-open implementation of date
(or busybox' if built with the FEATURE_DATE_NANO
option enabled), I would use:
$ date +%s%3N
which returns milliseconds since Unix epoch.
date +%s.%N
will give you, eg., 1364391019.877418748
. The %N is the
number of nanoseconds elapsed in the current second. Notice it is 9 digits,
and by default date will pad this with zeros if it is less than 100000000. This is actually a problem if we want to do math with the number, because bash treats numbers with a leading zero as octal. This padding can be disabled by using a hyphen in the field spec, so:
echo $((`date +%s`*1000+`date +%-N`/1000000))
would naively give you milliseconds since the epoch.
However, as Stephane Chazelas points out in comment below, that's two different date
calls which will yield two slightly different times. If
the second has rolled over in between them, the calculation will be an
entire second off. So:
echo $(($(date +'%s * 1000 + %-N / 1000000')))
Or optimized (thanks to comments below, though this should have been obvious):
echo $(( $(date '+%s%N') / 1000000));
In case anyone is using other shells than bash
, ksh93
and zsh
have a floating point $SECONDS
variable if you do a typeset -F SECONDS
which can be handy to measure time with accuracy:
$ typeset -F SECONDS=0
$ do-something
something done
$ echo "$SECONDS seconds have elapsed"
18.3994340000 seconds have elapsed
Since version 4.3.13 (2011) zsh
has a $EPOCHREALTIME
special floating point variable in the zsh/datetime
module:
$ zmodload zsh/datetime
$ echo $EPOCHREALTIME
1364401642.2725396156
$ printf '%d\n' $((EPOCHREALTIME*1000))
1364401755993
Note that that's derived from the two integers (for seconds and nanoseconds) returned by clock_gettime()
. On most systems, that's more precision than a single C double
floating point number can hold, so you'll lose precision when you use it in arithmetic expressions (except for dates in the first few months of 1970).
$ t=$EPOCHREALTIME
$ echo $t $((t))
1568473231.6078064442 1568473231.6078064
To compute high precision time differences (though I doubt you'd need more than millisecond precision), you may want to use the $epochtime
special array instead (which contains the seconds and nanoseconds as two separate elements).
Since version 5.7 (2018) the strftime
shell builtin also supports a %N
nanosecond format à la GNU date
and a %.
to specify the precision, so the number of milliseconds since the epoch can also be retrieved with:
zmodload zsh/datetime
strftime %s%3. $epochtime
(or stored in a variable with -s var
)