38

The date command doesn't offer such thing, which is kind of sad since RFC-3339 is the modern, widespread, sane format used everywhere (except in email which is neither modern nor sane).

My timezone offset is currently -08:00 so the simplest form of this command should print the current time as 2013-09-05T14:58:33.102-08:00.

4
  • Which standard (s) are you interested in? Commented Mar 19, 2014 at 21:54
  • I personally am fine with GNU but in the grand scheme of things it really should be broader than that. It should also come with a reasonable default (short option, millisecond precision) and have a way to specify the subsecond precision (number of digits other than 0 or 9). Commented Mar 19, 2014 at 22:37
  • 1
    It's not a sane format: the total absence of whitespace makes it unnecessarily hard for humans to read. You should use the slight variation 2013-09-05 14:58:33.102 -0800 except when there is some reason why spaces must not be used at all.
    – zwol
    Commented Mar 20, 2014 at 1:26
  • 2
    I was comparing it to the mail date format (RFC 822, 2822) which is hard to read for both humans and machines. Commented Mar 20, 2014 at 1:31

7 Answers 7

49

It seems like you can do several formats using the switch to the GNU implementation of date (version 5.90 or above), --rfc3339=.

Examples

$ date --rfc-3339=date
2014-03-19

$ date --rfc-3339=seconds
2014-03-19 18:00:05-04:00

$ date --rfc-3339=ns
2014-03-19 18:00:08.179780629-04:00

If you want the T to be added, as a hack:

$ date --rfc-3339=seconds | sed 's/ /T/'
2014-03-19T18:35:03-04:00

If you want it in milliseconds:

$ date --rfc-3339=ns | sed 's/ /T/; s/\(\....\).*\([+-]\)/\1\2/g'
2014-03-19T18:42:52.362-04:00

References

7
  • 14
    These days, no hack is needed to get the 'T'. The --iso-8601' option accepts the same arguments as --rfc-3339`, and includes the 'T' in its output.
    – Ti Strga
    Commented Mar 23, 2016 at 18:41
  • 1
    Sed part s/\(\....\).*-/\1-/g should be s/\(\....\).*\([+-]\)/\1\2/g to also work east of the Atlantic.
    – svante
    Commented Sep 11, 2019 at 12:01
  • 1
    @svante - thanks for the detail, fixed.
    – slm
    Commented Sep 11, 2019 at 12:09
  • 3
    @Eonil that is actually not correct, the RFC3339 states: NOTE: ISO 8601 defines date and time separated by "T". While RFC3339 allows you to use a space instead. Read ietf.org/rfc/rfc3339.txt Section 5.6
    – rwenz3l
    Commented Oct 8, 2019 at 12:47
  • 2
    @rwenz3l My fault. I just read only ABNF part and missed the notes. Thanks for pointing it out!
    – Eonil
    Commented Oct 9, 2019 at 9:46
19

With GNU date (5.90 or above):

$ TZ=America/Anchorage date '+%FT%T.%N%:z'
2014-03-19T14:29:31.041119357-08:00

Replace %N with %3N for milliseconds, %6N for micro-seconds...

AFAIK, none of the POSIX, Unix or LSB specifications specify any command that can display times with sub-second granularity, but the fractional part is optional in RFC 3339.

POSIX/Unix/LSB strftime supports %z to display the TZ offset as -0800, so the most portable you're probably going to get is:

 $ TZ=America/Anchorage perl -MPOSIX -le '$t = strftime "%Y-%m-%dT%T%z",
   localtime; $t =~ s/..$/:$&/; print $t'
 2014-03-19T14:30:23-08:00
19

You can also format time according to RFC3339 ( ISO8601 ) easier:

$ date -u +"%Y-%m-%dT%H:%M:%SZ"
2016-11-08T08:52:55Z

NOTE: This format is also used in the Label Schema Convention RC 1.0

3
  • 1
    That's not a valid RFC3339. Eran's answer of ``` date +%Y-%m-%dT%T%z ``` is correct and less characters. If you want in UTC pass -u flag, which will zero out the timezone offset.
    – briceburg
    Commented Nov 14, 2017 at 19:25
  • 1
    With the -u flag this answer is correct, right?
    – Lassi
    Commented Dec 14, 2019 at 15:41
  • 1
    @briceburg why is this not valid RFC3339? According to tools.ietf.org/html/rfc3339#section-5.6 it seems to be correct as far as I can tell. Commented Apr 27, 2020 at 23:57
13

How about good old :

$ date +%Y-%m-%dT%T%z
2015-10-29T14:47:06+0200
7
  • Where is the time zone information? Commented Oct 29, 2015 at 12:45
  • 1
    How about milliseconds? Commented Oct 29, 2015 at 14:19
  • 8
    quick note here, without opening up the RFC, the timezone segment, 0200 is missing a colon, which may break some systems which require it. Commented Nov 30, 2015 at 17:58
  • 3
    @MikeMackintosh's note is pertinent; the output shown here is not a legal RFC 3339 date. The colon in the timezone segment is required for RFC 3339; see the definition of time-numoffset at tools.ietf.org/html/rfc3339#section-5.6.
    – Mark Amery
    Commented Nov 14, 2017 at 15:34
  • 1
    This could be simplified to date -u "+%FT%TZ". Example output: 2021-03-20T18:23:14Z.
    – jrc
    Commented Mar 20, 2021 at 18:24
9

GNU date has the ISO-8601 format built in - isn't that quite close or even idential to RFC-3339?

1065 % date --iso-8601=seconds
2014-03-19T16:51:16-0600
1
  • ISO-8601 allows different formattings of dates and times, but I think the OP is asking specifically for W3C Date format "Complete date plus hours, minutes, seconds and a decimal fraction of a second YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)" - W3C Date and Time Formats.
    – hakre
    Commented Oct 13, 2014 at 10:58
2
echo "Local date only:"
date '+%Y-%m-%d'
echo
echo "Local date and time:"
date '+%Y-%m-%dT%H:%M:%S%z' | sed 's@^.\{22\}@&:@'
echo
echo "UTC date and time:"
date -u '+%Y-%m-%dT%H:%M:%SZ'

These commands are POSIX-compatible, with the exception of the %z conversion specification. However, %z is widely supported and works the same way in Linux, MacOS, FreeBSD, OpenBSD, NetBSD, DragonFlyBSD, Solaris, Minix and Haiku. It also works with the tools in Busybox, Toybox and sbase (the suckless.org base system utilities). Since %z outputs the timezone offset in ±HHMM format, we need the sed pipe to add a colon and change it to ±HH:MM.

NOTE: The Heirloom project's date command has incompatible %z output: it does not print a + sign.

0

For UTC you can use.

date -u --rfc-3339=ns | sed -r 's/ /T/; s/\.([0-9]{3}).*/\.\1Z/'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .