305

How do I convert an epoch timestamp to a human readable format on the cli? I think there's a way to do it with date but the syntax eludes me (other ways welcome).

0

12 Answers 12

463

On *BSD:

date -r 1234567890 

On Linux (specifically, with GNU coreutils ≥5.3):

date -d @1234567890 

With older versions of GNU date, you can calculate the relative difference to the UTC epoch:

date -d '1970-01-01 UTC + 1234567890 seconds' 

If you need portability, you're out of luck. The only time you can format with a POSIX shell command (without doing the calculation yourself) line is the current time. In practice, Perl is often available:

perl -le 'print scalar localtime $ARGV[0]' 1234567890 
9
  • 8
    +1 for the comment about the lack of portability (why doesn't the POSIX spec include a way to do this? grr) Commented Feb 1, 2012 at 22:50
  • 8
    What does the @ mean in date -d @1234567890? man date made no reference to that... Commented Jan 14, 2013 at 21:10
  • 14
    @ChrisMarkle GNU man pages are often woefully incomplete. “The date string format is more complex than is easily documented here but is fully described in the info documentation.” To wit: gnu.org/software/coreutils/manual/html_node/… Commented Jan 14, 2013 at 21:56
  • 4
    The info date is quite complete. The entry at 28.9 Seconds since the Epoch explains in detail about the @timestamp. Commented Feb 10, 2016 at 8:31
  • 2
    To display the date in UTC, add the -u option. Commented Jun 27, 2020 at 12:45
47

If your epoch time is in milliseconds instead of seconds, either put a dot before last three digits (as hinted in comments by user79743), or remove the last three digits before passing it to date -d:

Entered directly, this gives incorrect result :

$ date -d @1455086371603 Tue Nov 7 02:46:43 PST 48079 #Incorrect 

Put a dot before last three digits:

$ date -d @1455086371.603 Tue Feb 9 22:39:32 PST 2016 #Correct 

Or, remove the last three digits:

$ date -d @1455086371 Tue Feb 9 22:39:31 PST 2016 #Correct after removing the last three digits. You may remove and round off the last digit too. 
5
  • What utility prints included milliseconds (without a dot) ? Commented Feb 10, 2016 at 8:35
  • 1
    I have seen that WebLogic Application server mostly returns data time values with milliseconds and no dots when using scripting tool. e.g., lastSuccessfulConnectionUse=1455086371603 Commented Feb 10, 2016 at 8:49
  • I see. This page confirms Raw Time Value The timestamp in milliseconds. Thanks. Commented Feb 10, 2016 at 10:11
  • 1
    Atlassian tools log their timestamps as epoch time with milliseconds. Commented Mar 7, 2019 at 21:09
  • This doesn't work on HP-UX. Commented Sep 3, 2020 at 6:52
31

date -d @1190000000 Replace 1190000000 with your epoch

4
  • 8
    Assuming GNU date, that is. Commented Oct 11, 2010 at 18:14
  • This doesn't work on HP-UX. Commented Sep 3, 2020 at 6:51
  • 1
    Doesn't work on Mac OS too. Commented May 14, 2024 at 11:12
  • For MacOS, $ brew install coreutils && gdate -d @1190000000 Commented May 14, 2024 at 11:49
21

With bash-4.2 or above:

$ printf '%(%FT%T%z)T\n' 1234567890 2009-02-13T23:31:30+0000 

(where %FT%T%z is the strftime()-type format, here using standard unambiguous format which includes the UTC offset (%z))

That syntax is inspired from ksh93.

In ksh93 however, the argument is taken as a date expression where various and hardly documented formats are supported.

For a Unix epoch time, the syntax in ksh93 is:

printf '%(%FT%T%z)T\n' '#1234567890' 

ksh93 however seems to use its own algorithm for the timezone and can get it wrong. For instance, in mainland Britain, it was summer time all year in 1970, but:

$ TZ=Europe/London bash -c 'printf "%(%c)T\n" 0' Thu 01 Jan 1970 01:00:00 BST $ TZ=Europe/London ksh93 -c 'printf "%(%c)T\n" "#0"' Thu Jan 1 00:00:00 1970 

ksh93 (and zsh's strftime builtin) support subsecond, not bash yet:

$ ksh -c 'printf "%(%FT%T.%6N%z)T\n" 1234567890.123456789' 2009-02-13T23:31:30.123456-0000 $ zsh -c 'zmodload zsh/datetime; strftime %FT%T.%6.%z 1234567890 123456780' 2009-02-13T23:31:30.123457+0000 
1
  • This actually works on HP-UX. Thanks! Commented Sep 3, 2020 at 7:18
20

Custom format with GNU date:

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

Or with GNU awk:

awk 'BEGIN { print strftime("%Y-%m-%d %H:%M:%S", 1234567890); }' 

Linked SO question: https://stackoverflow.com/questions/3249827/convert-from-unixtime-at-command-line

1
  • 4
    Only works for GNU date and GNU awk. Neither awk nor nawk support strftime. Commented Jul 28, 2014 at 3:56
16
$ echo 1190000000 | perl -pe 's/(\d+)/localtime($1)/e' Sun Sep 16 20:33:20 2007 

This can come in handy for those applications which use epoch time in the logfiles:

$ tail -f /var/log/nagios/nagios.log | perl -pe 's/(\d+)/localtime($1)/e' [Thu May 13 10:15:46 2010] EXTERNAL COMMAND: PROCESS_SERVICE_CHECK_RESULT;HOSTA;check_raid;0;check_raid.pl: OK (Unit 0 on Controller 0 is OK) 
10

The two I frequently use are:

$ perl -leprint\ scalar\ localtime\ 1234567890 Sat Feb 14 00:31:30 2009 

and

$ tclsh % clock format 1234567890 Sa Feb 14 00:31:30 CET 2009 
2
  • 1
    Love this tclsh suggestion, that seems much easier to remember than most of the incantations in this thread Commented Aug 10, 2021 at 19:09
  • The perl one worked for me with timestamp formated like 1.679703228911E9 Commented Mar 31, 2023 at 10:05
9

With zsh you could use the strftime builtin:

strftime format epochtime Output the date denoted by epochtime in the format specified.

e.g.

zmodload zsh/datetime strftime '%A, %d %b %Y' 1234567890 
Friday, 13 Feb 2009

There's also dateconv from dateutils:

dateconv -i '%s' -f '%A, %d %b %Y' 1234567890 
Friday, 13 Feb 2009

keep in mind dateutils tools default to UTC (add -z your/timezone if needed).

2
  • It doesn't look like dateutils is available on HP-UX. Commented Sep 3, 2020 at 7:10
  • On Debian, the dateutils package has the dateutils.dconv binary instead of dateconv. I'm assuming it's the same thing, but renamed. Commented Jul 28, 2022 at 16:32
1

In PowerShell:

(([System.DateTimeOffset]::FromUnixTimeMilliSeconds($unixtime)).DateTime).ToString("s") 
5
  • This technique is using Microsoft .NET. It doesn't seem OP is looking for an MS solution. Commented Sep 20, 2019 at 20:40
  • 4
    Reviewers: PowerShell is available on Linux ;-). Commented Oct 23, 2019 at 13:04
  • @StephenKitt, but does PowerShell run on HP-UX? Seeming no: reddit.com/r/PowerShell/comments/8cx8dp/… . And this is unix. Commented Sep 3, 2020 at 6:58
  • @saulius2 by that reasoning, most of the content of Unix.SE is invalid, because it’s possible to find a Unix system where it isn’t applicable. This is Unix & Linux Stack Exchange. Commented Sep 4, 2020 at 6:54
  • @StephenKitt, maybe it's so, I made no research about quality of the questions. But just by looking at the right side of this page I see three of them which are asking about the specific OS: unix.stackexchange.com/questions/86507/… unix.stackexchange.com/questions/96189/… unix.stackexchange.com/questions/434844/… Commented Sep 5, 2020 at 6:15
1

If UTC is your preference (for the sample epoch timestamp 1666666666),

$ # long options; Linux $ date --date=@1666666666 --utc Tue 14 Nov 22:13:20 UTC 2023 $ # short options; Linux $ date -d @1666666666 -u Tue 14 Nov 22:13:20 UTC 2023 
0

You could also use a little C program for printing the datetime in the format that can be directly parsed by shell

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> int main(int argc, char * argv[]) { if (argc==1) { return 1; } struct tm input_tm; char * formatStr = "YEAR=%Y\nMON=%m\nDAY=%d\nHOUR=%H\nMIN=%M\nSEC=%S"; size_t formatSize = strlen(formatStr) + 2; char * output = (char *)malloc(sizeof(char)*formatSize); strptime(argv[1],"%s",&input_tm); strftime(output, formatSize, formatStr, &input_tm); printf("%s\n",output); free(output); return 0; } 

usage:

#compile clang -o epoch2datetime main.c #invoke eval `./epoch2datetime 1450196411` echo $YEAR $MON $DAY $HOUR $MIN $SEC #output #2015 12 16 00 20 11 
3
  • 1
    Doesn't work on HP-UX: ./a.out 1599099168 YEAR=1901 MON=03 DAY=00 HOUR=2130568304 MIN= Commented Sep 3, 2020 at 7:16
  • @saulius2 ... what? I completely believe you, but the situation is kind of crazy. HP-UX can't correctly handle stdio.h, stdlib.h, string.h, and time.h in Standard (ANSI/ISO) C !?!?!? . . . . . . . . . . . . . . . . What the for i in {1..4}; do ascii_base10_val=$(echo "33+$(shuf -i 0-14 -n 1)" | bc -l); ascii_hex_val=$(echo "obase=16; ${ascii_base10_val}" | bc); printf "\x${ascii_hex_val}"; done; echo has HP-UX done! . . . . . . . . . . . . . . . . . . . . . . . . . (The code will give a cartoon representation of a cuss word, by the way.) Commented Aug 18, 2022 at 21:27
  • Well, I didn't investigate at the time, and now I have lost access to these HP-UX boxes, so I cannot investigate at the moment too. Commented Aug 19, 2022 at 7:35
0

Wouldn't be a real solution without a little node.js:

epoch2date(){ node -p "new Date($1)" } 

add that to ~/.bash_aliases and make sure its sourced in ~/.bashrc with . ~/.bash_aliases

if [ -f ~/.bash_aliases ]; then . ~/.bash_aliases fi 

To get node on your system goto http://nvm.sh and run the curl command. It'll install node version manager (nvm) which allows you to switch versions of node.

Just type nvm ls-remote and pick a version to nvm install <version>.

1

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.