This note added August 18, 2017 - ammended January 16, 2018 This draft specification is superceded; EDTF functionality has been integrated into a draft revision of ISO 8601 to be published in 2018. The revision of ISO 8601 consists of two parts. Part 2 is Extensions, one of which is EDTF. (The full functionality of this draft specification is retained, however several syntactic changes were necessary, to satisfy international requirements.) Draft International Standard DIS ISO 8601-2018 has successfull ycompleted DIS ballot and is now in final editing stage . |
August 30, 2012. Minor editorial corrections applied. See http://listserv.loc.gov/cgi-bin/wa?A2=ind1208&L=datetime&T=0&X=0668D07233CC5FAE81&P=974
September 10, 2012. Additional minor editorial corrections applied. See http://listserv.loc.gov/cgi-bin/wa?A2=ind1208&L=datetime&T=0&X=585F336DE4AE48724C&P=2519 and
http://listserv.loc.gov/cgi-bin/wa?A2=ind1209&L=datetime&T=0&X=31F9AB39B03E40C1C8&P=62
March 18, 2014. Minor editorial corrections applied. See Spaces Removed and http://listserv.loc.gov/cgi-bin/wa?A2=ind1403&L=datetime&T=0&X=1A10F96E1DF2376B79&Y=rden%40loc.gov&P=149
October 16, 2014. Minor formatting error corrected (table of contents).
Listed here are proposals to be considered during further development of this specification
This specification defines features to be supported in a date/time string, features considered useful for a wide variety of applications. It takes the form of a profile of / extension to ISO 8601, the International Standard for the representation of dates and times. ISO 8601 describes a large number of date/time formats. On one hand some of these formats are redundant and/or not very useful; to reduce the scope for error and the complexity of software, it seems worthwhile to restrict the supported formats to a smaller set. On the other hand, there are a number of date and time format conventions in common use that are not included in ISO 8601; it seems worthwhile to normalize these.
Annex A. (Non Normative) Possible Future Features
Basic date and time formats are specified in ISO 8601 [ISO8601] (Hereafter, "8601".). But 8601 is not sufficiently expressive to support various semantic qualifiers and concepts than many applications find useful. For example, although 8601 can express the concept "the year 1984", it cannot express "approximately the year 1984", or "we think the year is 1984 but we're not certain". As another example, 8601 can express an interval, for example "the period of time beginning sometime during 1960 and ending sometime during 1969" but it cannot express "the date is a year, and it is some year between 1960 and 1969". These as well as various other concepts are currently represented according to various ad hoc conventions, and this specification aims to provide a standard syntax for their representation.
On the other hand, 8601 is a complex specification that describes a large number of date/time formats, and in many cases provides multiple options for a given format. Thus a second aim of this specification is to restrict the supported formats to a smaller set. This specification therefore profiles 8601 in the sense that it discards many redundant or less-useful features. It is not, however, strictly a profile of 8601; It also extends 8601, that is, it includes features that are not in 8601.
This specification therefore prescribes certain 8601 features as well as features that are extensions of 8601. The specification defines three levels:
Level 0 may be considered a profile of 8601. Features in levels 1 and 2 are not currently supported by 8601.
There is a W3C Note, Date and Time formats [W3CDTF] which similarly aims to provide a specification that simplifies 8601. That note was written in 1997 and has not been updated. This specification is intended to be compatible with that note.
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC 2119].
An implementation of this specification MUST support Level 0, and MUST state which (if either) additional level (1 or 2) is supported.
Approximate: An estimate whose value is asserted to be possibly correct, and if not, close to correct. (Where 'close to correct' means "close enough, for the application".)
Date: A year; year and month; or year, month, and day.
Date String: A finite sequence of characters representing a date as prescribed by this specification.
Date/Time String: A finite sequence of characters representing date and time, as prescribed by this specification.
Interval. An interval, as represented by a start and end date, is a period of time beginning sometime during the start date and ending sometime during the end date.
Interval string: A string representing the start and end date of an interval.
Precision: When a date string is cited, for purposes of indicating when an event occurred (or will occur), the precision of that date string is its measure of accuracy expressed as a date/time unit, e.g "year precision". For example, if an event is known to have occurred in 1984, then '1984', cited as the date when the event occurred, is said to have "year" precision. If an event is know to have occurred in December of 1984, then that date has "month" precision. If an event is know to have occurred December 12, 1984, then that date has "day" precision.
Uncertain: A date or date/time is considered "uncertain" when the process by which it is constructed (e.g. a user or some machine process extracting or converting data or metadata) determines algorithmically or based on rules of operation, that its source is dubious.
Unspecified: The value is unstated. It could be because the date (or part of the date) has not (yet) been assigned (it might be assigned in the future), or because it is classified, or unknown, or for any other reason.
A date string represents one of the following:
For 1 and 2, these MUST take 8601 extended form only, i.e. with hyphens.
Year MUST be four digits. (Years longer than four digits are covered in levels 1 and 2.)
A year may be positive, negative, or year zero. (This specification assumes astronomical numbering, which includes the year zero. )
A date/time string MUST be composed according to one of three representations as illustrated in the following three examples:
Note: 'T' separating date and time must be upper case.
The date/time string MUST use 8601 extended form, i.e. date with hyphen, time with colon. Zone-offset may be omitted or included. 8601 extended format time zone designation consists of either a 'Z' to indicate UTC, or a '+' or '-' to indicate "ahead of UTC" or "behind UTC", followed by a 2-digit hour, followed optionally by a colon and the 2-digit minutes.
An interval, as represented by a start date and an end date, is a period of time beginning sometime during the start date and ending sometime during the end date. The actual instant at which the interval begins or ends can be narrowed down only to the precision of the start or end date.
The start and end dates are both as prescribed in 5.1.1. Either endpoint may be a year, year-month, or year-month-day. The end endpoint must be later than or equal to the start endpoint.
An interval string is a start date and an end date, separated by a forward slash.
Examples
The characters '?' and '~' are used to mean "uncertain" and "approximate" respectively, and in combination, i.e. '?~', to mean "uncertain" as well as "approximate". These characters may occur only at the end of the date string and apply to the entire date. (To qualify part of the date, see level 2.)
Examples
The character 'u' may be used in place of a digit to indicate that the value of that digit is unspecified. It may be substituted for each of multiple digits, however for level 1, only the right-most one or two digits may be replaced, for the following cases:
Examples
For some applications, "u" is used as a placeholder, whose value might be filled in later. Precision for a date whose string includes the 'u' syntax assumes that the unspecified portion will eventually be supplied. Thus 199u and 19uu have year precision, 1999-uu has month precision, and 1999-01-uu and 1999-uu-uu have day precision.
As noted in 5.1.3, an interval string is a start date and an end date, separated by a forward slash.
For level 1:
Examples
'y' may be used at the beginning of the date string to signify that the date is a year, when (and only when) the year exceeds four digits, i.e. for years later than 9999 or earlier than -9999. (An alternative, exponential form, with optional precision, is allowed in level 2.)
Examples
The values 21, 22, 23, 24 may be used used to signify ' Spring', 'Summer', 'Autumn', 'Winter', respectively, in place of a month value (01 through 12) for a year-and-month format string.
Example
The use of the characters '?' and '~' are described in 5.2.1. For level 1 these characters may occur only at the end of the date string and apply to the entire date. For level 2 they may be used to qualify part of the date as follows:
Examples
however for level 1, only the right-most one or two digits may be replaced, for the following cases:
As noted in 5.2.2, the character 'u' may be used in place of a digit to indicate that the value of that digit is unspecified; It may be substituted for each of multiple digits. For level 1 it may be used only for one or more right-most characters. For level 2 it may be used for any character in the string.
Examples
Square brackets wrap a single-choice list. A list is represented using commas and double-dots where a double-dot indicates all the values between the two values it separates, inclusive. Double-dot at the beginning or end of the list means "on or before" or "on or after" respectively; see the second, third, and fourth example below. Different elements of a list may have different precisions, as in the fifth example.
Examples
Curly braces may be used to wrap an inclusive list (all members included). For consecutive dates, this means the discrete set and not an interval. Thus {1960,1961,1962,1963} does not mean "the (continuous) interval 1960 through 1963". {1960,1961,1962,1963} might be used to indicate the years of publication of a book - it was published in each of 1960, 1961, 1962, and 1963. Different elements of a list may have different precisions, as in the second example.
Examples
In a four-digit date string, 'x' may replace the last digit, or 'xx' the last two digits.
Examples
'196x' and '19xx ' have decade precision and century precision respectively.
Note the difference in semantics between 'x' and 'u'. '196x' has decade precision while '196u' has year precision. Both represent an unspecified year during the 1960s, but for 196x the year is not supplied because it is known only with decade precision. In contrast, for 196u the year is not supplied for reasons that are not specified but there is some expectation (though no guarantee) that the year may be supplied later; for 196x there is no such expectation.
The Level 2 Extended Interval feature extends Level 1 by allowing portions of a date to be designated as approximate, uncertain, or unspecified.
Examples
5.3.7 Year Exceeding Four Digits - Exponential Form
5.2.4 prescribes that 'y' may be used in Level 1 at the beginning of the date string when the date is a year exceeding four digits. In level 2 an alternative, exponential form, with optional precision, is allowed. The rules are as follows:
Examples
When season is immediately followed by '^' then a qualifier follows the ^.
Example
However, this specification does not define a vocabulary for seasonal qualifiers (the example above is hypothetical). Communities are encouraged to develop seasonal vocabularies. There is further discussion of this in Annex A.
When years, months,
and seasons are mixed together in a list to be sorted, this
specification does not address the sort order, that is, whether (for example) 2000 is before or
after 2000-01, 2000-10, 2000-12, 2000-21, etc. An application may adopt
whatever sorting algorithm fits its purpose, thus the value '2000', for
purposes of sorting, could be considered to be before 2000-01-01, or
after 2000-12-31, or before or after 2000-24, etc.
Seasons should sort as Spring < Summer < Autumn <
Winter (e.g. "2011-21" should sort before "2011-23"), but
applications may choose to sort "2011-21" and "2011-10" either
way, or consider them incomparable.
The following table summarized the features listed in section 5.
Level 0. ISO 8601 Features | |
Feature | Examples |
Date |
|
Date and Time |
|
Interval (start/end) |
|
Level 1 Extensions | |
Feature | Examples |
Uncertain/Approximate |
|
Unspecified |
|
L1 Extended Interval |
|
Year Exceeding Four Digits |
|
Season |
|
Level 2 Extensions | |
Feature | Examples |
Partial Uncertain/ Approximate |
|
Partial Unspecified |
|
One of a Set |
|
Multiple Dates |
|
Masked Precision |
|
L2 Extended Interval |
|
Year Requiring More than Four Digits - Exponential Form |
|
This BNF (Backus–Naur Form) description specifies the syntax for the dateTime string. It is presented in three levels.
The syntax used in this BNF description is:
dateTimeString = level0Expression
| level1Expression
| level2Expression
(* ************************** Level 0 *************************** *)
level0Expression =
date
| dateAndTime
| L0Interval
(* ** date ** *)
date = year | yearMonth | yearMonthDay
(* ** dateAndTime ** *)
dateAndTime = date "T" time
time = baseTime zoneOffset?
baseTime = hour ":" minute ":" second | "24:00:00"
(* Zone *)
zoneOffset = "Z"
| ("+" | "-")
(zoneOffsetHour (":" minute)?
| "14:00"
| "00:" oneThru59 )
zoneOffsetHour = oneThru13
(* ** level 0 interval ** *)
L0Interval = date "/" date
(* ** Definition for year ** *)
year = positiveYear | negativeYear | "0000"
positiveYear =
positiveDigit digit digit digit
| digit positiveDigit digit digit
| digit digit positiveDigit digit
| digit digit digit positiveDigit
negativeYear = "-" positiveYear
(* ** Other Auxiliary Assignments for Level 0 ** *)
year = digit digit digit digit
month = oneThru12
monthDay =
("01" |"03" |"05" |"07" |"08" |"10" |"12") "-" oneThru31
| ("04" |"06" |"09" |"11") "-" oneThru30
| "02-" oneThru29
yearMonth = year "-" month
yearMonthDay = year "-" monthDay
hour = zeroThru23
minute = zeroThru59
second = zeroThru59
oneThru12 = "01" | "02" | "03" | "04" | "05" | "06" | "07" | "08" | "09" | "10" | "11" | "12"
oneThru13 = oneThru12 | "13"
oneThru23 = oneThru13 | "14" | "15" | "16" | "17" | "18" | "19" | "20" | "21" | "22" | "23"
zeroThru23 = "00" | oneThru23
oneThru29 = oneThru23 | "24" | "25" | "26" | "27" | "28" | "29"
oneThru30 = oneThru29 | "30"
oneThru31 = oneThru30 | "31"
oneThru59 = oneThru31 | "32" | "33"| "34"| "35"| "36"| "37"| "38"| "39"| "40"| "41"| "42" | "43"
| "44"| "45"| "46" | "47"| "48"| "49" |"50"|"51"|"52"|"53"|"54"|"55"|"56"|"57"|"58"|"59"
zeroThru59 = "00" | oneThru59
digit = positiveDigit | "0"
positiveDigit = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
day = oneThru31
(* ************************** Level 1 *************************** *)
level1Expression = uncertainOrApproxDate
| unspecified
| L1Interval
| longYearSimple
| season
(* *** uncertainOrApproxDate *** *)
uncertainOrApproxDate = date UASymbol
(* *** unspecified *** *)
unspecified = yearWithOneOrTwoUnspecifedDigits
| monthUnspecified
| dayUnspecified
| dayAndMonthUnspecified
yearWithOneOrTwoUnspecifedDigits = digit digit (digit|'u') 'u'
monthUnspecified = year "-uu'
dayUnspecified = yearMonth "-uu'
dayAndMonthUnspecified = year "-uu-uu'
(* *** L1Interval *** *)
L1interval = L1Start "/" L1End
L1Start = ( dateOrSeason UASymbol?) | "unknown"
L1End = L1Start | "open"
(* *** Long Year - Simple Form *** *)
longYearSimple = "y" "-"? positiveDigit digit digit digit digit+
(* *** Season (unqualified) *** *)
season = year "-" seasonNumber
(* ** Auxiliary Assignments for Level 1 ** *)
UASymbol = ("?" | "~" | "?~")
seasonNumber = "21" | "22" | "23" | "24"
dateOrSeason = date | season
(* ************************** Level 2 *************************** *)
level2Expression = internalUncertainOrApproximate
| internalUnspecified
| choiceList
|inclusiveList
|maskedPrecision
| L2Interval
|longYearScientific
|seasonQualified
(* ** Internal Uncertain or Approximate** *)
internalUncertainOrApproximate = IUABase | "(" IUABase ")" UASymbol
IUABase = year UASymbol "-" month ("-(" day ")" UASymbol)?
| year UASymbol "-" monthDay UASymbol?
| year UASymbol? "-(" month ")" UASymbol ("-(" day ")" UASymbol)?
| year UASymbol? "-(" month ")" UASymbol ( "-" day )?
| yearMonth UASymbol "-(" day ")" UASymbol
| yearMonth UASymbol "-" day
| yearMonth "-(" day ")" UASymbol
| year "-(" monthDay ")" UASymbol
| season UASymbol
(* ** Internal Unspecified** *)
internalUnspecified =
yearWithU
| yearMonthWithU
| yearMonthDayWithU
yearWithU =
"u" digitOrU digitOrU digitOrU
| digitOrU "u" digitOrU digitOrU
| digitOrU digitOrU "u" digitOrU
| digitOrU digitOrU digitOrU "u"
yearMonthWithU =
(year | yearWithU) "-" monthWithU
| yearWithU "-" month
yearMonthDayWithU =
(yearWithU | year) "-" monthDayWithU
| yearWithU "-" monthDay
monthDayWithU=
(month | monthWithU) "-" dayWithU
| monthWithU "-" day
monthWithU = oneThru12 | "0u" | "1u" | ("u" digitOrU)
dayWithU =
oneThru31
| "u" dugitOrU
| oneThru3 "u"
digitOrU = positiveDigitOrU | "0"
positiveDigitOrU = positiveDigit | "u"
oneThru3 = "1" | "2" | "3"
(* ** Inclusive list and choice list** *)
choiceList = "[" listContent "]"
inclusiveList = "{" listContent "}"
listContent = earlier ("," listElement)*
| (earlier ",")? (listElement ",")* later
| listElement ("," listElement)+
| consecutives
listElement = date
| dateWithInternalUncertainty
| uncertainOrApproxDate
| unspecified
| consecutives
earlier = ".." date
later = date ".."
consecutives = yearMonthDay ".." yearMonthDay
| yearMonth ".." yearMonth
| year ".." year
(* ** Masked precision ** *)
maskedPrecision = digit digit ((digit "x") | "xx" )
(* ** L2Interval ** *)
L2Interval = dateOrSeason "/" dateWithInternalUncertainty
|dateWithInternalUncertainty "/"dateOrSeason
|dateWithInternalUncertainty "/" dateWithInternalUncertainty
(* ** Long Year - Scientific Form ** *)
longYearScientific = "y" "-"? positiveInteger "e" positiveInteger ("p" positiveInteger)?
positiveInteger = positiveDigit digit*
(* ** SeasonQualified ** *)
seasonQualified = season "^" seasonQualifier
seasonQualifier = qualifyingString
(* ** Auxiliary Assignments for Level 2 ** *)
dateWithInternalUncertainty =
internalUncertainOrApproximate
| internalUnspecified
qualifyingString = Any sequence of characters that does not include whitespace.
This specification has been developed as a result of the work of many individuals, including:
Gerry Ashton, unaffiliated engineer
Syd Bauman, Brown University
Karin Bredenberg, National Archives of Sweden
Bruce D'Arcus, Miami University
Ray Denenberg, Library of Congress
Larry E. Dixson, Library of Congress
Rebecca Guenther, Library of Congress
John Hostage, Harvard Law School
Andrew Houghton, OCLC
Kathryn Lybarger, University of Kentucky
Bert Lyons, Library of Congress
Andy Mabbett
Sally Hart McCallum, Library of Congress
Betsy McKelvey, Boston College
Neil McNaughton, Oil Information Technology Journal
Tracy Neckar Meehleib, Library of Congress
Clay Redding, Library of Congress
Dave Reser, Library of Congress
Saašha Metsärantala, Umeå University, Sweden
C. M. Sperberg-McQueen, Black Mesa Technologies
Jakob Voss, Gemeinsamer Bibliotheksverbund
Edward C. Zimmermann, Basis Systeme netzwerk
Some of the features discussed during the development of this draft specification were not sufficiently well-developed to include. These are sumarized briefly here so that they will not be forgotten and so that they may be considered in a future version.
ReliabilityThe character '?' means "uncertain". Some developers are satisfied to simply assert that a value is "uncertain" while others want to attach a level of reliability. One suggestion is to adopt a simple list of qualifiers, for example .....
a) Known to be correct (observed, documented etc.)
b) Likely correct ( probability > 50%)
c) Possibly correct (Might be but not likely)
d) Likely incorrect (The date is expected to be wrong)
e) Certainty unknown
...... and to append the '?' with one of these letters, a, b, c, d, e.
The default (whenever '?' is not followed by one of these letters) would be "unstated reliability ".
This proposal may suffer from oversimplification and lack of extensibility; for example, someone may want to represent "almost certaintly correct (probability near but not 100%)". On the other hand, it may meet the majority of needs, and it does have the advantage of extreme simplicity.
There are two broad approches. One is to declare this model to be explicitly non-extensible and define a closed controlled vocabulary, which may be as simple as the one suggested above, or it may be richer. The other would be a model based on an extensible vocabulary, either centralized (i.e. a registry), or decentralized with reliability levels represented by URIs.
PrecisionSomewhat analogous to "reliability" (above), the character '~' indicates "approximate". Some developers are satisfied to simply assert that a value is "approximate" while others want to attach a level of precision. This could perhaps be done in a manner similar to the suggestion for "reliability".
Volatile/dynamic/contextual datesRepresenting dates such as "today", "now", "yesterday", "past two weeks", "last month", "next year". etc...
Season QualifierNo seasonal qualifiers have yet been developed. 21, 22, 23, 24 are used to mean Spring, Summer, Autumn, Winter, respectively, in place of month, for example, '2001-21' for Spring, 2001. When the season is immediately followed by '^' then a qualifier follows the ^. For example, in the expression '2001-21^xxx, "xxx" is the qualifier. But no such qualifiers have been developed.
A qualifier might indicate hemisphere - north or south. There are also competing semantics for seasonal names: Meteorological, Astronomical, Cultural, Historical... For example, on February 1 it is Spring in Ireland but Winter in England (where March 1 traditionally marks the start of Spring). Universities have varying semantics: At the University of California, for example, Spring starts on March 28. Some campuses on the semester system use Fall and Spring to denote the two semesters but others use Winter and Summer (common in Germany).
There is also the possibility of inserting a geographic qualifier. And there is discussion about interpreting 21, 22, 23, 24 as quarter rather than season, and also distinguishing calendar from fiscal quarter.
Alternative definitions of year, month, day.e.g.