97

I have a UNIX timestamp and I'd like to get a formatted date (like the output of date) corresponding to that timestamp.

My attempts so far:

$ date +%s
1282367908
$ date -d 1282367908
date: invalid date `1282367908'
$ date -d +1282367908
date: invalid date `+1282367908'
$ date +%s -d +1282367908
date: invalid date `+1282367908'

I'd like to be able to get output like:

$ TZ=UTC somecommand 1282368345
Sat Aug 21 05:25:45 UTC 2010
tshepang
  • 65,642
Umang
  • 1,171

8 Answers8

144

On Mac OS X and BSD:

$ date -r 1282368345
Sat Aug 21 07:25:45 CEST 2010
$ date -r 1282368345 +%Y-%m-%d
2010-08-21

with GNU core tools (you have to dig through the info file for that):

$ date -d @1282368345
Sat Aug 21 07:25:45 CEST 2010
$ date -d @1282368345 --rfc-3339=date
2010-08-21

With either, add the -u (standard) option, or pass a TZ=UTC0 environment variable to have the UTC date (TZ=UTC0 defines a timezone called UTC with offset 0 from UTC while the behaviour for TZ=UTC (with no offset) is unspecified (though on most systems would refer to a system-defined timezone also called UTC with offset 0 from UTC)).

  • 1
    It takes a lot of digging, though, which is surprising for such a common task. – David Z Aug 21 '10 at 08:04
  • Thanks, accepted your answer. I should have read info coreutils date a little more carefully. – Umang Aug 21 '10 at 08:27
  • This is giving me a slightly different date: date -r 1447264553943 results in Wed Dec 28 01:39:03 BRST 47831, when it's actually 11/11/2015, 3:55:53 PM GMT-2:00. – falmp Nov 11 '15 at 18:01
  • 1
    @falmp: it will work if you use seconds instead of microseconds. –  Nov 12 '15 at 16:03
  • @hop ops, should have figured with the year being 47831, but that number was so high I missed it. Thanks! – falmp Nov 12 '15 at 22:25
7

This perl one-liner will do it:

$ perl -e 'print scalar localtime $ARGV[0]' 1282367908
Sat Aug 21 09:18:28 2010
tshepang
  • 65,642
AlexD
  • 1,173
7

After some googling, I found way to do it with the date command only:

$ date --date "Jan 1, 1970 00:00:00 +0000 + 1282367908 seconds"
Sat Aug 21 09:18:28 MSD 2010
tshepang
  • 65,642
AlexD
  • 1,173
  • Thanks for that. I was hoping there'd be something simpler, so just an up vote for now. – Umang Aug 21 '10 at 06:36
  • another great example for how google makes you stupid. does nobody ever read the documentation anymore? –  Aug 21 '10 at 07:28
  • 2
    @hop, support for date -d @xxx was not added until coreutils 5.3 in 2005. That's how you had to do it before that. – Stéphane Chazelas Oct 07 '16 at 06:27
  • 1
    @StéphaneChazelas: a) this answer is from 2010 and b) why does this excuse googling before reading the documentation? If you answer from your own authority, one can excuse making errors like this, but if you have to look it up anyway, look it up right. –  Oct 07 '16 at 17:15
  • 1
    @hop, I was just pointing out that it was not a stupid answer, just an outdated one. – Stéphane Chazelas Oct 07 '16 at 21:51
5

With shell builtins:

  • zsh (4.1.1 (2003) and above) :

    $ zmodload zsh/datetime
    $ TZ=UTC0 strftime %c 1282368345
    Sat 21 Aug 2010 05:25:45 UTC
    
  • ksh93 (ksh93i (2000) and above):

    $ TZ=UTC0 printf '%(%c)T\n' '#1282368345'
    Sat Aug 21 05:25:45 2010
    
  • bash (4.2 (2010) and above):

    $ TZ=UTC0 printf '%(%c)T\n' 1282368345
    Sat 21 Aug 2010 05:25:45 UTC
    

In all those, replace %c with the strftime() format you want.

4

On osx, to have in UTC

date -r "1475737200" -u
anyone
  • 41
2

Answer to an old question, but I think this might be an improvement if anyone else searches for this. This Bash function works on both Linux and OS X. I have not tested on any other BSD systems. Pass the epoch time as an argument to this function and it will print the RFC-3339 time format.

epochtorfc3339 ()
{
    RFC3339_FORMAT="+%FT%T:::%z"
    EPOCH=$(echo $@ | sed -n "s/.*\([0-9]\{10\}\).*/\1/p");
    if date --version >/dev/null 2>/dev/null; then
        # Linux
        date ${RFC3339_FORMAT} -d "1970-01-01 UTC ${EPOCH} seconds"
        #date -d @${EPOCH} --rfc-3339=seconds
    else
        # OS X/BSD
        date -r ${EPOCH} ${RFC3339_FORMAT}
    fi
}
1

For Unix-like environment, the following will work.

# Current UNIXTIME
unixtime() {
  datetime2unixtime "$(date -u +'%Y-%m-%d %H:%M:%S')"
}

From DateTime(%Y-%m-%d %H:%M:%S)to UNIXTIME

datetime2unixtime() { set -- "${1%% }" "${1## }" set -- "${1%%-}" "${1#-}" "${2%%:}" "${2#:}" set -- "$1" "${2%%-}" "${2#-}" "$3" "${4%%:}" "${4#:}" set -- "$1" "${2#0}" "${3#0}" "${4#0}" "${5#0}" "${6#0}" [ "$2" -lt 3 ] && set -- $(( $1-1 )) $(( $2+12 )) "$3" "$4" "$5" "$6" set -- $(( (365$1)+($1/4)-($1/100)+($1/400) )) "$2" "$3" "$4" "$5" "$6" set -- "$1" $(( (306($2+1)/10)-428 )) "$3" "$4" "$5" "$6" set -- $(( ($1+$2+$3-719163)86400+$43600+$5*60+$6 )) echo "$1" }

From UNIXTIME to DateTime format(%Y-%m-%d %H:%M:%S)

unixtime2datetime() { set -- $(( $1%86400 )) $(( $1/86400+719468 )) 146097 36524 1461 set -- "$1" "$2" $(( $2-(($2+2+3$2/$3)/$5)+($2-$2/$3)/$4-(($2+1)/$3) )) set -- "$1" "$2" $(( $3/365 )) set -- "$@" $(( $2-( (365$3)+($3/4)-($3/100)+($3/400) ) )) set -- "$@" $(( ($4-($4+20)/50)/30 )) set -- "$@" $(( 12$3+$5+2 )) set -- "$1" $(( $6/12 )) $(( $6%12+1 )) $(( $4-(30$5+3*($5+4)/5-2)+1 )) set -- "$2" "$3" "$4" $(( $1/3600 )) $(( $1%3600 )) set -- "$1" "$2" "$3" "$4" $(( $5/60 )) $(( $5%60 )) printf "%04d-%02d-%02d %02d:%02d:%02d\n" "$@" }

Examples

unixtime # => Current UNIXTIME date +%s # Linux command

datetime2unixtime "2020-07-01 09:03:13" # => 1593594193 date -u +%s --date "2020-07-01 09:03:13" # Linux command

unixtime2datetime "1593594193" # => 2020-07-01 09:03:13 date -u --date @1593594193 +"%Y-%m-%d %H:%M:%S" # Linux command

https://tech.io/snippet/a3dWEQY

shin
  • 749
1

Another neat example of the rich heritage of modern Unix. This is indeed possible under most BSD variants:

$ TZ=UTC date -r 1282368345
Sat Aug 21 05:25:45 UTC 2010

(BTW your example seems to be off by one second)

codehead
  • 4,960
  • Doesn't work on Linux. hop's answer seems to have the correct Linux answer. Thanks for pointing that out, I suspected something like that would happen, I've made it 45 seconds now. – Umang Aug 21 '10 at 08:21