Bugzilla – Bug 331
Define 'local date and time', 'date', 'time', and redefine 'global date and time' in a more factored-out way.
Last modified: 2009-11-23 17:17:05 CET
Index: source =================================================================== --- source (revision 2381) +++ source (revision 2382) @@ -1952,44 +1952,156 @@ Gregorian calendar. <a href="#refsGREGORIAN">[GREGORIAN]</a></p> + <p>The <dfn title="concept-datetime-digit">digits</dfn> in the date + and time syntaxes defined in this section must be characters in the + range U+0030 DIGIT ZERO to U+0039 DIGIT NINE, used to express + numbers in base ten.</p> - <h5>Global dates and times</h5> - <p>A <dfn title="concept-datetime">global date and time</dfn> - consists of a specific Gregorian date, consisting of a year, a - month, a day, an hour, a minute, a second, and a fraction of a - second, expressed with a time zone, consisting of a number of hours - and minutes. <a href="#refsGREGORIAN">[GREGORIAN]</a></p> + <h5>Dates</h5> - <!--XXX [GREGORIAN] should point to - <dd id="refsGREGORIAN">[GREGORIAN]</dd> - <dd>(Non-normative) <cite>Inter Gravissimas</cite>, A. Lilius, C. Clavius. Gregory XIII Papal Bulls, February 1582.</dd> - --> + <p>A <dfn title="concept-date">date</dfn> consists of a specific + Gregorian date with no timezone information, consisting of a year, a + month, and a day. <a href="#refsGREGORIAN">[GREGORIAN]</a></p> - <p>A string is a <dfn>valid global date and time string</dfn> if it - has the components in the following list, in the given order, and if - the components in the list follow the constraints given after the + <p>A string is a <dfn>valid date string</dfn> if it has the + components in the following list, in the given order, and if the + components in the list follow the constraints given after the list:</p> <ol> - <li>Four or more digits (representing the year)</li> + <li>Four or more <span title="concept-datetime-digit">digits</span> (representing the year)</li> <li>A U+002D HYPHEN-MINUS character (-).</li> - <li>Two digits (representing the month)</li> + <li>Two <span title="concept-datetime-digit">digits</span> (representing the month)</li> <li>A U+002D HYPHEN-MINUS character (-).</li> - <li>Two digits (representing the day)</li> + <li>Two <span title="concept-datetime-digit">digits</span> (representing the day)</li> - <li>A U+0054 LATIN CAPITAL LETTER T character.</li> + </ol> + + <p>The aforementioned constraints are:</p> + + <ul> + + <li>The month <var title="">m</var> must be in the range + 0 ≤ <var title="">m</var> ≤ 12.</li> + + <li>The day <var title="">d</var> must be in the range + 0 ≤ <var title="">d</var> ≤ <var + title="">D</var> where <var title="">D</var> is the <span + title="number of days in month month of year year">number of days + in the given month and year</span>.</li> + + </ul> + + <p>The rules to <dfn>parse a date string</dfn> are as follows. This + will either return a date, or nothing. If at any point the algorithm + says that it "fails", this means that it is aborted at that point + and returns nothing.</p> + + <ol> + + <li><p>Let <var title="">input</var> be the string being + parsed.</p></li> + + <li><p>Let <var title="">position</var> be a pointer into <var + title="">input</var>, initially pointing at the start of the + string.</p></li> + + <li><p><span>Parse a date component</span> to obtain <var + title="">year</var>, <var title="">month</var>, and <var + title="">day</var>. If this returns nothing, then fail.</p> + + <li><p>If <var title="">position</var> is <em>not</em> beyond the + end of <var title="">input</var>, then fail.</p></li> + + <li><p>Let <var title="">date</var> be the date with year <var + title="">year</var>, month <var title="">month</var>, and day <var + title="">day</var>.</p></li> + + <li><p>Return <var title="">date</var>.</p></li> + + </ol> + + <p>The rules to <dfn>parse a date component</dfn>, given an <var + title="">input</var> string and a <var title="">position</var>, are + as follows. This will either return a year, a month, and a day, or + nothing. If at any point the algorithm says that it "fails", this + means that it is aborted at that point and returns nothing.</p> + + <ol> + + <li><p><span>Collect a sequence of characters</span> in the range + U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected + sequence is not at least four characters long, then + fail. Otherwise, interpret the resulting sequence as a base-ten + integer. Let that number be the <var title="">year</var>.</p></li> + + <li><p>If <var title="">position</var> is beyond the end of <var + title="">input</var> or if the character at <var + title="">position</var> is not a U+002D HYPHEN-MINUS character, + then fail. Otherwise, move <var title="">position</var> forwards + one character.</p></li> + + <li><p><span>Collect a sequence of characters</span> in the range + U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected + sequence is not exactly two characters long, then fail. Otherwise, + interpret the resulting sequence as a base-ten integer. Let that + number be the <var title="">month</var>.</p></li> + + <li>If <var title="">month</var> is not a number in the range + 1 ≤ <var title="">month</var> ≤ 12, then + fail.</li> + + <li><p>Let <var title="">maxday</var> be the <span>number of days + in month <var title="">month</var> of year <var + title="">year</var></span>.</p></li> + + <li><p>If <var title="">position</var> is beyond the end of <var + title="">input</var> or if the character at <var + title="">position</var> is not a U+002D HYPHEN-MINUS character, + then fail. Otherwise, move <var title="">position</var> forwards + one character.</p></li> + + <li><p><span>Collect a sequence of characters</span> in the range + U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected + sequence is not exactly two characters long, then fail. Otherwise, + interpret the resulting sequence as a base-ten integer. Let that + number be the <var title="">day</var>.</p></li> + + <li><p>If <var title="">day</var> is not a number in the range + 1 ≤ <var title="">month</var> ≤ <var + title="">maxday</var>, then fail.</li> + + <li><p>Return <var title="">year</var>, <var title="">month</var>, + and <var title="">day</var>.</p></li> + + </ol> + + + + <h5>Times</h5> + + <p>A <dfn title="concept-time">time</dfn> consists of a specific + time with no timezone information, consisting of an hour, a minute, + a second, and a fraction of a second.</p> + + <p>A string is a <dfn>valid time string</dfn> if it has the + components in the following list, in the given order, and if the + components in the list follow the constraints given after the + list:</p> + + <ol> - <li>Two digits (representing the hour)</li> + <li>Two <span title="concept-datetime-digit">digits</span> (representing the hour)</li> <li>A U+003A COLON character (:).</li> - <li>Two digits (representing the minutes)</li> + <li>Two <span title="concept-datetime-digit">digits</span> (representing the minutes)</li> <li>Optionally: @@ -1997,7 +2109,7 @@ <li>A U+003A COLON character (:).</li> - <li>Two digits (representing the integer part of the seconds)</li> + <li>Two <span title="concept-datetime-digit">digits</span> (representing the integer part of the seconds)</li> <li>Optionally: @@ -2005,7 +2117,7 @@ <li>A 002E FULL STOP character (.)</li> - <li>One or more digits (representing the fractional part of the seconds)</li> + <li>One or more <span title="concept-datetime-digit">digits</span> (representing the fractional part of the seconds)</li> </ol> @@ -2015,6 +2127,233 @@ </li> + </ol> + + <p>The aforementioned constraints are:</p> + + <ul> + + <li>The hour <var title="">h</var> must be in the range + 0 ≤ <var title="">h</var> ≤ 23.</li> + + <li>The minute <var title="">m</var> must be in the range + 0 ≤ <var title="">m</var> ≤ 59.</li> + + <li>If present, the second <var title="">s</var> (consisting of the + integer part and its fractional part) must be in the range + 0 ≤ <var title="">s</var> < 60. (The + values 60 and 61 are not allowed: leap seconds cannot be + represented by datetime values.)</li> + + </ul> + + <p>The rules to <dfn>parse a time string</dfn> are as follows. This + will either return a time, or nothing. If at any point the algorithm + says that it "fails", this means that it is aborted at that point + and returns nothing.</p> + + <ol> + + <li><p>Let <var title="">input</var> be the string being + parsed.</p></li> + + <li><p>Let <var title="">position</var> be a pointer into <var + title="">input</var>, initially pointing at the start of the + string.</p></li> + + <li><p><span>Parse a time component</span> to obtain <var + title="">hour</var>, <var title="">minute</var>, and <var + title="">second</var>. If this returns nothing, then fail.</p> + + <li><p>If <var title="">position</var> is <em>not</em> beyond the + end of <var title="">input</var>, then fail.</p></li> + + <li><p>Let <var title="">time</var> be the time with hour <var + title="">hour</var>, minute <var title="">minute</var>, and second + <var title="">second</var>.</p></li> + + <li><p>Return <var title="">time</var>.</p></li> + + </ol> + + <p>The rules to <dfn>parse a time component</dfn>, given an <var + title="">input</var> string and a <var title="">position</var>, are + as follows. This will either return an hour, a minute, and a second, + or nothing. If at any point the algorithm says that it "fails", this + means that it is aborted at that point and returns nothing.</p> + + <ol> + + <li><p><span>Collect a sequence of characters</span> in the range + U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected + sequence is not exactly two characters long, then fail. Otherwise, + interpret the resulting sequence as a base-ten integer. Let that + number be the <var title="">hour</var>.</p></li> + + <li>If <var title="">hour</var> is not a number in the range + 0 ≤ <var title="">hour</var> ≤ 23, then + fail.</li> + + <li><p>If <var title="">position</var> is beyond the end of <var + title="">input</var> or if the character at <var + title="">position</var> is not a U+003A COLON character, then + fail. Otherwise, move <var title="">position</var> forwards one + character.</p></li> + + <li><p><span>Collect a sequence of characters</span> in the range + U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected + sequence is not exactly two characters long, then fail. Otherwise, + interpret the resulting sequence as a base-ten integer. Let that + number be the <var title="">minute</var>.</p></li> + + <li>If <var title="">minute</var> is not a number in the range + 0 ≤ <var title="">minute</var> ≤ 59, then + fail.</li> + + <li><p>Let <var title="">second</var> be a string with the value + "0".</p></li> + + <li> + + <p>If <var title="">position</var> is not beyond the end of + <var title="">input</var> and the character at <var + title="">position</var> is a U+003A COLON, then run these + substeps:</p> + + <ol> + + <li><p>Advance <var title="">position</var> to the next character + in <var title="">input</var>.</p></li> + + <li><p>If <var title="">position</var> is beyond the end of <var + title="">input</var>, or at the last character in <var + title="">input</var>, or if the next <em>two</em> characters in + <var title="">input</var> starting at <var + title="">position</var> are not two characters both in the range + U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then + fail.</p></li> + + <li><p><span>Collect a sequence of characters</span> that are + either characters in the range U+0030 DIGIT ZERO (0) to U+0039 + DIGIT NINE (9) or U+002E FULL STOP characters. If the collected + sequence has more than one U+002E FULL STOP characters, or if the + last character in the sequence is a U+002E FULL STOP character, + then fail. Otherwise, let the collected string be <var + title="">second</var> instead of its previous value.</p></li> + + </ol> + + </li> + + <li><p>Interpret <var title="">second</var> as a base-ten number + (possibly with a fractional part). Let <var title="">second</var> + be that number instead of the string version.</p></li> + + <li>If <var title="">second</var> is not a number in the range + 0 ≤ <var title="">second</var> < 60, then + fail.</li> + + <li><p>Return <var title="">hour</var>, <var title="">minute</var>, + and <var title="">second</var>.</p></li> + + </ol> + + + + <h5>Local dates and times</h5> + + <p>A <dfn title="concept-datetime-local">local date and time</dfn> + consists of a specific Gregorian date, consisting of a year, a + month, and a day, and a time, consisting of an hour, a minute, a + second, and a fraction of a second, but expressed without a time + zone. <a href="#refsGREGORIAN">[GREGORIAN]</a></p> + + <p>A string is a <dfn>valid local date and time string</dfn> if it + has the components in the following list, in the given order:</p> + + <ol> + + <li>A <span>valid date string</span>.</li> + + <li>A U+0054 LATIN CAPITAL LETTER T character.</li> + + <li>A <span>valid time string</span>.</li> + + </ol> + + <p>The rules to <dfn>parse a local date and time string</dfn> are as + follows. This will either return a date and time, or nothing. If at + any point the algorithm says that it "fails", this means that it is + aborted at that point and returns nothing.</p> + + <ol> + + <li><p>Let <var title="">input</var> be the string being + parsed.</p></li> + + <li><p>Let <var title="">position</var> be a pointer into <var + title="">input</var>, initially pointing at the start of the + string.</p></li> + + <li><p><span>Parse a date component</span> to obtain <var + title="">year</var>, <var title="">month</var>, and <var + title="">day</var>. If this returns nothing, then fail.</p> + + <li><p>If <var title="">position</var> is beyond the end of <var + title="">input</var> or if the character at <var + title="">position</var> is not a U+0054 LATIN CAPITAL LETTER T + character then fail. Otherwise, move <var title="">position</var> + forwards one character.</p></li> + + <li><p><span>Parse a time component</span> to obtain <var + title="">hour</var>, <var title="">minute</var>, and <var + title="">second</var>. If this returns nothing, then fail.</p> + + <li><p>If <var title="">position</var> is <em>not</em> beyond the + end of <var title="">input</var>, then fail.</p></li> + + <li><p>Let <var title="">date</var> be the date with year <var + title="">year</var>, month <var title="">month</var>, and day <var + title="">day</var>.</p></li> + + <li><p>Let <var title="">time</var> be the time with hour <var + title="">hour</var>, minute <var title="">minute</var>, and second + <var title="">second</var>.</p></li> + + <li><p>Return <var title="">date</var> and <var + title="">time</var>.</p></li> + + </ol> + + + + <h5>Global dates and times</h5> + + <p>A <dfn title="concept-datetime">global date and time</dfn> + consists of a specific Gregorian date, consisting of a year, a + month, and a day, and a time, consisting of an hour, a minute, a + second, and a fraction of a second, expressed with a time zone, + consisting of a number of hours and minutes. <a + href="#refsGREGORIAN">[GREGORIAN]</a></p> + + <!--XXX [GREGORIAN] should point to + <dd id="refsGREGORIAN">[GREGORIAN]</dd> + <dd>(Non-normative) <cite>Inter Gravissimas</cite>, A. Lilius, C. Clavius. Gregory XIII Papal Bulls, February 1582.</dd> + --> + + <p>A string is a <dfn>valid global date and time string</dfn> if it + has the components in the following list, in the given order, and if + the components in the list follow the constraints given after the + list:</p> + + <ol> + + <li>A <span>valid date string</span>.</li> + + <li>A U+0054 LATIN CAPITAL LETTER T character.</li> + + <li>A <span>valid time string</span>.</li> + <li>Either: <ul> @@ -2030,11 +2369,11 @@ HYPHEN-MINUS (-) character (the sign of the timezone offset)</li> - <li>Two digits (representing the hours component of the timezone offset)</li> + <li>Two <span title="concept-datetime-digit">digits</span> (representing the hours component of the timezone offset)</li> <li>A U+003A COLON character (:).</li> - <li>Two digits (representing the minutes component of the timezone offset)</li> + <li>Two <span title="concept-datetime-digit">digits</span> (representing the minutes component of the timezone offset)</li> </ol> @@ -2050,27 +2389,6 @@ <ul> - <li>The month <var title="">m</var> must be in the range - 0 ≤ <var title="">m</var> ≤ 12.</li> - - <li>The day <var title="">d</var> must be in the range - 0 ≤ <var title="">d</var> ≤ <var - title="">D</var> where <var title="">D</var> is the <span - title="number of days in month month of year year">number of days - in the given month and year</span>.</li> - - <li>The hour <var title="">h</var> must be in the range - 0 ≤ <var title="">h</var> ≤ 23.</li> - - <li>The minute <var title="">m</var> must be in the range - 0 ≤ <var title="">m</var> ≤ 59.</li> - - <li>If present, the second <var title="">s</var> (consisting of the - integer part and its fractional part) must be in the range - 0 ≤ <var title="">s</var> < 60. (The - values 60 and 61 are not allowed: leap seconds cannot be - represented by datetime values.)</li> - <li>If present, the time zone hour <var title="">h</var> must be in the range 0 ≤ <var title="">h</var> ≤ 23. (However, in practice, time @@ -2085,9 +2403,6 @@ </ul> - <p>The digits must be characters in the range U+0030 DIGIT ZERO to - U+0039 DIGIT NINE, used to express numbers in base ten.</p> - <div class="example"> <p>The following are some examples of dates written as <span @@ -2159,47 +2474,9 @@ title="">input</var>, initially pointing at the start of the string.</p></li> - <li><p><span>Collect a sequence of characters</span> in the range - U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected - sequence is not at least four characters long, then - fail. Otherwise, interpret the resulting sequence as a base-ten - integer. Let that number be the <var title="">year</var>.</p></li> - - <li><p>If <var title="">position</var> is beyond the end of <var - title="">input</var> or if the character at <var - title="">position</var> is not a U+002D HYPHEN-MINUS character, - then fail. Otherwise, move <var title="">position</var> forwards - one character.</p></li> - - <li><p><span>Collect a sequence of characters</span> in the range - U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected - sequence is not exactly two characters long, then fail. Otherwise, - interpret the resulting sequence as a base-ten integer. Let that - number be the <var title="">month</var>.</p></li> - - <li>If <var title="">month</var> is not a number in the range - 1 ≤ <var title="">month</var> ≤ 12, then - fail.</li> - - <li><p>Let <var title="">maxday</var> be the <span>number of days - in month <var title="">month</var> of year <var - title="">year</var></span>.</p></li> - - <li><p>If <var title="">position</var> is beyond the end of <var - title="">input</var> or if the character at <var - title="">position</var> is not a U+002D HYPHEN-MINUS character, - then fail. Otherwise, move <var title="">position</var> forwards - one character.</p></li> - - <li><p><span>Collect a sequence of characters</span> in the range - U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected - sequence is not exactly two characters long, then fail. Otherwise, - interpret the resulting sequence as a base-ten integer. Let that - number be the <var title="">day</var>.</p></li> - - <li><p>If <var title="">day</var> is not a number in the range - 1 ≤ <var title="">month</var> ≤ <var - title="">maxday</var>, then fail.</li> + <li><p><span>Parse a date component</span> to obtain <var + title="">year</var>, <var title="">month</var>, and <var + title="">day</var>. If this returns nothing, then fail.</p> <li><p>If <var title="">position</var> is beyond the end of <var title="">input</var> or if the character at <var @@ -2207,75 +2484,9 @@ character then fail. Otherwise, move <var title="">position</var> forwards one character.</p></li> - <li><p><span>Collect a sequence of characters</span> in the range - U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected - sequence is not exactly two characters long, then fail. Otherwise, - interpret the resulting sequence as a base-ten integer. Let that - number be the <var title="">hour</var>.</p></li> - - <li>If <var title="">hour</var> is not a number in the range - 0 ≤ <var title="">hour</var> ≤ 23, then - fail.</li> - - <li><p>If <var title="">position</var> is beyond the end of <var - title="">input</var> or if the character at <var - title="">position</var> is not a U+003A COLON character, then - fail. Otherwise, move <var title="">position</var> forwards one - character.</p></li> - - <li><p><span>Collect a sequence of characters</span> in the range - U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9). If the collected - sequence is not exactly two characters long, then fail. Otherwise, - interpret the resulting sequence as a base-ten integer. Let that - number be the <var title="">minute</var>.</p></li> - - <li>If <var title="">minute</var> is not a number in the range - 0 ≤ <var title="">minute</var> ≤ 59, then - fail.</li> - - <li><p>Let <var title="">second</var> be a string with the value - "0".</p></li> - - <li><p>If <var title="">position</var> is beyond the end of <var - title="">input</var>, then fail.</p></li> - - <li> - - <p>If the character at <var title="">position</var> is a U+003A - COLON, then run these substeps:</p> - - <ol> - - <li><p>Advance <var title="">position</var> to the next character - in <var title="">input</var>.</p></li> - - <li><p>If <var title="">position</var> is beyond the end of <var - title="">input</var>, or at the last character in <var - title="">input</var>, or if the next <em>two</em> characters in - <var title="">input</var> starting at <var - title="">position</var> are not two characters both in the range - U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then - fail.</p></li> - - <li><p><span>Collect a sequence of characters</span> that are - either characters in the range U+0030 DIGIT ZERO (0) to U+0039 - DIGIT NINE (9) or U+002E FULL STOP characters. If the collected - sequence has more than one U+002E FULL STOP characters, or if the - last character in the sequence is a U+002E FULL STOP character, - then fail. Otherwise, let the collected string be <var - title="">second</var> instead of its previous value.</p></li> - - </ol> - - </li> - - <li><p>Interpret <var title="">second</var> as a base-ten number - (possibly with a fractional part). Let <var title="">second</var> - be that number instead of the string version.</p></li> - - <li>If <var title="">second</var> is not a number in the range - 0 ≤ <var title="">second</var> < 60, then - fail.</li> + <li><p><span>Parse a time component</span> to obtain <var + title="">hour</var>, <var title="">minute</var>, and <var + title="">second</var>. If this returns nothing, then fail.</p> <li><p>If <var title="">position</var> is beyond the end of <var title="">input</var>, then fail.</p></li> @@ -2375,30 +2586,6 @@ </ol> - <h5>Local dates and times</h5> - - <p>A <dfn title="concept-datetime-local">local date and time</dfn> - consists of a specific Gregorian date with no timezone information, - consisting of a year, a month, a day, an hour, a minute, a second, - and a fraction of a second. <a - href="#refsGREGORIAN">[GREGORIAN]</a></p> - - <p class="XXX">... <dfn>valid local date and time string</dfn></p> - - <p class="XXX">... rules to <dfn>parse a local date and time - string</dfn></p> - - - <h5>Dates</h5> - - <p>A <dfn title="concept-date">date</dfn> consists of a specific - Gregorian date with no timezone information, consisting of a year, a - month, and a day. <a href="#refsGREGORIAN">[GREGORIAN]</a></p> - - <p class="XXX">... <dfn>valid date string</dfn></p> - - <p class="XXX">... rules to <dfn>parse a date string</dfn></p> - <h5>Months</h5> @@ -2426,17 +2613,6 @@ <p class="XXX">... rules to <dfn>parse a week string</dfn></p> - <h5>Times</h5> - - <p>A <dfn title="concept-time">time</dfn> consists of a specific - time with no timezone information, consisting of an hour, a minute, - a second, and a fraction of a second.</p> - - <p class="XXX">... <dfn>valid time string</dfn></p> - - <p class="XXX">... rules to <dfn>parse a time string</dfn></p> - - <h5>Vaguer moments in time</h5>