1326

I tried using $(date) in my bash shell script, however, I want the date in YYYY-MM-DD format.
How do I get this?

Arsen Khachaturyan
  • 7,335
  • 4
  • 37
  • 38
Kapsh
  • 19,051
  • 11
  • 34
  • 43
  • 8
    Comments must be at the least 15 words in length. date -I – abc Oct 15 '20 at 05:12
  • 11
    Indeed `date -I` is all you need. It took me years to stumble upon that. – Sridhar Sarnobat Mar 15 '21 at 23:28
  • 1
    `date -I` only works on Linux using GNU tools, not on macOS / BSD; installing [brew](https://brew.sh) --> `brew install coreutils` makes `gdate -I` available – ssc Jul 29 '21 at 18:05

16 Answers16

2083

In bash (>=4.2) it is preferable to use printf's built-in date formatter (part of bash) rather than the external date (usually GNU date).

As such:

# put current date as yyyy-mm-dd in $date
# -1 -> explicit current date, bash >=4.3 defaults to current time if not provided
# -2 -> start time for shell
printf -v date '%(%Y-%m-%d)T\n' -1 

# put current date as yyyy-mm-dd HH:MM:SS in $date
printf -v date '%(%Y-%m-%d %H:%M:%S)T\n' -1 

# to print directly remove -v flag, as such:
printf '%(%Y-%m-%d)T\n' -1
# -> current date printed to terminal

In bash (<4.2):

# put current date as yyyy-mm-dd in $date
date=$(date '+%Y-%m-%d')

# put current date as yyyy-mm-dd HH:MM:SS in $date
date=$(date '+%Y-%m-%d %H:%M:%S')

# print current date directly
echo $(date '+%Y-%m-%d')

Other available date formats can be viewed from the date man pages (for external non-bash specific command):

man date
flindeberg
  • 4,767
  • 1
  • 23
  • 36
Philip Fourie
  • 103,989
  • 10
  • 59
  • 82
  • 6
    In the first days of the month I get "2012-07-1" which is not what the OP asks for. – DerMike Jul 02 '12 at 09:29
  • 6
    This works for me. Man page suggests that the first of the month is 01, no 1 (Ex. 2012-07-01). – Bob Kuhar Mar 19 '13 at 18:59
  • 42
    DATE=$(date +%d-%m-%Y" "%H:%M:%S); What I ended up after. – JacopKane Mar 14 '15 at 04:53
  • 9
    I haven't checked how widely available these shortcuts are, but in some distributions you can use `+%F %T` as a shortcut for `+%Y-%m-%d %H:%M:%S`. Just note that _some filesystems_ (cough**HFS) will convert the `:` to a `/`, giving you a string like `2016-09-15 11/05/00` which is mighty confusing. – beporter Sep 15 '16 at 16:07
  • 33
    The preferred syntax in any POSIX-compliant shell in this millennium is `date=$(date)` instead of `date=\`date\``. Also, don't use uppercase for your private variables; uppercase variable names are reserved for the system. – tripleee Sep 26 '16 at 05:53
  • 1
    The command to use is not a feature of Bash. On OSX, the default shell is still Bash, but the `date` command accepts different options than on GNU (though this simple command should work on both). – tripleee Sep 26 '16 at 05:54
  • If you want a two digit year use `%y` (lowercase) instead of `%Y` (uppercase) – Kellen Stuart Nov 15 '16 at 21:04
  • How do I get the date without leading zeros? Current code returns 2017.02.06 – harsh_v Mar 06 '17 at 10:28
  • 1
    On debian @beporter solution didn't work. It worked like this: date +"%Y-%m-%d %H:%M:%S" Extra \s between date and time gave the error. – LukasS Mar 09 '17 at 12:14
  • 3
    `man date` does not explain the `+` which indicates the beginning of the format string. – Timo Jan 29 '18 at 08:41
  • 1
    @Timo My guess is that the `+` is to distinguish the format string from the `-` that indicates options – studog Nov 20 '18 at 18:33
  • 2
    @harsh_v Surely the beauty of the YYYY-MM-DD date format is that it allows sorting dates easily. Removing leading zeros would prevent that. – mwfearnley Jan 28 '19 at 15:57
  • Try this:https://stackoverflow.com/questions/13533661/todays-date-minus-x-days-in-shell-script – dolphinZhang Feb 13 '19 at 07:40
  • 2
    is it a good idea to name the date variable the same thing as the command `date`? – qwr Aug 24 '19 at 03:44
  • 3
    Why is it preferrable to use printf vs `date`? – Boris Verkhovskiy Oct 29 '19 at 20:28
  • `printf` can not format milliseconds. GNU `date` can. – ceving Jan 29 '20 at 13:53
  • 1
    `date +%Y-%m-%d_%H%M%S` is what I was looking for, and https://unix.stackexchange.com/a/149753/48973 helped me realize that I needed to avoid spaces. – Ryan Mar 10 '20 at 18:31
  • GNU `date` has simpler syntax than `printf`, which is why I prefer `date`. – Maxim Egorushkin Jun 02 '21 at 15:40
  • Also if you want to get GMT / Universal time you can run date with additional "-u" flag: date +%Y-%m-%d-%H%M%S -u – Altair7852 Dec 12 '21 at 19:52
  • `echo $(date '+%Y-%m-%d')` can be replaced with `date '+%Y-%m-%d'` directly – Manuel Jordan Jan 22 '22 at 15:09
444

Try: $(date +%F)

The %F option is an alias for %Y-%m-%d

malhal
  • 20,618
  • 6
  • 104
  • 120
kwatford
  • 21,848
  • 2
  • 43
  • 60
  • 14
    The man pages for date reads: %F full date; same as %Y-%m-%d, so this is just a more compact notation for the accepted answer. – Håvard Geithus Nov 16 '15 at 20:42
123

You can do something like this:

$ date +'%Y-%m-%d'
Undo
  • 25,381
  • 37
  • 106
  • 126
54

You're looking for ISO 8601 standard date format, so if you have GNU date (or any date command more modern than 1988) just do: $(date -I)

Basil Bourque
  • 262,936
  • 84
  • 758
  • 1,028
Medievalist
  • 693
  • 5
  • 8
  • 10
    I have a recent (>1988) Mac OS X computer, and `date -I` didn't work. Having installed [GNU coreutils](http://www.gnu.org/software/coreutils) using [brew](http://brew.sh/) (which uses the prefix 'g') `gdate -I` did work. – Joel Purra Aug 23 '13 at 15:47
  • 3
    Odd. I can't find the `-I` option documented for GNU `date`, although sure enough it does seem to be equivalent to `date +%F`. – chepner Oct 14 '13 at 21:55
  • 3
    OS X is generally a GPL v3 wasteland, so they might just not have updated date or BASH recently. – Indolering Dec 16 '13 at 20:50
  • 1
    I like this option because it doesn't require escaping `%` in cron. – simlev Jun 29 '20 at 09:46
53
$(date +%F)

output

2018-06-20

Or if you also want time:

$(date +%F_%H-%M-%S)

can be used to remove colons (:) in between

output

2018-06-20_09-55-58
malhal
  • 20,618
  • 6
  • 104
  • 120
ahmettolga
  • 706
  • 6
  • 15
24
date -d '1 hour ago' '+%Y-%m-%d'

The output would be 2015-06-14.

Toby Speight
  • 25,191
  • 47
  • 61
  • 93
xu2mao
  • 526
  • 4
  • 8
22

With recent Bash (version ≥ 4.2), you can use the builtin printf with the format modifier %(strftime_format)T:

$ printf '%(%Y-%m-%d)T\n' -1  # Get YYYY-MM-DD (-1 stands for "current time")
2017-11-10
$ printf '%(%F)T\n' -1  # Synonym of the above
2017-11-10
$ printf -v date '%(%F)T' -1  # Capture as var $date

printf is much faster than date since it's a Bash builtin while date is an external command.

As well, printf -v date ... is faster than date=$(printf ...) since it doesn't require forking a subshell.

wjandrea
  • 23,210
  • 7
  • 49
  • 68
  • 4
    As a note in 2019, this command is incredibly faster* than `date` if you are using this from within a bash script already, as it doesn't have to load any extra libraries. (* I measured on my linux server a ~160x speed difference over 1000 iterations) – timtj May 24 '19 at 13:11
  • @timtj Thanks for pointing that out! I added some notes about speed to the answer. – wjandrea May 24 '19 at 14:35
  • 1
    I wish I could +5 for the comment about `printf -v date` not forking a subshell. Very good info!! – timtj May 26 '19 at 12:47
  • Usually I use date because I also need to increment through some dates. Can printf do date arithmetic? – Merlin Sep 30 '19 at 22:07
  • 1
    @Merlin I don't think so – wjandrea Sep 30 '19 at 22:52
14

I use the following formulation:

TODAY=`date -I`
echo $TODAY

Checkout the man page for date, there is a number of other useful options:

man date
Luís de Sousa
  • 4,634
  • 7
  • 44
  • 77
  • 1
    This answer seems equivalent to [this other one](https://stackoverflow.com/a/17195700/9164010), which actually uses the other syntax `$( … )` for command substitution; see e.g. [GreyCat](https://mywiki.wooledge.org/)'s [BashFAQ #082](https://mywiki.wooledge.org/BashFAQ/082) for details. – ErikMD Aug 04 '21 at 20:31
10

if you want the year in a two number format such as 17 rather than 2017, do the following:

DATE=`date +%d-%m-%y`
ford prefect
  • 6,478
  • 10
  • 54
  • 83
kgui
  • 3,879
  • 4
  • 39
  • 51
8

I use $(date +"%Y-%m-%d") or $(date +"%Y-%m-%d %T") with time and hours.

treyBake
  • 6,277
  • 6
  • 25
  • 54
Miguel
  • 2,945
  • 2
  • 29
  • 28
7

Whenever I have a task like this I end up falling back to

$ man strftime

to remind myself of all the possibilities for time formatting options.

arp
  • 279
  • 3
  • 7
7

Try to use this command :

date | cut -d " " -f2-4 | tr " " "-" 

The output would be like: 21-Feb-2021

Abdallah_98
  • 1,233
  • 5
  • 15
5
#!/bin/bash -e

x='2018-01-18 10:00:00'
a=$(date -d "$x")
b=$(date -d "$a 10 min" "+%Y-%m-%d %H:%M:%S")
c=$(date -d "$b 10 min" "+%Y-%m-%d %H:%M:%S")
#date -d "$a 30 min" "+%Y-%m-%d %H:%M:%S"

echo Entered Date is $x
echo Second Date is $b
echo Third Date is $c

Here x is sample date used & then example displays both formatting of data as well as getting dates 10 mins more then current date.

ankitbaldua
  • 253
  • 3
  • 12
2

I used below method. Thanks for all methods/answers

ubuntu@apj:/tmp$ datevar=$(date +'%Y-%m-%d : %H-%M')
ubuntu@apj:/tmp$ echo $datevar
2022-03-31 : 10-48
Anto
  • 2,192
  • 1
  • 14
  • 13
2

Try this code for a simple human readable timestamp:

dt=$(date)
echo $dt

Output:

Tue May 3 08:48:47 IST 2022
Stephen Ostermiller
  • 21,408
  • 12
  • 81
  • 104
0

You can set date as environment variable and later u can use it

setenv DATE `date "+%Y-%m-%d"`
echo "----------- ${DATE} -------------"

or

DATE =`date "+%Y-%m-%d"`
echo "----------- ${DATE} -------------"
Farid Haq
  • 2,960
  • 17
  • 14