866

I need something simple like date, but in seconds since 1970 instead of the current date, hours, minutes, and seconds.

date doesn't seem to offer that option. Is there an easy way?

codeforester
  • 39,467
  • 16
  • 112
  • 140
n-alexander
  • 14,663
  • 12
  • 42
  • 43
  • 9
    Some versions of date have it and some don't. So it's not always present. I ran 'type -a date' and used a different version and that worked. – Scott Rowley May 15 '14 at 19:19
  • 2
    FWIW, Ubuntu only has /bin/date, for which @Steef's answer works – Jonathan Hartley Sep 23 '15 at 05:44
  • 1
    @TheBonsai that's not part of the POSIX standard version of the 'date' tool. Just because your version has it (probably GNU), you shouldn't assume everyone's implementations do. – Wyatt Ward Jun 16 '19 at 05:50

7 Answers7

1581

This should work:

date +%s

As recently corrected in the date manual:

%s = seconds since the Epoch (1970-01-01 00:00 UTC)

Steef
  • 33,059
  • 4
  • 45
  • 36
178

Just to add.

Get the seconds since epoch(Jan 1 1970) for any given date(e.g Oct 21 1973).

date -d "Oct 21 1973" +%s


Convert the number of seconds back to date

date --date @120024000


The command date is pretty versatile. Another cool thing you can do with date(shamelessly copied from date --help). Show the local time for 9AM next Friday on the west coast of the US

date --date='TZ="America/Los_Angeles" 09:00 next Fri'

Better yet, take some time to read the man page http://man7.org/linux/man-pages/man1/date.1.html

