How do I convert the number of seconds passed since 1 January 2001 00:00 to human readable date in bash?
Since Unix' Epoch is 1970-01-01 00:00:00 UTC rather than 2001-01-01 00:00:00 UTC, available tools, like the gnu date command, must just be supplied the seconds between both in addition to the actual data to give the result using their built-in conversion features.
$ seconds=500000
$ TZ=UTC date --iso-8601=s -d @$(( $(date +%s -d '2001-01-01T00:00:00+00') + $seconds ))
2001-01-06T18:53:20+00:00
UPDATE: (thanks to @Kusalananda's comment) actually there's not even the need to mention Unix Epoch, because the GNU date command accepts directly adding a time offset to a given date. It must just be supplied with the correct unit suffix (here seconds
). This makes the command simplier, more generic, and easier to read:
$ seconds=500000
$ TZ=UTC date --iso-8601=s -d "2001-01-01T00:00:00+00 + $seconds seconds"
2001-01-06T18:53:20+00:00
To output exactly like OP's output format, replace --iso-8601=s
with '+%F %T %z'
Above command uses those options and parameters:
-d
: use given date rather than current date. Can include additions of time offsets.--iso-8601=s
is the ISO format similar to (give or take some spaces etc.)+%F %T %z
which is same as+Y-%m-%d %H:%M:%S %z
: self explanatory, with %z the timezone offset to UTC, which here will be +0000 sinceTZ=UTC
forced it.
Using an awk
implementation that supports mktime()
and strftime()
(such as mawk
or GNU awk
):
$ awk 'BEGIN { epoch = mktime("2001 01 01 00 00 00"); print strftime("%F %T %z", epoch + 500000) }'
2001-01-06 18:53:20 +0000
This first creates a UNIX timestamp corresponding to 2001-01-01 at 00:00, and then adds 500000 seconds to that and formats and prints the result according to the strftime()
format string. The computations here are done in local time.
With the seconds taken from an argument on the command line:
awk -v offset=500000 '
BEGIN { epoch = mktime("2001 01 01 00 00 00")
print strftime("%F %T %z", epoch + offset) }'
Reading the seconds from standard input (the first word on each line):
awk 'BEGIN { epoch = mktime("2001 01 01 00 00 00") }
{ print strftime("%F %T %z", epoch + $1) }'
See your awk
manual for a description of the mktime()
and strftime()
functions, and also see man strftime
for the available format strings.
Set the TZ environment variable to UTC
for doing calculations and output in UTC rather than local time:
TZ=UTC awk ...as above...