зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1265136 - Modify Date.parse's handling of two digit years to improve cross-compatibility; r=Waldo
--HG-- extra : rebase_source : 06add939e56d61394e05903c2e43049b1f831e00
This commit is contained in:
Родитель
e343bcae34
Коммит
7f8892b27f
|
@ -1104,55 +1104,49 @@ ParseDate(const CharT* s, size_t length, ClippedTime* result)
|
|||
* Case 1. The input string contains an English month name.
|
||||
* The form of the string can be month f l, or f month l, or
|
||||
* f l month which each evaluate to the same date.
|
||||
* If f and l are both greater than or equal to 70, or
|
||||
* both less than 70, the date is invalid.
|
||||
* The year is taken to be the greater of the values f, l.
|
||||
* If the year is greater than or equal to 70 and less than 100,
|
||||
* it is considered to be the number of years after 1900.
|
||||
* If f and l are both greater than or equal to 100 the date
|
||||
* is invalid.
|
||||
*
|
||||
* The year is taken to be either the greater of the values f, l or
|
||||
* whichever is set to zero. If the year is greater than or equal to
|
||||
* 50 and less than 100, it is considered to be the number of years
|
||||
* after 1900. If the year is less than 50 it is considered to be the
|
||||
* number of years after 2000, otherwise it is considered to be the
|
||||
* number of years after 0.
|
||||
*
|
||||
* Case 2. The input string is of the form "f/m/l" where f, m and l are
|
||||
* integers, e.g. 7/16/45.
|
||||
* Adjust the mon, mday and year values to achieve 100% MSIE
|
||||
* compatibility.
|
||||
* a. If 0 <= f < 70, f/m/l is interpreted as month/day/year.
|
||||
* i. If year < 100, it is the number of years after 1900
|
||||
* ii. If year >= 100, it is the number of years after 0.
|
||||
* b. If 70 <= f < 100
|
||||
* i. If m < 70, f/m/l is interpreted as
|
||||
* year/month/day where year is the number of years after
|
||||
* 1900.
|
||||
* ii. If m >= 70, the date is invalid.
|
||||
* c. If f >= 100
|
||||
* i. If m < 70, f/m/l is interpreted as
|
||||
* year/month/day where year is the number of years after 0.
|
||||
* ii. If m >= 70, the date is invalid.
|
||||
* integers, e.g. 7/16/45. mon, mday and year values are adjusted
|
||||
* to achieve Chrome compatibility.
|
||||
*
|
||||
* a. If 0 < f <= 12 and 0 < l <= 31, f/m/l is interpreted as
|
||||
* month/day/year.
|
||||
* i. If year < 50, it is the number of years after 2000
|
||||
* ii. If year >= 50, it is the number of years after 1900.
|
||||
* iii. If year >= 100, it is the number of years after 0.
|
||||
* b. If 31 < f and 0 < m <= 12 and 0 < l <= 31 f/m/l is
|
||||
* interpreted as year/month/day
|
||||
* i. If year < 50, it is the number of years after 2000
|
||||
* ii. If year >= 50, it is the number of years after 1900.
|
||||
* iii. If year >= 100, it is the number of years after 0.
|
||||
*/
|
||||
if (seenMonthName) {
|
||||
if ((mday >= 70 && year >= 70) || (mday < 70 && year < 70))
|
||||
if (mday >= 100 && mon >= 100)
|
||||
return false;
|
||||
|
||||
if (mday > year) {
|
||||
if (year > 0 && (mday == 0 || mday > year)) {
|
||||
int temp = year;
|
||||
year = mday;
|
||||
mday = temp;
|
||||
}
|
||||
if (year >= 70 && year < 100) {
|
||||
year += 1900;
|
||||
}
|
||||
} else if (mon < 70) { /* (a) month/day/year */
|
||||
if (year < 100) {
|
||||
year += 1900;
|
||||
}
|
||||
} else if (mon < 100) { /* (b) year/month/day */
|
||||
if (mday < 70) {
|
||||
int temp = year;
|
||||
year = mon + 1900;
|
||||
mon = mday;
|
||||
mday = temp;
|
||||
} else {
|
||||
|
||||
if (mday <= 0 || mday > 31)
|
||||
return false;
|
||||
}
|
||||
} else { /* (c) year/month/day */
|
||||
if (mday < 70) {
|
||||
|
||||
} else if (0 < mon && mon <= 12 && 0 < mday && mday <= 31) {
|
||||
/* (a) month/day/year */
|
||||
} else {
|
||||
/* (b) year/month/day */
|
||||
if (mon > 31 && mday <= 12 && year <= 31) {
|
||||
int temp = year;
|
||||
year = mon;
|
||||
mon = mday;
|
||||
|
@ -1162,6 +1156,11 @@ ParseDate(const CharT* s, size_t length, ClippedTime* result)
|
|||
}
|
||||
}
|
||||
|
||||
if (year < 50)
|
||||
year += 2000;
|
||||
else if (year >= 50 && year < 100)
|
||||
year += 1900;
|
||||
|
||||
mon -= 1; /* convert month to 0-based */
|
||||
if (sec < 0)
|
||||
sec = 0;
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
* Contributor: Bob Clary
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 273292;
|
||||
var summary = '15.9.3.2 new Date(value)';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
var date1;
|
||||
var date2;
|
||||
var i;
|
||||
var validDateStrings = [
|
||||
"11/69/2004",
|
||||
"11/70/2004",
|
||||
"69/69/2004",
|
||||
"69/69/69",
|
||||
"69/69/1969",
|
||||
"70/69/70",
|
||||
"70/69/1970",
|
||||
"70/69/2004"
|
||||
];
|
||||
|
||||
var invalidDateStrings = [
|
||||
"70/70/70",
|
||||
"70/70/1970",
|
||||
"70/70/2004"
|
||||
];
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
expect = 0;
|
||||
|
||||
for (i = 0; i < validDateStrings.length; i++)
|
||||
{
|
||||
date1 = new Date(validDateStrings[i]);
|
||||
date2 = new Date(date1.toDateString());
|
||||
actual = date2 - date1;
|
||||
|
||||
reportCompare(expect, actual, inSection(i) + ' ' +
|
||||
validDateStrings[i]);
|
||||
}
|
||||
|
||||
expect = true;
|
||||
|
||||
var offset = validDateStrings.length;
|
||||
|
||||
for (i = 0; i < invalidDateStrings.length; i++)
|
||||
{
|
||||
date1 = new Date(invalidDateStrings[i]);
|
||||
actual = isNaN(date1);
|
||||
|
||||
reportCompare(expect, actual, inSection(i + offset) + ' ' +
|
||||
invalidDateStrings[i] + ' is invalid.');
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommonn.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
/*
|
||||
* For the sake of cross compatibility with other implementations we
|
||||
* implement date parsing heuristics which support single and double
|
||||
* digit years. See bug: 1265136
|
||||
*/
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
for (let year of Array(100).keys()) {
|
||||
for (let month of Array(12).keys()) {
|
||||
for (let day of Array(31).keys()) {
|
||||
let fullYear = year >= 50 ? year + 1900 : year + 2000;
|
||||
let fullDate = new Date(`${month + 1}/${day + 1}/${fullYear}`);
|
||||
|
||||
// mm/dd/yy
|
||||
let d1 = new Date(`${month + 1}/${day + 1}/${year}`);
|
||||
assertEq(d1.getTime(), fullDate.getTime())
|
||||
|
||||
// yy/mm/dd
|
||||
let d2 = new Date(`${year}/${month + 1}/${day + 1}`);
|
||||
if (year > 31) {
|
||||
assertEq(d2.getTime(), fullDate.getTime())
|
||||
} else if (year > 12) {
|
||||
assertEq(d2.getTime(), new Date(NaN).getTime())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertEq(new Date("99/1/99").getTime(), new Date(NaN).getTime());
|
||||
assertEq(new Date("13/13/13").getTime(), new Date(NaN).getTime());
|
||||
assertEq(new Date("0/10/0").getTime(), new Date(NaN).getTime());
|
||||
|
||||
// Written months.
|
||||
for (let year of Array(1000).keys()) {
|
||||
let fullDate = new Date(`5/1/${year}`);
|
||||
let d1 = new Date(`may ${year} 1`);
|
||||
let d2 = new Date(`may 1 ${year}`);
|
||||
|
||||
let d3 = new Date(`1 may ${year}`);
|
||||
let d4 = new Date(`${year} may 1`);
|
||||
|
||||
let d5 = new Date(`1 ${year} may`);
|
||||
let d6 = new Date(`${year} 1 may`);
|
||||
|
||||
assertEq(d1.getTime(), fullDate.getTime())
|
||||
assertEq(d2.getTime(), fullDate.getTime())
|
||||
assertEq(d3.getTime(), fullDate.getTime())
|
||||
assertEq(d4.getTime(), fullDate.getTime())
|
||||
assertEq(d5.getTime(), fullDate.getTime())
|
||||
assertEq(d6.getTime(), fullDate.getTime())
|
||||
}
|
||||
|
||||
assertEq(new Date("may 1999 1999").getTime(), new Date(NaN).getTime());
|
||||
assertEq(new Date("may 0 0").getTime(), new Date(NaN).getTime());
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
||||
print("Tests complete");
|
|
@ -1,130 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 301738;
|
||||
var summary = 'Date parse compatibilty with MSIE';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
/*
|
||||
Case 2. The input string is of the form "f/m/l" where f, m and l are
|
||||
integers, e.g. 7/16/45.
|
||||
Adjust the mon, mday and year values to achieve 100% MSIE
|
||||
compatibility.
|
||||
a. If 0 <= f < 70, f/m/l is interpreted as month/day/year.
|
||||
i. If year < 100, it is the number of years after 1900
|
||||
ii. If year >= 100, it is the number of years after 0.
|
||||
b. If 70 <= f < 100
|
||||
i. If m < 70, f/m/l is interpreted as
|
||||
year/month/day where year is the number of years after
|
||||
1900.
|
||||
ii. If m >= 70, the date is invalid.
|
||||
c. If f >= 100
|
||||
i. If m < 70, f/m/l is interpreted as
|
||||
year/month/day where year is the number of years after 0.
|
||||
ii. If m >= 70, the date is invalid.
|
||||
*/
|
||||
|
||||
var f;
|
||||
var m;
|
||||
var l;
|
||||
|
||||
function newDate(f, m, l)
|
||||
{
|
||||
return new Date(f + '/' + m + '/' + l);
|
||||
}
|
||||
|
||||
function newDesc(f, m, l)
|
||||
{
|
||||
return f + '/' + m + '/' + l;
|
||||
}
|
||||
|
||||
// 2.a.i
|
||||
f = 0;
|
||||
m = 0;
|
||||
l = 0;
|
||||
|
||||
expect = (new Date(l, f-1, m)).toDateString();
|
||||
actual = newDate(f, m, l).toDateString();
|
||||
reportCompare(expect, actual, newDesc(f, m, l));
|
||||
|
||||
f = 0;
|
||||
m = 0;
|
||||
l = 100;
|
||||
|
||||
expect = (new Date(l, f-1, m)).toDateString();
|
||||
actual = newDate(f, m, l).toDateString();
|
||||
reportCompare(expect, actual, newDesc(f, m, l));
|
||||
|
||||
// 2.a.ii
|
||||
f = 0;
|
||||
m = 24;
|
||||
l = 100;
|
||||
|
||||
expect = (new Date(l, f-1, m)).toDateString();
|
||||
actual = newDate(f, m, l).toDateString();
|
||||
reportCompare(expect, actual, newDesc(f, m, l));
|
||||
|
||||
f = 0;
|
||||
m = 24;
|
||||
l = 2100;
|
||||
|
||||
expect = (new Date(l, f-1, m)).toDateString();
|
||||
actual = newDate(f, m, l).toDateString();
|
||||
reportCompare(expect, actual, newDesc(f, m, l));
|
||||
|
||||
|
||||
// 2.b.i
|
||||
f = 70;
|
||||
m = 24;
|
||||
l = 100;
|
||||
|
||||
expect = (new Date(f, m-1, l)).toDateString();
|
||||
actual = newDate(f, m, l).toDateString();
|
||||
reportCompare(expect, actual, newDesc(f, m, l));
|
||||
|
||||
f = 99;
|
||||
m = 12;
|
||||
l = 1;
|
||||
|
||||
expect = (new Date(f, m-1, l)).toDateString();
|
||||
actual = newDate(f, m, l).toDateString();
|
||||
reportCompare(expect, actual, newDesc(f, m, l));
|
||||
|
||||
// 2.b.ii.
|
||||
|
||||
f = 99;
|
||||
m = 70;
|
||||
l = 1;
|
||||
|
||||
expect = true;
|
||||
actual = isNaN(newDate(f, m, l));
|
||||
reportCompare(expect, actual, newDesc(f, m, l) + ' is an invalid date');
|
||||
|
||||
// 2.c.i
|
||||
|
||||
f = 100;
|
||||
m = 12;
|
||||
l = 1;
|
||||
|
||||
expect = (new Date(f, m-1, l)).toDateString();
|
||||
actual = newDate(f, m, l).toDateString();
|
||||
reportCompare(expect, actual, newDesc(f, m, l));
|
||||
|
||||
// 2.c.ii
|
||||
|
||||
f = 100;
|
||||
m = 70;
|
||||
l = 1;
|
||||
|
||||
expect = true;
|
||||
actual = isNaN(newDate(f, m, l));
|
||||
reportCompare(expect, actual, newDesc(f, m, l) + ' is an invalid date');
|
||||
|
||||
|
|
@ -7,8 +7,8 @@
|
|||
<window title="datepicker" width="500" height="600"
|
||||
onload="setTimeout(testtag_datepickers, 0);"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<hbox onpopupshown="testtag_datepicker_UI_popup()"
|
||||
onpopuphidden="testtag_finish()">
|
||||
|
@ -126,11 +126,6 @@ function testtag_datepicker(dp, type, testid)
|
|||
setDateField("date", 0, true, 2002, 10, 15);
|
||||
setDateField("date", 32, true, 2002, 10, 15);
|
||||
|
||||
// check that dates overflow properly
|
||||
setDateField("value", "2002-2-40", false, 2002, 2, 12);
|
||||
setDateField("value", "2003-03-32", false, 2003, 3, 1);
|
||||
setDateField("value", "2003-12-32", false, 2004, 0, 1);
|
||||
|
||||
// check leap year handling
|
||||
setDateField("value", "1600-2-29", false, 1600, 1, 29);
|
||||
setDateField("value", "2000-2-29", false, 2000, 1, 29);
|
||||
|
|
Загрузка…
Ссылка в новой задаче