3.3.3 Date Tokens
DATE = "#" *WSC [dateortime *WSC] "#"

dateortime = (datevalue 1*WSC timevalue) / datevalue / timevalue datevalue = leftdatevalue dateseparator middledatevalue [dateseparator rightdatevalue] leftdatevalue = decimalliteral / monthname middledatevalue = decimalliteral / monthname rightdatevalue = decimalliteral / monthname dateseparator = 1*WSC / (*WSC ("/" / "" / ",") *WSC) monthname = Englishmonthname / Englishmonthabbreviation Englishmonthname = "january" / "february" / "march" / "april" / "may" / "june" / "august" / "september" / "october" / "november" / "december" Englishmonthabbreviation = "jan" / "feb" / "mar" / "apr" / "jun" / "jul" / "aug" / "sep" / "oct" / "nov" / "dec" timevalue = (hourvalue ampm) / (hourvalue timeseparator minutevalue [timeseparator secondvalue] [ampm]) hourvalue = decimalliteral minutevalue = decimalliteral secondvalue = decimalliteral timeseparator = *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 <dateortime> does not include a <timevalue> its specified time is determined as if a <timevalue> consisting of the characters "00:00:00" was present.
If a <dateortime> does not include a <datevalue> its specified date is determined as if a <datevalue> consisting of the characters "1899/12/30" was present.
At most one of <leftdatevalue>, <middledatevalue>, and <rightdatevalue> may be a <monthname>.
Given that L is the data value of <leftdatevalue>, M is the data value of <middledatevalue>, and R is the data value of <rightdatevalue> if it is present. L, M, and R are interpreted as a calendar date as follows:
Let
Let
Let CY be an implementationdefined 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 <datevalue> 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 <datevalue> 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 <datevalue> is not valid.
A <decimalliteral> that is an element of an <hourvalue> must have an integer value in the inclusive range of 0 to 23.
A <decimalliteral> that is an element of an <minutevalue> must have an integer value in the inclusive range of 0 to 59.
A <decimalliteral> that is an element of an <secondvalue> must have an integer value in the inclusive range of 0 to 59
If <timevalue> includes an <ampm> element that consists of "pm" or "p" and the <hourvalue> has an integer value in the inclusive range of 0 to 11 then the <hourvalue> is used as if its integer value was 12 greater than its actual integer value.
A <ampm> element has no significance if the <hourvalue> is greater than 12.
If <timevalue> includes an <ampm> element that consists of "am" or "a" and the <hourvalue> is the integer value 12, then the <hourvalue> is used as if its integer value was 0.
If a <timevalue> does not include a <minutevalue> it is as if there was a <minutevalue> whose integer value was 0.
If a <timevalue> does not include a <secondvalue> it is as if there was a <secondvalue> whose integer value was 0.
Let h be the integer value of the <hourvalue> element of a <timevalue>, let m be the integer value of the <minutevalue> element of that <timevalue>, and let s be the integer value of the <secondvalue> of that <timevalue>. The specified time of the <timevalue> is defined by the formula (3600h+60m+s)/86400.