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

8 Answers 8

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)).

5
  • 1
    It takes a lot of digging, though, which is surprising for such a common task.
    – David Z
    Aug 21, 2010 at 8:04
  • Thanks, accepted your answer. I should have read info coreutils date a little more carefully.
    – Umang
    Aug 21, 2010 at 8: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, 2015 at 18:01
  • 1
    @falmp: it will work if you use seconds instead of microseconds.
    – user601
    Nov 12, 2015 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, 2015 at 22:25
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
5
  • Thanks for that. I was hoping there'd be something simpler, so just an up vote for now.
    – Umang
    Aug 21, 2010 at 6:36
  • another great example for how google makes you stupid. does nobody ever read the documentation anymore?
    – user601
    Aug 21, 2010 at 7: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. Oct 7, 2016 at 6: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.
    – user601
    Oct 7, 2016 at 17:15
  • 1
    @hop, I was just pointing out that it was not a stupid answer, just an outdated one. Oct 7, 2016 at 21:51
7

This perl one-liner will do it:

$ perl -e 'print scalar localtime $ARGV[0]' 1282367908
Sat Aug 21 09:18:28 2010
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.

2
4

On osx, to have in UTC

date -r "1475737200" -u
1
  • Thanks. I've edited that in the accepted answer so the information is more readily available. Oct 7, 2016 at 6:09
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

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)

1
  • 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, 2010 at 8:21
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+$4*3600+$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

2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .