Code Matters

Three Ways to Get a Unix Epoch in Bash

June 13, 2021

The Unix epoch time is the number of elapsed seconds since January 1st, 1970. Epoch times are handy because they’re not subject to timezone offsets, and they’re numbers, unlike ISO 8601 timestamps for example (“1970-01-01T00:00:00Z”). That makes them memory efficient, and more importantly, easy to do math with.

Here are three ways to get the epoch time in Bash.

Use Date

You can use the date program to generate the epoch time by providing the %s formatting argument. Here I’ve included %N to append nanoseconds:

$ date +%s.%N
1623598897.598538943

A few downsides here: the first is it requires the date program to be available on the system and it forks to run the program, which is slow. If you want to capture the result in a variable, you can use command substitution:

epoch=$(date +%s.%N)

But this is even slower as it starts a subshell first.

GNU date is needed for the %N option. Even the %s option is not officially portable, as the POSIX strftime standard doesn’t require it.

Use EPOCHREALTIME

Bash versions 5 and higher come with the global variable EPOCHREALTIME which includes microseconds:

$ echo "$EPOCHREALTIME"
1623598897.598538

This is much faster than calling date, however you can’t get nanosecond precision.

Use Printf

Yet another way is use the printf builtin command with a time formatting argument:

$ printf "%(%s)T\n"
1623598897

As a builtin command, this is faster than date (no fork) and works on older versions of Bash that don’t have EPOCHREALTIME. However printf doesn’t support sub-second precision (presumably because time.h strftime doesn’t). It can output to a variable with the -v option though:

$ printf -v epoch "%(%s)T"

This is much faster than command substitution as it avoids the subshell bottleneck.

Tags: bash datetime unix epochrealtime date posix printf