From e9664b78cddbe574fd3a41c068670071b570b489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csaba=20Osztrogon=C3=A1c?= Date: Tue, 1 Oct 2019 15:08:16 +0200 Subject: [PATCH] Make Date.parse accept extended years format too (#3177) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ES5.1 15.9.4.2 specifies that Date.parse (string) has to accept at least Date Time String Format: YYYY-MM-DDTHH:mm:ss.sssZ. But the spec allows implementation-specific fallbacks. Additionally ES5.1 15.9.1.15.1 specifies Extended years format, but isn't explicitly required to be accepted by Date.parse. But ES6 already clarified that Date.parse has to accept extended years format too. JerryScript-DCO-1.0-Signed-off-by: Csaba Osztrogonác oszi@inf.u-szeged.hu --- .../ecma/builtin-objects/ecma-builtin-date.c | 23 +++++++++++++--- tests/jerry/date-parse.js | 26 ++++++++++++++++++- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-date.c b/jerry-core/ecma/builtin-objects/ecma-builtin-date.c index 4094ad66c..f7cc996c2 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date.c @@ -199,10 +199,27 @@ ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */ const lit_utf8_byte_t *date_str_end_p = date_start_p + date_start_size; /* 1. read year */ - ecma_number_t year = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 4); - if (!ecma_number_is_nan (year) - && year >= 0) + uint32_t year_digits = 4; + bool year_sign = false; /* false: positive, true: negative */ + if (*date_str_curr_p == '-' || *date_str_curr_p == '+') + { + year_digits = 6; + if (*date_str_curr_p == '-') + { + year_sign = true; + } + /* eat up '-' or '+' */ + date_str_curr_p++; + } + + ecma_number_t year = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, year_digits); + if (year_sign) + { + year = -year; + } + + if (!ecma_number_is_nan (year)) { ecma_number_t month = ECMA_NUMBER_ONE; ecma_number_t day = ECMA_NUMBER_ONE; diff --git a/tests/jerry/date-parse.js b/tests/jerry/date-parse.js index 94b790541..361eda6fd 100644 --- a/tests/jerry/date-parse.js +++ b/tests/jerry/date-parse.js @@ -49,7 +49,14 @@ var wrongFormats = ["", "2015-01-01T00:60", "2015-01-01T-1:00", "2015-01-01T00:-1", - "2e+3"]; + "2e+3", + "+2015-01-01", + "-2015-01-01", + "+02015-01-01", + "-02015-01-01", + "002015-01-01", + "+0002015-01-01", + "-0002015-01-01"]; for (i in wrongFormats) { var d = Date.parse(wrongFormats[i]); @@ -96,3 +103,20 @@ assert (d == 1420081200000); d = Date.parse("2015-07-03T14:35:43.123+01:30"); assert (d == 1435928743123); + +assert (Date.parse("-271821-04-20T00:00:00.000Z") == -8640000000000000) +assert (Date.parse("-000001-12-31T23:59:59.999Z") == -62167219200001) +assert (Date.parse("0000-01-01T00:00:00.000Z") == -62167219200000) +assert (Date.parse("0009-12-31T23:59:59.999Z") == -61851600000001) +assert (Date.parse("0010-01-01T00:00:00.000Z") == -61851600000000) +assert (Date.parse("0099-12-31T23:59:59.999Z") == -59011459200001) +assert (Date.parse("0100-01-01T00:00:00.000Z") == -59011459200000) +assert (Date.parse("0999-12-31T23:59:59.999Z") == -30610224000001) +assert (Date.parse("1000-01-01T00:00:00.000Z") == -30610224000000) +assert (Date.parse("1969-12-31T23:59:59.999Z") == -1) +assert (Date.parse("1970-01-01T00:00:00.000Z") == 0) +assert (Date.parse("1970-01-01T00:00:00.001Z") == 1) +assert (Date.parse("9999-12-31T23:59:59.999Z") == 253402300799999) +assert (Date.parse("+010000-01-01T00:00:00.000Z") == 253402300800000) +assert (Date.parse("+275760-09-13T00:00:00.000Z") == 8640000000000000) +assert (Date.parse("+275760-09-13T00:00:00.001Z") == 8640000000000001)