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.
April 18th, 2006 at 8:44 am
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
April 18th, 2006 at 3:26 pm
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.
April 25th, 2006 at 7:57 pm
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.
April 25th, 2006 at 10:41 pm
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.
April 27th, 2006 at 4:12 pm
Thanks Anton, that helps.
July 23rd, 2006 at 7:31 am
Many thanks - this solved a problem that I had been having. The eventual solution (using ‘date’) is simple and effective.
September 28th, 2006 at 4:43 pm
Doing a copy/paste on the above script borks the ascii values of ” and ‘ so that it fails completely.
November 12th, 2006 at 12:14 am
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.
November 12th, 2006 at 12:24 am
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.
November 23rd, 2006 at 4:44 am
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.
December 6th, 2006 at 10:30 am
My system (AIX) does not define $EPOCH.
December 10th, 2006 at 6:03 pm
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.
December 18th, 2006 at 1:54 pm
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 . . .
December 18th, 2006 at 5:45 pm
got it! qq is our friend!
alias ctime ‘perl -e “print scalar localtime(\!^).qq(\n)”‘
January 11th, 2007 at 11:51 am
It’s worth noting that the “date” and “awk” provided on Solaris 9 or 10 do not support the various syntaxes used here *sniff*
January 11th, 2007 at 11:46 pm
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`.
January 25th, 2007 at 12:52 pm
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’
February 22nd, 2007 at 7:11 pm
[…] Puteţi consulta deasemenea şi pagina asta: http://anton.lr2.com/archives/2006/04/06/convert-a-unix-epoch-timestamp-to-a-date-in-bash/. […]
March 17th, 2007 at 11:59 am
date -d @1000000042