1469

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

phuclv
  • 37,963
  • 15
  • 156
  • 475
Kapsh
  • 20,751
  • 13
  • 36
  • 44
  • 13
    Comments must be at the least 15 words in length. date -I – abc Oct 15 '20 at 05:12
  • 23
    Indeed `date -I` is all you need. It took me years to stumble upon that. – Sridhar Sarnobat Mar 15 '21 at 23:28
  • 5
    `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

18 Answers18

2247

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). Note that invoking a subshell has performance problems in Cygwin due to a slow fork() call on Windows.

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
Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
Philip Fourie
  • 111,587
  • 10
  • 63
  • 83
  • 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
  • 46
    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
  • 37
    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
  • 3
    @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
  • `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
515

Try: $(date +%F)

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

malhal
  • 26,330
  • 7
  • 115
  • 133
kenm
  • 23,127
  • 2
  • 43
  • 62
148

You can do something like this:

$ date +'%Y-%m-%d'
Undo
  • 25,519
  • 37
  • 106
  • 129
82
$(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
  • 26,330
  • 7
  • 115
  • 133
ahmettolga
  • 996
  • 7
  • 16
56

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
  • 303,325
  • 100
  • 852
  • 1,154
Medievalist
  • 713
  • 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
  • 4
    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
  • 4
    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
27
date -d '1 hour ago' '+%Y-%m-%d'

The output would be 2015-06-14.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
xu2mao
  • 572
  • 6
  • 8
24

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
  • 28,235
  • 9
  • 60
  • 81
  • 5
    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
19

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
  • 5,765
  • 11
  • 49
  • 86
  • 2
    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
12

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
  • 7,096
  • 11
  • 56
  • 83
kgui
  • 4,015
  • 5
  • 41
  • 53
10

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
  • 3,128
  • 1
  • 20
  • 20
9

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
  • 299
  • 3
  • 7
9

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

treyBake
  • 6,440
  • 6
  • 26
  • 57
Miguel
  • 3,349
  • 2
  • 32
  • 28
7

Try to use this command :

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

The output would be like: 21-Feb-2021

Abdallah_98
  • 1,331
  • 7
  • 17
  • this is the worst method ever! Not only it's longer and slower, it also **doesn't work at all for most locales**. Try `LC_ALL=C.UTF-8 date`, `LC_ALL=de_DE.UTF-8 date`, `LC_ALL=fr_FR.UTF-8 date`, `LC_ALL=ru_RU.UTF-8 date`, or `LC_ALL=el_GR.UTF-8 date`... for example. It doesn't even work for all English locales – phuclv Sep 27 '22 at 07:09
  • `date` outputs a human-readable date in the current locale, so parsing it is as useless as parsing `apt install` output – phuclv Sep 27 '22 at 15:51
6
#!/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
  • 263
  • 4
  • 14
4
echo "`date "+%F"`"

Will print YYYY-MM-DD

Harikrishna
  • 438
  • 5
  • 8
  • 1) There were already so many answers on `%F`. 2) This is wrong & redundant in so many levels: using backticks is deprecated, see the unreadable quotes? using `$()` would be much more readable; there's no need to spawn a subshell, capture its output and print with `echo` when a single `date "+%F"` in the current shell is already enough – phuclv Sep 27 '22 at 15:48
2

date +%Y-%m-%dT%H:%M:%S

will print something like 2023-07-18T11:09:16 which is generally known as RFC-3339

zeg
  • 432
  • 2
  • 9
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
  • 3,728
  • 1
  • 21
  • 15
  • ```backticks`` ``` are obsolete and deprecated long ago. Never use them, use `$()` instead which is nestable and readable – phuclv Sep 27 '22 at 15:42
-5

Try this code for a simple human readable timestamp:

dt=$(date)
echo $dt

Output:

Tue May 3 08:48:47 IST 2022
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109