pellucide
  • 3,407
  • 2
  • 22
  • 25
  • 1
    This is not the OP's question, but it answers mine, so +1 from me. – adentinger Feb 09 '19 at 19:15
  • Maybe it's the version of `date` or because I'm using `zsh` (macOS Catalina) but this doesn't work for me. Running `$ date -d "Oct 21 1973" +%s` outputs `usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]` – Joshua Pinter Oct 17 '19 at 14:20
  • @JoshuaPinter and others on macOS, I had the same question. `man date` shows that the option(s) used to parse another date string are `-j` and `-f expectedformat` on macOS. (`-d` is used to set daylight savings.) – Bill Feth Nov 04 '21 at 19:40
  • 1
    The `date` command above is from **gnu coreutils** pacakge. On mac, **gnu coreutils** package can be installed with [brew](https://brew.sh) or [macports](https://www.macports.org/). After installing, the binary is named as `gdate` to distinguish it from macOS's preinstalled `/bin/date` – pellucide Nov 07 '21 at 00:52
  • @JoshuaPinter use ```date -r 120024000``` – datasmurf Feb 22 '22 at 17:52
88

Pure bash solution

Since bash 5.0 (released on 7 Jan 2019) you can use the built-in variable EPOCHSECONDS.

$ echo $EPOCHSECONDS
1547624774

There is also EPOCHREALTIME which includes fractions of seconds.

$ echo $EPOCHREALTIME
1547624774.371210

EPOCHREALTIME can be converted to micro-seconds (μs) by removing the decimal point. This might be of interest when using bash's built-in arithmetic (( expression )) which can only handle integers.

$ echo ${EPOCHREALTIME/./}
1547624774371210

In all examples from above the printed time values are equal for better readability. In reality the time values would differ since each command takes a small amount of time to be executed.

Socowi
  • 25,550
  • 3
  • 32
  • 54
  • 4
    For millisecond resolution (same format as `date +%s%3N`) you can use `echo $(( ${EPOCHREALTIME/./} / 1000 ))` – luckman212 Apr 14 '20 at 05:55
60

So far, all the answers use the external program date.

Since Bash 4.2, printf has a new modifier %(dateformat)T that, when used with argument -1 outputs the current date with format given by dateformat, handled by strftime(3) (man 3 strftime for informations about the formats).

So, for a pure Bash solution:

printf '%(%s)T\n' -1

or if you need to store the result in a variable var:

printf -v var '%(%s)T' -1

No external programs and no subshells!

Since Bash 4.3, it's even possible to not specify the -1:

printf -v var '%(%s)T'

(but it might be wiser to always give the argument -1 nonetheless).

If you use -2 as argument instead of -1, Bash will use the time the shell was started instead of the current date. This can be used to compute elapsed times

$ printf -v beg '%(%s)T\n' -2
$ printf -v now '%(%s)T\n' -1
$ echo beg=$beg now=$now elapsed=$((now-beg))
beg=1583949610 now=1583953032 elapsed=3422
qneill
  • 1,643
  • 14
  • 18
gniourf_gniourf
  • 44,650
  • 9
  • 93
  • 104
  • 10
    You want to use `-2` in case you have a longer running job (think of a script to control you backups) and send a mail in the end "Backup started at $somewhen completed at $now" - which can be accomplished with `-2` avoiding to store a dedicated variable at the beginning. – Sebastian J. Apr 26 '16 at 16:33
52

With most Awk implementations:

awk 'BEGIN {srand(); print srand()}'
Zombo
  • 1
  • 62
  • 391
  • 407
  • 44
    Wow that is obscure – ericslaw Mar 30 '17 at 19:34
  • 16
    Wow, had to go look this one up. This is a pragmatic solution, but not necessarily good/portable. [It seems that implementations of awk `srand()`](https://www.gnu.org/software/gawk/manual/html_node/Numeric-Functions.html) are typically seeded with the current date/time. The second call to `srand()` returns the value previously used as the seed. – Ryan Ransford Jul 28 '17 at 13:41
  • POSIX compliant as well, because this is how NAWK behaves. Very nice. I was trying to remember this one and tracked down your post. Thanks. – Kajukenbo Jul 10 '21 at 23:37
  • 3
    Would it be wrong of me to suggest awk 'BEGIN {print srand(srand())}' – Ben Aveling Feb 20 '22 at 05:02
24

This is an extension to what @pellucide has done, but for Macs:

To determine the number of seconds since epoch (Jan 1 1970) for any given date (e.g. Oct 21 1973)

$ date -j -f "%b %d %Y %T" "Oct 21 1973 00:00:00" "+%s"
120034800

Please note, that for completeness, I have added the time part to the format. The reason being is that date will take whatever date part you gave it and add the current time to the value provided. For example, if you execute the above command at 4:19PM, without the '00:00:00' part, it will add the time automatically. Such that "Oct 21 1973" will be parsed as "Oct 21 1973 16:19:00". That may not be what you want.

To convert your timestamp back to a date:

$ date -j -r 120034800
Sun Oct 21 00:00:00 PDT 1973

Apple's man page for the date implementation: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/date.1.html

PeqNP
  • 1,363
  • 15
  • 26
  • 2
    To be clear, this is for BSD's `date` command, whereas any solutions suggesting `date -d` are for GNU `date`. BSD date in macOS [comes from FreeBSD](https://man.freebsd.org/date), and shares a number of options with NetBSD and OpenBSD. And this is ***entirely separate*** from bash. – ghoti Aug 16 '18 at 14:24
  • 1
    the `%N` option mentioned for fractional seconds in gnu date is missing from MacOS date. On 10.14, none of the formats are in the man page; they're in the `strftime(3)` man page, which you won't have if you don't have Xcode installed, and might not see with man command even if you do. – Dan Pritts Mar 01 '19 at 18:45
  • By extension of @ghoti's comment, this works on MacOS. – Chris Conover May 13 '21 at 18:45
3

use this bash script (my ~/bin/epoch):

#!/bin/bash

# get seconds since epoch
test "x$1" == x && date +%s && exit 0

# or convert epoch seconds to date format (see "man date" for options)
EPOCH="$1"
shift
date -d @"$EPOCH" "$@"
comonad
  • 5,134
  • 2
  • 33
  • 31