[bash] How to convert timestamps to dates in Bash?

I need a shell command or script that converts a Unix timestamp to a date. The input can come either from the first parameter or from stdin, allowing for the following usage patterns:

ts2date 1267619929

and

echo 1267619929 | ts2date

Both commands should output "Wed Mar 3 13:38:49 2010".

This question is related to bash date unix-timestamp

The answer is


In OSX, or BSD, there's an equivalent -r flag which apparently takes a unix timestamp. Here's an example that runs date four times: once for the first date, to show what it is; one for the conversion to unix timestamp with %s, and finally, one which, with -r, converts what %s provides back to a string.

$  date; date +%s; date -r `date +%s`
Tue Oct 24 16:27:42 CDT 2017
1508880462
Tue Oct 24 16:27:42 CDT 2017

At least, seems to work on my machine.

$ uname -a
Darwin XXX-XXXXXXXX 16.7.0 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64 x86_64

Since Bash 4.2 you can use printf's %(datefmt)T format:

$ printf '%(%c)T\n' 1267619929
Wed 03 Mar 2010 01:38:49 PM CET

That's nice, because it's a shell builtin. The format for datefmt is a string accepted by strftime(3) (see man 3 strftime). Here %c is:

%c The preferred date and time representation for the current locale.


Now if you want a script that accepts an argument and, if none is provided, reads stdin, you can proceed as:

#!/bin/bash

if (($#)); then
    printf '%(%c)T\n' "$@"
else
    while read -r line; do
        printf '%(%c)T\n' "$line"
    done
fi

I use this when converting log files or monitoring them:

tail -f <log file> | gawk \
'{ printf strftime("%c", $1); for (i=2; i<NF; i++) printf $i " "; print $NF }'

some example:

$ date
Tue Mar 22 16:47:06 CST 2016

$ date -d "Tue Mar 22 16:47:06 CST 2016" "+%s"
1458636426

$ date +%s
1458636453

$ date -d @1458636426
Tue Mar 22 16:47:06 CST 2016

$ date --date='@1458636426'
Tue Mar 22 16:47:06 CST 2016



I had to convert timestamps inline in my bash history to make sense to me.

Maybe the following coming from an answer to How do I replace a substring by the output of a shell command with sed, awk or such? could be interesting to other readers too. Kudos for the original sed inline code go to @Gabriel.

cat ~/.bash_history | sed "s/^#\([0-9]\+\)$/echo -n '#'; date -u --d @\1 '\+\%Y-\%m-\%d \%T'/e" | less

In this answer I copy Dennis Williamson's answer and modify it slightly to allow a vast speed increase when piping a column of many timestamps to the script. For example, piping 1000 timestamps to the original script with xargs -n1 on my machine took 6.929s as opposed to 0.027s with this modified version:

#!/bin/bash
LANG=C
if [[ -z "$1" ]]
then
    if [[ -p /dev/stdin ]]    # input from a pipe
    then
        cat - | gawk '{ print strftime("%c", $1); }'
    else
        echo "No timestamp given." >&2
        exit
    fi
else
    date -d @$1 +%c
fi

You can get formatted date from timestamp like this

date +'%Y-%m-%d %H:%M:%S' -d "@timestamp"

While not pure bash, the following script will convert timestamps of length 13 in a string to their equivalent date in your local timezone using perl

timestamp_to_date.sh

#!/usr/bin/env bash
IT=$(cat /dev/stdin)
re='(.*)([0-9]{13})(.*)'
while [[ $IT =~ $re ]]; do
  TIMESTAMP=${BASH_REMATCH[2]}
  AS_DATE=$(echo "$TIMESTAMP" | perl -pe 's/([\d]{10})([\d]{3})/localtime $1/eg;')
  IT="${IT/$TIMESTAMP/$AS_DATE}"    
done
echo "$IT"

input

{"timestamp":"1573121629939","level":"DEBUG","thread":"http-nio-15372-exec-3","logger":"org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor"}

output

$ cat input | timestamp_to_date.sh

{"timestamp":"Thu Nov  7 06:13:49 2019","level":"DEBUG","thread":"http-nio-15372-exec-3","logger":"org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor"}

In PHP

$unix_time = 1256571985;

echo date("Y-m-d H:i:s",$unix_time)

You can use GNU date, for example,

$ sec=1267619929
$ date -d "UTC 1970-01-01 $sec secs"

or

$ date -ud @1267619929

date -r <number>

works for me on Mac OS X.


This version is similar to chiborg's answer, but it eliminates the need for the external tty and cat. It uses date, but could just as easily use gawk. You can change the shebang and replace the double square brackets with single ones and this will also run in sh.

#!/bin/bash
LANG=C
if [[ -z "$1" ]]
then
    if [[ -p /dev/stdin ]]    # input from a pipe
    then
        read -r p
    else
        echo "No timestamp given." >&2
        exit
    fi
else
    p=$1
fi
date -d "@$p" +%c

You can use this simple awk script:

#!/bin/gawk -f   
{ print strftime("%c", $0); }

Sample usage:

$ echo '1098181096' | ./a.awk 
Tue 19 Oct 2004 03:18:16 AM PDT
$

I have written a script that does this myself:

#!/bin/bash
LANG=C
if [ -z "$1" ]; then
    if [  "$(tty)" = "not a tty" ]; then
            p=`cat`;
    else
            echo "No timestamp given."
            exit
    fi
else
    p=$1
fi
echo $p | gawk '{ print strftime("%c", $0); }'

I use this cross-platform one-liner:

date -d @1267619929 2>/dev/null || date -r 1267619929

It should work in both macOS and later versions of popular Linux distributions.


Examples related to bash

Comparing a variable with a string python not working when redirecting from bash script Zipping a file in bash fails How do I prevent Conda from activating the base environment by default? Get first line of a shell command's output Fixing a systemd service 203/EXEC failure (no such file or directory) /bin/sh: apt-get: not found VSCode Change Default Terminal Run bash command on jenkins pipeline How to check if the docker engine and a docker container are running? How to switch Python versions in Terminal?

Examples related to date

How do I format {{$timestamp}} as MM/DD/YYYY in Postman? iOS Swift - Get the Current Local Time and Date Timestamp Typescript Date Type? how to convert current date to YYYY-MM-DD format with angular 2 SQL Server date format yyyymmdd Date to milliseconds and back to date in Swift Check if date is a valid one change the date format in laravel view page Moment js get first and last day of current month How can I convert a date into an integer?

Examples related to unix-timestamp

Converting unix time into date-time via excel Convert python datetime to timestamp in milliseconds Getting current unixtimestamp using Moment.js How to parse unix timestamp to time.Time Go / golang time.Now().UnixNano() convert to milliseconds? Get current NSDate in timestamp format MYSQL query between two timestamps How to get current time with jQuery Convert unix time to readable date in pandas dataframe How to get the unix timestamp in C#