`date` command on OS X doesn't have ISO 8601 `-I` option?
Asked Answered
B

10

265

In a Bash script, I want to print the current datetime in ISO 8601 format (preferably UTC), and it seems that this should be as simple as date -I:

http://ss64.com/bash/date.html

But this doesn't seem to work on my Mac:

$ date -I
date: illegal option -- I
usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... 
            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]

And indeed, man date doesn't list this option.

Anyone know why this is, or any other (easy) way for me to print the date in ISO 8601 format? Thanks!

Bigener answered 27/8, 2011 at 18:5 Comment(8)
To clarify, I want a full ISO 8601 date, including the time, and preferably in UTC timezone.Bigener
It's better to just edit the question. What format do you want the time in?Nonparous
@Tom: okay, edited. By format, is ISO 8601 not specific enough?Bigener
No, ISO 8601 isn't specific enough. That standard specifies a number of formats of various precisions. Both 2011-08-27 and 2011-08-27T18:55:43Z are ISO 8601 formats. And really, editing the question would be more helpful that scatting updates across several comments. An example of what you're trying to print would be ideal.Sufflate
Having installed GNU coreutils using brew (which uses the prefix 'g') gdate -I did work, along with other GNU flags.Bentlee
@JoelPurra: It would be good to post your comment as an answer; I'd upvote it.Respirator
@codermonkeyfuel: @slm beat me to it ;)Bentlee
SS64 has a MacOS page which covers this ss64.com/osx/date.htmlCallisto
T
428

You could use

date "+%Y-%m-%d"

Or for a fully ISO-8601 compliant date, use one of the following formats:

date -u +"%Y-%m-%dT%H:%M:%SZ"

Output:

2011-08-27T23:22:37Z

or

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

Output:

2011-08-27T15:22:37-0800
Tay answered 27/8, 2011 at 18:12 Comment(9)
Technically, the "T" is recommended but optional in ISO 8601. Using a space instead of 'T' would be: date -u +"%Y-%m-%d %H-%M-%SZ"Fairfield
Finally! I added this to my bash_aliasIncommodious
Yup, awesome answer Thanks!, but this date -u +"%Y-%m-%dT%H:%MZ" exactly I was looking for.Provenance
Why is the Z there? Ruby's #iso8601 doesn't seem to have it: ruby -e 'require "time"; puts Time.now.iso8601' #=> 2017-04-10T13:44:03-07:00Meacham
@Meacham : Z and +00:00 are the same (mostly). For purposes of translating time, they both mean UTC. However England is +00:00 in winter and +01:00 in summer (BST).Bagman
@JeffreyHulten: "they both mean UTC" - Nitpick, but Z is UTC, while +00:00 is GMT. UTC is not a timezone and does not have an offset; offset is defined as the time difference between a timezone and UTC, the standard of time measurement. GMT is +00:00 removed from UTC (and BST is, as you say, +01:00 removed from UTC).Potty
BTW: Your solution is the most portable. I get identical results on mac and alpine and ubuntuIncommodious
@BasilBourque, as you already mentioned, the T can be omitted, but not in all cases. There are rare possibilities of ambiguity depending on the format you're using. Probably obvious but seemed worthy to note. As written on Wikipedia, "So a time might appear as either "T134730" in the basic format or "T13:47:30" in the extended format. ISO 8601-1:2019 allows the T to be omitted in the extended format, as in "13:47:30", but only allows the T to be omitted in the basic format when there is no risk of ambiguity with date expressions."Kathrynkathryne
I should add that, my previous comment was only referring to times in ISO-8601-1:2019 format. When referring to combinations of date and time, the Wiki page says that separating date and time with a character other than T is no longer supported in ISO-8601-1:2019 but it is supported in its profile, RFC 3339. In short, I'm just confusing things and it's generally fine to omit the T :) Just adding the details I noticed regarding the newer spec.Kathrynkathryne
P
73

In GNU date date -I is the same as date +%F, and -Iseconds and -Iminutes also include time with UTC offset.

