Search notes:

Shell command: date

date [OPTION]… [+FORMAT]
date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]

Options

-d --date STRING display time described by STRING (without -d, date assumes now).
--debug Annotate the parsed date, and warn about questionable usage to stderr.
-f --file DATEFILE like --date; once for each line of DATEFILE
-I --iso FMT Output date/time in ISO 8601 format. FMT is one of date, hours, minutes, seconds or ns and specifies the intended precision, for example: 2006-08-14T02:34:56-06:00.
--resolution Output the available resolution of timestamps, for example: 0.000000001
-R --rfc-email Output date and time in RFC 5322 (internet message) format, for example: Mon, 14 Aug 2006 02:34:56 -0600
--rfc-3339 PREC Output date/time in RFC 3339 (date and time on the internet) format. PREC is one of date, seconds or ns and specifies the precision, for example: 2006-08-14 02:34:56-06:00.
-r --reference FILE display the last modification time of FILE
-s --set STRING set time described by STRING
-u --utc, --unversal Use UTC
--help
--version output version information and exit

-d Specify a date with a user friendly string

Display the time described by the user friendly string.
Without -d, date operates on the date described by now.
date -d "+5 days"
date -d "+7 weeks +2 days"
date -d "last Wednesday 2 pm"
Github repository shell-commands, path: /date/d_arithmetic
Using @… allows to calculate the date from a Unix epoch (seconds since 1970-01-01):
$ date +%s -d '2023-08-14 08:05:17'
1691964000
$ date date +'%F %T' -d @1691993117
2023-08-14 08:05:17
Compare with -d flag of touch.

Formatting output

The output of date can be formatted with a format string that is preceded by a + sign (see also strftime):
$ date +'Year: %Y, Month: %m, Day: %d'
Year: 2023, Month: 08, Day: 14

Format specifiers

Each format specifier is prepended by a percent sign (i. e. the % is factually a %%):
Example
% A literal %
a Locale's abbreviated weekday name Sun
A Locale's full weekday name Sunday
b Locale's abbreviated month name Jan
B Locale's full month name January
c Locale's date and time Thu Mar 3 23:05:25 2005
C Century; like %Y, except omit last two digits. See also %y 20
d Day of month 01
D Date, same as %m/%d/%y (but locale dependend, so it might also print %y-%d-%m!)
e Day of month, space padded; same as %_d
F Full date; like %+4Y-%m-%d
g Last two digits of year of ISO week number, see %G
G Year of ISO week number (see %V); normally useful only with %V
h Same as %b
H Hour (0023)
I Hour (0012)
j Day of year (001366)
k Hour, space padded ( 023); same as %_H
l Hour, space padded ( 112); same as %_I
m Month (0112)
M Minute (0059)
n A newline
N Nanoseconds (000000000999999999)
p Locale's equivalent of either AM or PM. Blank if not known
P Lower case variant of %p
q Quarter of year (14)
r Locale's 12-hour clock time 11:11:04 PM
R 24-hour hour and minute; same as %H:%M
s Seconds since the Unix epoch
S Second 0060 (is this correct, should it not be 59?)
t A tab
T Time; same as %H:%M:%S
u Day of week (17, 1 is Monday)
w Day of week (06); 0 is Sunday
U Week number of year, with Sunday as first day of week (0053)
V ISO week number, with Monday as first day of week (0153)
W Week number of year, with Monday as first day of week (0053)
x Locale's date representation 12/31/99
X Locale's time representation 23:13:48
y Last two digits of year (0099). See also %C
Y Year
z +hhmm numeric time zone -0400
:z +hh:mm numeric time zone -04:00
::z +hh:mm:ss numeric time zone -04:00:00
:::z numeric time zone with : to necessary precision -04, +05:30
Z alphabetic time zone abbreviation EDT

Flags

The following optional flags may be put between the % and the format specifier:
- (hyphen) do not pad the field
_ (underscore) pad with spaces
0 (zero) pad with zeros
+ pad with zeros, and put + before future years with >4 digits
^ use upper case if possible
# use opposite case if possible

ISO 8601, RFC 3339 or email format

