Fix TimeWithinDay(t) abstract operation (#3974)

Fixes #3973.

TimeWithinDay(t) = t modulo msPerDay, where msPerDay = 86400000.
The sign of the modulo operation result should be same as the right side
per definition, conseqently TimeWithinDay(t) >= 0.

References:
- https://www.ecma-international.org/ecma-262/11.0/#sec-mathematical-operations
- https://www.ecma-international.org/ecma-262/11.0/#sec-overview-of-date-objects-and-definitions-of-abstract-operations

JerryScript-DCO-1.0-Signed-off-by: Csaba Osztrogonác oszi@inf.u-szeged.hu
This commit is contained in:
Csaba Osztrogonác 2020-07-06 08:12:07 +02:00 committed by GitHub
parent 392ee71712
commit 5f951bb4f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 1 deletions

View File

@ -72,7 +72,13 @@ ecma_date_time_within_day (ecma_number_t time) /**< time value */
{ {
JERRY_ASSERT (!ecma_number_is_nan (time)); JERRY_ASSERT (!ecma_number_is_nan (time));
return (ecma_number_t) fmod (time, ECMA_DATE_MS_PER_DAY); ecma_number_t modulo = fmod (time, ECMA_DATE_MS_PER_DAY);
if (modulo < 0)
{
modulo += ECMA_DATE_MS_PER_DAY;
}
return modulo;
} /* ecma_date_time_within_day */ } /* ecma_date_time_within_day */
/** /**

View File

@ -207,6 +207,23 @@ d.setTime(0);
assert (d.setUTCFullYear(1970) == 0); assert (d.setUTCFullYear(1970) == 0);
assert (d.getUTCFullYear() == 1970); assert (d.getUTCFullYear() == 1970);
/* ECMA262 v11 20.4.1.2 Day Number and Time within Day
msPerDay = 86400000
TimeWithinDay(t) = t modulo msPerDay
ECMA262 v11 5.2.5 Mathematical Operations
The notation x modulo y (y must be finite and nonzero) computes a value k of the same sign as y (or zero).
Consequently TimeWithinDay(t) >= 0. It can be tested properly with dates close to 1970.
*/
d = new Date("1969-12-01T01:00:00.000Z");
d.setFullYear(1968);
assert (d.toISOString() == "1968-12-01T01:00:00.000Z");
d = new Date("1970-01-31T01:00:00.000Z");
d.setFullYear(1971);
assert (d.toISOString() == "1971-01-31T01:00:00.000Z");
/* Without argument */ /* Without argument */
d = new Date(); d = new Date();
assert (isNaN (d.setTime())); assert (isNaN (d.setTime()));