TL;DR: date prints out the date.

I didn't know about this one before my friend Stephanie brought it up.

"That's a thing?  How did I not know about this?"  Especially given my irrational love for cal.

This one is pretty neat though, and it's got a few tricks up its sleeve.  For the most part, this is probably going to be useful when running Bash scripts which require current dates or series of dates, but it can also be a quick way to check some stuff.

Let's just do a few examples and you'll get the gist.  Depending on how you have your time zones set up, your stuff might look a bit different.

$ date
Wed Feb 12 15:18:21 UTC 2020

# Format Dates Nicely!
$ date +"%Y-%m-%d %H:%M:%S %Z"
2020-02-12 15:19:16 UTC

# Easily convert datetimes to another timezone!
$ TZ="EST" date +"%Y-%m-%d %H:%M:%S %Z"
2020-02-12 15:19:41 EST

# Look at future dates!
$ date --date="next Thursday"
Thu Feb 13 00:00:00 UTC 2020

$ date --date="next Sat"
Sat Feb 15 00:00:00 UTC 2020

# Other weird stuff!
$ date --date="-35 hours 12 minutes"
Tue Feb 11 04:40:18 UTC 2020

$ date --date="6 years 3 days -421 hours 6 minutes -1 seconds"
Thu Jan 29 02:35:35 UTC 2026

# And you can combine the above with formatting.
$ date --date="6 years 3 days -421 hours 6 minutes -1 seconds" +"%Y-%m-%d %H:%S:%M %Z"
2026-01-29 02:12:38 UTC

The only things to note here are:

  • When specifying things like "next Sat" or adding time we use the flag --date, this is mostly timedelta-based things.
  • When formatting a date, you need to put a + in front of it without using the --date flag in front of it — see the last example for the way to do this.  This uses the standard time formatting abbreviations that you know and love.

Using the above, it's pretty easy to make a script that, for example, lists every date in a range if you're into that sort of thing.  

$ for num in $(seq 1 5); do echo $(date --date="$num day" +"%Y-%m-%d"); done