-I or --iso-8601 prints the date in ISO 8601 format.
$ date -I
2018-03-15

$ date --iso-8601 # seems to be equivalent
2018-03-15
Similarly, --rfc-3339=x prints a date in RFC 3339 format, x being date, sec or ns. (Note that in RFC 3339, there is no T that separates the date portion from the time portion in the result):
$ date --rfc-3339=date
2021-08-20

$ date --rfc-3339=sec
2021-08-20 11:07:07+00:00

$ date --rfc-3339=ns
2021-08-20 11:07:10.178274618+00:00
Then, there is also the so called email format
$ date --rfc-email
Fri, 20 Aug 2021 11:07:37 +0000

Seconds since Unix epoch

+%s (lower case s) formats a date as Unix time (which is the number of (non-leap) seconds since 1970-01-01).
#!/bin/sh

some_date='2001-02-03 04:05:06'

# Convert date into seconds (Format is %s)
seconds_since_epoch=$(date -d "$some_date" +%s)

echo $some_date is $seconds_since_epoch seconds from 1970-01-01 away
#
# 2001-02-03 04:05:06 is 981169506 seconds from 1970-01-01 away

# Convert seconds into date with using @
echo $seconds_since_epoch seconds from 1970 is $(date -d @$seconds_since_epoch)
#
# 981169506 seconds from 1970 is Sam Feb 3 04:05:06 CET 2001
Github repository shell-commands, path: /date/d_seconds-since-epoch
date +%s in combination with expr can be used to calculate elapsed time in seconds.

Time zones

Some z and Z specifiers show the currently active time zone
echo $(date '+%z'   ) # +0200
echo $(date '+%:z'  ) # +02:00
echo $(date '+%::z' ) # +02:00:00
echo $(date '+%:::z') # +02         (Print required precision only)
echo $(date '+%Z'   ) # CEST        (Alphabetic timezone abbreviation)
Github repository shell-commands, path: /date/z_time-zone

TZ environment variable

The value of the TZ environment variable influences the output of date:
# vim: ft=sh
date_with_tz() {
  printf "%-20s %s\n" $1 "$(TZ=$1 date)"
}

date_with_tz Europe/Lisboa
date_with_tz Europe/Zurich
date_with_tz America/Los_Angeles

# Script prints:
#   Europe/Lisboa        Sam Dez 16 12:41:47 Europe 2017
#   Europe/Zurich        Sam Dez 16 13:41:47 CET 2017
#   America/Los_Angeles  Sam Dez 16 04:41:47 PST 2017
Github repository shell-commands, path: /date/TZ

Common formats

https://zxq9.com/archives/795 summarizes which options return a desired comman date format:
YYYY-MM-DD_hh:mm:ss date +%F_%T
YYYYMMDD_hhmmss date +%Y%m%d_%H%M%S
YYYYMMDD_hhmmss (UTC version) date --utc +%Y%m%d_%H%M%SZ
YYYYMMDD_hhmmss (with local TZ) date +%Y%m%d_%H%M%S%Z
YYYYMMSShhmmss date +%Y%m%d%H%M%S
YYYYMMSShhmmssnnnnnnnnn date +%Y%m%d%H%M%S%N
YYMMDD_hhmmss date +%y%m%d_%H%M%S
Seconds since UNIX epoch date +%s This option is useful for date arithmetic such as calculating the differences between to timestamps.
Nanoseconds only date +%N
Nanoseconds since UNIX epoch date +%s%N
Z-notation UTC timestamp date --utc +%FT%TZ
Z-notation UTC timestamp + ms date --utc +%FT%T.%3NZ
ISO8601 UTC timestamp date --utc +%FT%T%Z
ISO8601 UTC timestamp + ms date --utc +%FT%T.%3N%Z
ISO8601 Local TZ timestamp date +%FT%T%Z
YYYY-MM-DD (Short day) date +%F\(%a\)
YYYY-MM-DD (Long day) date +%F\(%A\)

See also

Calculate difference between two dates with date arithmetic.
faketime manipulates the system time for a given command.
UTC
The cmd.exe commands date and time
The PowerShell command noun date and especially the get-date cmdLet.

Index