SRCco.de

Date Formats: ISO 8601

Posted:
../galleries/date-formats/calendar.png

Date formats are plentiful and humans are creatures of habit. Communication in an international context mostly works, but date formats cause unnecessary confusion. Which date format to use?

This blog post should be obsolete as Wikipedia already knows the answer:

Writers have traditionally written abbreviated dates according to their local custom, creating all-numeric equivalents to dates such as, '30 June 2020' (30/06/20) and 'June 30, 2020' (06/30/20). This can result in dates that are impossible to understand correctly without knowing the writer's origin and/or other contextual details, as dates such as "10/11/06" can be interpreted as "10 November 2006" in the DMY format, "October 11, 2006" in MDY, and "2010 November 6" in YMD.

The ISO 8601 format YYYY-MM-DD (2020-06-30) is intended to harmonize these formats and ensure accuracy in all situations. Many countries have adopted it as their sole official date format, though even in these areas writers may adopt abbreviated formats that are no longer recommended.

This is the hill I'm willing to die on: NEVER use slashes (X/Y/Z) as date format as it's ambiguous in an international context. Use ISO format (YYYY-MM-DD) or write the full month name.

@try_except_ on Twitter

The Wikipedia Manual of Style explicitly lists acceptable and unacceptable date formats:

Acceptable:

  • 2 September 2001 — ok

  • 2 Sep 2001 — only where brevity is helpful

  • September 2, 2001 — "The weather on March 12, 2005, was clear and warm"

  • Sep 2, 2001 — only where brevity is helpful

  • 2001-09-02 — only where brevity is helpful

Unacceptable:

  • 09-06 — not ok

  • 06-09 — not ok

  • 2007/04/15 — do not use separators other than hyphens

  • 15-04-2007 — do not use dd-mm-yyyy or mm-dd-yyyy formats

Date Formats in the Wild

Confusion with different date formats is not just a theoretical problem! I can remember at least three situations where people needed to ask what date is meant (d/m or m/d).

@try_except_ on Twitter

Some date formats I encountered in the wild:

  • 2020/03/02 — is this March 2, or February 3? It really makes a difference when seeing this as a due date on 1st of February. Do we have two days or one month remaining?

  • 07.10.2019 — the "German" date format, I can read it, but what about international colleagues?

  • 11.28.2019 — M.D.Y 😱

  • 05-02-2020 — please, just don't!

  • 27 Nov’17 — ok, we survived 2k, but can we please keep 4 digits for the year?

  • 10/10-11/10 — look, a "date" range! Are we talking about one day or one month?

I was raised in Germany, so my native all-numeric date format would be DD.MM.YYYY. DD.MM.YYYY is relatively "safe" (I never saw MM.DD.YYYY being used [1]), but I still advocate for the ISO date format as it has obvious benefits.

ISO 8601

The International Organization for Standardization (ISO) date format (ISO 8601) is a standard way to express a numeric calendar date that eliminates ambiguity. It has some nice properties:

  • Date values are ordered from the largest to smallest unit of time: year, month, and day.

  • Sorting ISO dates lexicographically will order the dates correctly by time. This allows dates to be naturally sorted by, for example, file systems.

  • Each date value has a fixed number of digits that must be padded with leading zeros. This allows to conveniently extract fixed substrings.

  • ISO 8601 is "the Internet Date/Time Format": RFC3339 defines a subset of ISO 8601 as the Internet Date/Time Format.

Valid ISO date/time formats include:

  • 2020-06-30

  • 2020-06-30T20:41 (no timezone specified)

  • 2020-06-30T20:41:26Z (UTC timezone)

  • 2020-06-30T22:41:26+02:00 (CEST, UTC+2 timezone)

  • 2020-06-30 20:41 (RFC3339 allows space as separator for readability)

For Python programmers: the Python standard library supports parsing and formatting ISO date/time natively since Python 3.7:

import datetime

# dates
d = datetime.date.fromisoformat("2020-06-30")
d.isoformat()  # => 2020-06-30

# date/time (without timezone)
dt = datetime.datetime.fromisoformat("2020-06-30T20:41:26.538088")
dt.isoformat()  # => 2020-06-30T20:41:26.538088

Summary

Use the ISO date format (2020-06-30) or the full textual format (US: June 30, 2020, UK: 30 June 2020) to avoid confusion.

No, this is not about being "right" or "wrong", but about avoiding confusion in an international context. Other people already thought about this problem and found a solution: the ISO date/time format!

Further Reading

xkcd: ISO 8601