$ date +%F # -I or +%Y-%m-%d
2013-05-03
$ date +%FT%T%z # -Iseconds or +%Y-%m-%dT%H:%M:%S%z
2013-05-03T15:59:24+0300
$ date +%FT%H:%M # -Iminutes or +%Y-%m-%dT%H:%M%z
2013-05-03T15:59+0300

-u is like TZ=UTC. +00:00 can be replaced with Z.

$ date -u +%FT%TZ
2013-05-03T12:59:24Z

These are also valid ISO 8601 date or time formats:

20130503T15 (%Y%m%dT%M)
2013-05 (%Y%m)
2013-W18 (%Y-W%V)
2013-W18-5 (%Y-W%V-%u)
2013W185 (%YW%V%u)
2013-123 (%Y-%j, ordinal date)
2013 (%Y)
1559 (%H%M)
15 (%H)
15:59:24+03 (UTC offset doesn't have to include minutes)

These are not:

2013-05-03 15:59 (T is required in the extended format)
201305 (it could be confused with the YYMMDD format)
20130503T15:59 (basic and exteded formats can't be mixed)
Psalter answered 3/5, 2013 at 14:11 Comment(1)
hooray for +"%FT%T%z" that's exactly what I neededXiomaraxiong
C
28

A short alternative that works on both GNU and BSD date is:

date -u +%FT%T%z
Crosspatch answered 7/12, 2015 at 16:27 Comment(1)
or date -u +%FT%TZ because in UTC offset would be zero anywayUntouched
S
25

The coreutils package provides GNU versions of tools. To install:

$ brew install coreutils

You can see what's provided:

$ brew list coreutils

Notice it comes with date:

$ brew list coreutils | grep date

This is the standard GNU date command so it'll take the -I switch:

$ gdate -I
2016-08-09
Sakhuja answered 9/8, 2016 at 16:29 Comment(1)
Or : gdate --iso-8601=ns : 2016-09-29T16:54:23,485230000+02:00Subdual
N
8

Just use normal date formatting options:

date '+%Y-%m-%d'

Edit: to include time and UTC, these are equivalent:

date -u -Iseconds

date -u '+%Y-%m-%dT%k:%M:%S%z'
Nonparous answered 27/8, 2011 at 18:11 Comment(1)
Added a comment to my OP clarifying that I want the full date, including the time, and preferably in UTC timezone. Thanks for the tip, though!Bigener
B
5

Taking the other answers one step further, you could add a function to your ~/.bashrc or ~/.zshrc to add the date -I flag:

date() {
  if [ "$1" = "-I" ]; then
    command date "+%Y-%m-%dT%H:%M:%S%z"
  else
  command date "$@"
  fi
}
Bradeord answered 11/10, 2018 at 12:55 Comment(0)
W
3

It's not a feature of Bash, it's a feature of the date binary. On Linux you would typically have the GNU coreutils version of date, whereas on OSX you would have the BSD legacy utilities. The GNU version can certainly be installed as an optional package, or you can roll your own replacement - I believe it should be a simple one-liner e.g. in Perl.

Wringer answered 27/8, 2011 at 18:14 Comment(1)
Interesting, thanks. I'm kind of a Mac/Linux/Unix/Bash noob; would you mind elaborating on coreutils and how to install it on Mac? Thanks!Bigener
B
2

There's a precompiled coreutils package for Mac OS X available at:

http://rudix.org/packages-abc.html#coreutils.

Beelzebub answered 28/8, 2011 at 10:3 Comment(0)
O
1

So many years later, but in macOS 12 (Monterey) man date does include the -I option, but it generates the same error, unless you dig further and find

 date -u -I seconds
2023-08-04T03:59:20+00:00

I note that it doesn't append "Z" to the end, but the -u option did make it output in UTC.

Ozzy answered 4/8, 2023 at 4:3 Comment(1)
date -u -Iseconds works for me, without the extra space between -I and seconds.Pagurian
K
0

I regularly use 'date -I' in Linux when saving files. ex: touch x.date -I. While the equivalent in MacOS is 'date +%F', it is a bit awkward to type every time I save a file. So, I set an alias "alias dt='date +%F'" then touch x.dt gives me the date.

Kreis answered 16/8, 2020 at 11:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.