Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct behaviour for date.setHours(-1)?

I have the following code:

var date = new Date(2010,09,09); //09.10.2010 00:00
date.setHours(-1); //sets the date to 08.10.2010 23:00

Calling date.setHours(-1); sets the date to 23:00 at the previous day (at least for Opera and Chrome).

Is this legal?

like image 524
tstenner Avatar asked Nov 23 '25 16:11

tstenner


2 Answers

Not only is it legal, is it required.

The behaviour is officially defined in the ECMAScript specification, section 15.9.5.34:

Date.prototype.setHours (hour [, min [, sec [, ms ] ] ] )

If min is not specified, this behaves as if min were specified with the value getMinutes().

If sec is not specified, this behaves as if sec were specified with the value getSeconds().

If ms is not specified, this behaves as if ms were specified with the value getMilliseconds().

  1. Let t be the result of LocalTime(this time value).
  2. Let h be ToNumber(hour).
  3. If min is not specified, then let m be MinFromTime(t); otherwise, let m be ToNumber(min).
  4. If sec is not specified, then let s be SecFromTime(t); otherwise, let s be ToNumber(sec).
  5. If ms is not specified, then let milli be msFromTime(t); otherwise, let milli be ToNumber(ms).
  6. Let date be MakeDate(Day(t), MakeTime(h, m, s, milli)).
  7. Let u be TimeClip(UTC(date)).
  8. Set the [[PrimitiveValue]] internal property of this Date object to u.
  9. Return u

And the specification for MakeTime, used in step 6, ultimately calculates a millisecond offset by multiplying the various parts together. There are no preconditions for bounds on the arguments (other than that they are finite), so a negative number of hours is legal, and will result in a negative result.

Thus the overall result, that is midnight + (-1 hours), does need to be 23:00 on the previous day to conform with the spec.

like image 199
Andrzej Doyle Avatar answered Nov 25 '25 06:11

Andrzej Doyle


Yes, this is effectively what the specification dictates, so it would be an "illegal" implementation if it didn't.

The actual computation happens in MakeDate. The date is converted into milliseconds, as is the -1 hours. These are then added. Adding a negative number does subtraction, so you get an earlier date.

If day is not finite or time is not finite, return NaN.

Return day × msPerDay + time.

like image 21
pimvdb Avatar answered Nov 25 '25 05:11

pimvdb