3.3.3 Date Tokens
-
date-or-time = (date-value 1*WSC time-value) / date-value / time-value date-value = left-date-value date-separator middle-date-value [date-separator right-date-value] left-date-value = decimal-literal / month-name middle-date-value = decimal-literal / month-name right-date-value = decimal-literal / month-name date-separator = 1*WSC / (*WSC ("/" / "-" / ",") *WSC) month-name = English-month-name / English-month-abbreviation English-month-name = "january" / "february" / "march" / "april" / "may" / "june" / "july" / "august" / "september" / "october" / "november" / "december" English-month-abbreviation = "jan" / "feb" / "mar" / "apr" / "jun" / "jul" / "aug" / "sep" / "oct" / "nov" / "dec" time-value = (hour-value ampm) / (hour-value time-separator minute-value [time-separator second-value] [ampm]) hour-value = decimal-literal minute-value = decimal-literal second-value = decimal-literal time-separator = *WSC (":" / ".") *WSC ampm = *WSC ("am" / "pm" / "a" / "p")
Static Semantics
A <DATE> token (section 3.3) has an associated data value (section 2.1) of value type (section 2.1) and declared type (section 2.2) Date.
The numeric data value of a <DATE> token is the sum of its specified date and its specified time.
If a <date-or-time> does not include a <time-value> its specified time is determined as if a <time-value> consisting of the characters "00:00:00" was present.
If a <date-or-time> does not include a <date-value> its specified date is determined as if a <date-value> consisting of the characters "1899/12/30" was present.
At most one of <left-date-value>, <middle-date-value>, and <right-date-value> can be a <month-name>.
Given that L is the data value of <left-date-value>, M is the data value of <middle-date-value>, and R is the data value of <right-date-value> if it is present. L, M, and R are interpreted as a calendar date as follows:
Let
Let
Let CY be an implementation-defined default year.
Let
If L and M are numbers and R is not present:
If LegalMonth(L) and LegalDay(L,M,CY) then L is the month, M is the day, and the year is CY
Else if LegalMonth(M) and LegalDay(M,L,CY) then M is the month, L is the day, and the year is CY
Else if LegalMonth(L) then L is the month, the day is 1, and the year is M
Else if LegalMonth(M) then M is the month, the day is 1, and the year is L
Otherwise, the <date-value> is not valid.
If L, M, and R are numbers:
If LegalMonth(L) and LegalDay(L,M,Year(R)) then L is the month, M is the day, and Year(R) is the year
Else if LegalMonth(M) and LegalDay(M,R,Year(L)) then M is the month, R is the day, and Year(L) is the year
Else if LegalMonth(M) and LegalDay(M,L,Year(R)) then M is the month, L is the day, and Year(R) is the year
Otherwise, the <date-value> is not valid.
If either L or M is not a number and R is not present:
Let N be the value of whichever of L or M is a number.
Let M be the value in the range 1 to 12 corresponding to the month name or abbreviation that is the value of whichever of L or M is not a number.
If LegalDay(M,N,CY) then M is the month, N is the day, and the year is CY
Otherwise, M is the month, 1 is the day, and the year is Year(N).
Otherwise, R is present and one of L, M, and R is not a number:
Let M be the value in the range 1 to 12 corresponding to the month name or abbreviation that is the value of whichever of L, M, or R is not a number.
Let N1 and N1 be the numeric values of which every of L, M, or R are numbers.
If LegalDay(M,N1,Year(N2) then M is the month, N1 is the day, and Year(N2) is the year
If LegalDay(M,N2,Year(N1) then M is the month, N2 is the day, and Year(N1) is the year
Otherwise, the <date-value> is not valid.
A <decimal-literal> that is an element of an <hour-value> MUST have an integer value in the inclusive range of 0 to 23.
A <decimal-literal> that is an element of an <minute-value> MUST have an integer value in the inclusive range of 0 to 59.
A <decimal-literal> that is an element of an <second-value> MUST have an integer value in the inclusive range of 0 to 59
If <time-value> includes an <ampm> element that consists of "pm" or "p" and the <hour-value> has an integer value in the inclusive range of 0 to 11 then the <hour-value> is used as if its integer value was 12 greater than its actual integer value.
A <ampm> element has no significance if the <hour-value> is greater than 12.
If <time-value> includes an <ampm> element that consists of "am" or "a" and the <hour-value> is the integer value 12, then the <hour-value> is used as if its integer value was 0.
If a <time-value> does not include a <minute-value> it is as if there was a <minute-value> whose integer value was 0.
If a <time-value> does not include a <second-value> it is as if there was a <second-value> whose integer value was 0.
Let h be the integer value of the <hour-value> element of a <time-value>, let m be the integer value of the <minute-value> element of that <time-value>, and let s be the integer value of the <second-value> of that <time-value>. The specified time of the <time-value> is defined by the formula (3600h+60m+s)/86400.