I tried using $(date)
in my bash shell script, however, I want the date in YYYY-MM-DD
format.
How do I get this?
-
13Comments must be at the least 15 words in length. date -I – abc Oct 15 '20 at 05:12
-
23Indeed `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 Answers
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

- 30,436
- 41
- 178
- 315

- 111,587
- 10
- 63
- 83
-
6In 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
-
9I 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
-
37The 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
-
1The 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
-
1On 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
-
-
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
-
17The 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
-
1
$(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

- 26,330
- 7
- 115
- 133

- 996
- 7
- 16
-
2Appreciate the addtional time - OP may not have asked, but I'm sure most people googling this are interested! – Adam Hughes Oct 28 '21 at 19:30
-
5
-
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)

- 303,325
- 100
- 852
- 1,154

- 713
- 5
- 8
-
10I 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
-
4Odd. 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
-
4OS 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
date -d '1 hour ago' '+%Y-%m-%d'
The output would be 2015-06-14
.

- 27,591
- 48
- 66
- 103

- 572
- 6
- 8
-
5Wrong for a couple of reasons, obviously this gives the wrong date between 00:00 and 01:00, and besides you end with a `%`. – Gerhard Burger Apr 18 '16 at 15:50
-
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.

- 28,235
- 9
- 60
- 81
-
5As 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
-
1I 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
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

- 5,765
- 11
- 49
- 86
-
2This 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
if you want the year in a two number format such as 17 rather than 2017, do the following:
DATE=`date +%d-%m-%y`

- 7,096
- 11
- 56
- 83

- 4,015
- 5
- 41
- 53
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

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

- 299
- 3
- 7
Try to use this command :
date | cut -d " " -f2-4 | tr " " "-"
The output would be like: 21-Feb-2021

- 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
#!/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.

- 263
- 4
- 14
echo "`date "+%F"`"
Will print YYYY-MM-DD

- 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
date +%Y-%m-%dT%H:%M:%S
will print something like 2023-07-18T11:09:16 which is generally known as RFC-3339

- 432
- 2
- 9
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} -------------"

- 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
Try this code for a simple human readable timestamp:
dt=$(date)
echo $dt
Output:
Tue May 3 08:48:47 IST 2022

- 23,933
- 14
- 88
- 109

- 22
- 2