BASH: Convert Unix Timestamp to a Date

I've been asked this a number of times and always have to look it up, so here are 3 ways to convert a unix timestamp (seconds since Jan 1, 1970 GMT) to a real looking date.
Perl method 1: use the ctime module:

perl -e "require 'ctime.pl'; print &ctime($EPOCH);"

Perl method 2: use the scalar and localtime functions:

perl -e "print scalar(localtime($EPOCH))"

Awk has a wrapper for the standard C strftime function:

echo $EPOCH|awk '{print strftime("%c",$1)}'

Here's a sample script that uses all methods.

!#/bin/bash
EPOCH=1000000000
DATE=$(perl -e "require 'ctime.pl'; print &ctime($EPOCH);")
echo $DATE
DATE=$(perl -e "print scalar(localtime($EPOCH))")
echo $DATE
DATE=$(echo $EPOCH|awk '{print strftime("%c",$1)}')
echo $DATE

[update: Thanks to S. Maynard for reminding me of the proper use of quotes and how to avoid using the pipe...]
DATE=$(awk "BEGIN { print strftime(\"%c\",$EPOCH) }")

[UPDATE]

A reader found another way listed below. This doesn't seem to be as portable (The mac ignores the --date and -d is an illegal option).
# date --date='1970-01-01 1000000000 sec GMT'
Sat Sep 8 20:46:40 CDT 2001

[UPDATE]
# date -d @1000000042
Sun Sep  9 01:47:22 GMT 2001

But this only works on newer versions of date.  It fails on my FC2 server and my Debian Sarge machine, but works fine on Ubuntu Feisty and Debian Etch.

27 thoughts on “BASH: Convert Unix Timestamp to a Date

  1. Hi,
    you can use “date” too:

    $ date -d ‘1970-01-01 sec’

    $ date -d ‘1970-01-01 944089200 sec’
    Wed Dec 1 23:00:00 CET 1999

    Bye,
    Ado

  2. Very cool, I didn’t think to try that way.

    Be sure to specify GMT in the date string or you may be off by a few hours. On my machine which defaults to CST I get the following results:

    #date -d ‘1970-01-01 1000000000 sec GMT’
    Sat Sep 8 20:46:40 CDT 2001

    #date -d ‘1970-01-01 1000000000 sec’
    Sun Sep 9 02:46:40 CDT 2001

    A unix timestamp is the number of seconds since Jan 1, 1970, GMT so it’s important that you specify GMT.

  3. Hi,

    I ran into the issue of converting user supplied date in the following format dd/mm/yyyy:hrs:min:sec (Ex:18/04/2006:14:52:53) into EPOC time and back.
    I thought it would be simple to implement in Perl, but it’s not. My options are BASH and PERL, any help is appreciated.

    Thanks.

  4. You just need to flip the day and month around with some string manipulation.

    There is no good way to detect if the date string starts with mm/dd or dd/mm. 01/12 and 12/01 are both valid in either format but are almost a year apart.  We just have to know the user’s locale and assume they use the right format.

    date=”08/09/2001 20:46:40 CDT”
    date -d “${date:3:2}/${date:0:2}/${date:6}” +%s

  5. Many thanks – this solved a problem that I had been having. The eventual solution (using ‘date’) is simple and effective.

  6. Also using GNU date it’s
    date {dash}{dash}date. The text processor or blogware seems to have turned the n-dash, n-dash into a single m-dash in Anton’s undated update. I did not try this on a Macintosh.

  7. To clarify, using GNU date, both date -d ‘STRING’ and date {dash}{dash}date=’STRING’ work fine for me. Single-quotes are what I have typed surrounding the word STRING.

  8. The pipe in the awk example is inefficient. It’s easily done without if you know how to nest double-quotes properly:

    DATE=$(awk “BEGIN { print strftime(“%c”,$EPOCH) }”)

    Doing everything in awk’s BEGIN block ensures that it will not wait for piped input (more efficient again). Bourne shells does variable expansions inside of double-quotes, so $EPOCH gets evaluated properly.

  9. Isaac, In my example above I defined EPOCH as 1 billion. I don’t know of any systems that define EPOCH automagically.

    The example could have been EPOCH=`date +%s` but if you’re using date to get an epoch then there is no sense in converting it since a different date argument would get the format you need.

  10. Anyone know how to make it into a csh alias? I can’t figure out how to escape all of the ‘ and “‘s. I would love to have an alias so that I can just type: ctime 11645789.

    I know I could easily move this same code into a script and put that in my path for the same effect but I’m also running on different machines and it’s easier to move an alias than a script . . .

  11. With GNU date on Ubuntu, the command is date -d @1168573011, and on NetBSD it’s date -r 1168573011.

    The manual command is almost funny: `man date`.

  12. Oh, this way with “@” is the coolest one!
    Thanks you, Thomas!

    BTW, I have no mentions about this “@” in ‘man date’, but I have it in ‘info date’ 😛

  13. Pingback: liber » Calcule calendarisitice cu date

  14. @Tim

    That works ok, but it is too difficult to use a web page in a BASH script. A local option will always work better than remote for simple tasks like this.

  15. Thanks for the tips! So far, I was using SQL requests in my linux and nt scripts to convert to and from unixtimestamp dates, which requires to create a special DB user with minimum privileges…

  16. The `awk` examples require GNU Awk. Most Debian and Ubuntu systems do not have the ‘gawk’ package installed by default.

  17. Pingback: Online Tools: Unix Time

  18. Under solaris 9/10 is additional directory with GNU tools, including date, tar etc. Standard solaris tools has a lot incompatibilities. use find command 🙂 and correct path .
    some incompatibilities are under opensolaris too.

  19. not worked for me .

    we used for scripting purpose it will give onle result.

    o/p:-
    perl -MPOSIX=strftime -e print strftime(“%Y-%m-%d %T”, localtime($lastlog1)), “n”
    1970-01-01 00:00:00

    i wan to conver gmt regular date formate;

    Thanks & Regards,
    Babukiran

Leave a Reply

Your email address will not be published. Required fields are marked *