# 3.3.3 Date Tokens

DATE = "#" *WSC [date-or-time *WSC] "#"

```
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" / "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 <timevalue> 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 <datevalue> consisting of the characters "1899/12/30" was present.

• At most one of <left-date-value>, <middle-date-value>, and <right-date-value> may 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.