bug 802760: Document all ISO-8601 date parsing exceptions draft
authoreric skoglund <eric@pagefault.se>
Tue, 17 Oct 2017 13:13:58 +0200
changeset 682181 deb5fbb774743638b763fec4acc56162c2aefa81
parent 681384 ca068118abc506b1a1753b754fa8521fd4f3c57f
child 736333 ee3f72c786e489f3d906088acb89030e37d9af2d
push id85037
push userbmo:eric@pagefault.se
push dateWed, 18 Oct 2017 08:53:56 +0000
bugs802760
milestone58.0a1
bug 802760: Document all ISO-8601 date parsing exceptions Update the documentation for ParseISOStyleDate to reflect the current specification and the extensions we allow. MozReview-Commit-ID: 2Zlrrj45bOc
js/src/jsdate.cpp
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -774,37 +774,48 @@ static int
 DaysInMonth(int year, int month)
 {
     bool leap = IsLeapYear(year);
     int result = int(DayFromMonth(month, leap) - DayFromMonth(month - 1, leap));
     return result;
 }
 
 /*
- * Parse a string in one of the date-time formats given by the W3C
- * "NOTE-datetime" specification. These formats make up a restricted
- * profile of the ISO 8601 format. Quoted here:
+ * Parse a string according to the formats specified in section 20.3.1.16
+ * of the ECMAScript standard. These formats are based upon a simplification
+ * of the ISO 8601 Extended Format. As per the spec omitted month and day
+ * values are defaulted to '01', omitted HH:mm:ss values are defaulted to '00'
+ * and an omitted sss field is defaulted to '000'.
  *
- *   Any combination of the date formats with the time formats is
- *   allowed, and also either the date or the time can be missing.
+ * For cross compatibility we allow the following extensions.
+ *
+ * These are:
+ *
+ *   Standalone time part:
+ *     Any of the time formats below can be parsed without a date part.
+ *     E.g. "T19:00:00Z" will parse successfully. The date part will then
+ *     default to 1970-01-01.
  *
- *   The specification is silent on the meaning when fields are
- *   ommitted so the interpretations are a guess, but hopefully a
- *   reasonable one. We default the month to January, the day to the
- *   1st, and hours minutes and seconds all to 0. If the date is
- *   missing entirely then we assume 1970-01-01 so that the time can
- *   be aded to a date later. If the time is missing then we assume
- *   00:00 UTC.  If the time is present but the time zone field is
- *   missing then we use local time.
+ *   'T' from the time part may be replaced with a space character:
+ *     "1970-01-01 12:00:00Z" will parse successfully. Note that only a single
+ *     space is permitted and this is not permitted in the standalone
+ *     version above.
+ *
+ *   One or more decimal digits for milliseconds:
+ *     The specification requires exactly three decimal digits for
+ *     the fractional part but we allow for one or more digits.
  *
- * For the sake of cross compatibility with other implementations we
- * make a few exceptions to the standard: months, days, hours, minutes
- * and seconds may be either one or two digits long, and the 'T' from
- * the time part may be replaced with a space. Given that, a date time
- * like "1999-1-1 1:1:1" will parse successfully.
+ *   Time zone specifier without ':':
+ *     We allow the time zone to be specified without a ':' character.
+ *     E.g. "T19:00:00+0700" is equivalent to "T19:00:00+07:00".
+ *
+ *   One or two digits for months, days, hours, minutes and seconds:
+ *     The specification requires exactly two decimal digits for the fields
+ *     above. We allow for one or two decimal digits. I.e. "1970-1-1" is
+ *     equivalent to "1970-01-01".
  *
  * Date part:
  *
  *  Year:
  *     YYYY (eg 1997)
  *
  *  Year and month:
  *     YYYY-MM (eg 1997-07)
@@ -826,17 +837,17 @@ DaysInMonth(int year, int month)
  * where:
  *
  *   YYYY = four-digit year or six digit year as +YYYYYY or -YYYYYY
  *   MM   = one or two-digit month (01=January, etc.)
  *   DD   = one or two-digit day of month (01 through 31)
  *   hh   = one or two digits of hour (00 through 23) (am/pm NOT allowed)
  *   mm   = one or two digits of minute (00 through 59)
  *   ss   = one or two digits of second (00 through 59)
- *   s    = one or more digits representing a decimal fraction of a second
+ *   sss  = one or more digits representing a decimal fraction of a second
  *   TZD  = time zone designator (Z or +hh:mm or -hh:mm or missing for local)
  */
 template <typename CharT>
 static bool
 ParseISOStyleDate(const CharT* s, size_t length, ClippedTime* result)
 {
     size_t i = 0;
     int tzMul = 1;