505
votes

What is the simplest way to obtain an instance of new Date() but set the time at midnight?

9

9 Answers

1022
votes

The setHours method can take optional minutes, seconds and ms arguments, for example:

var d = new Date();
d.setHours(0,0,0,0);

That will set the time to 00:00:00.000 of your current timezone, if you want to work in UTC time, you can use the setUTCHours method.

268
votes

Just wanted to clarify that the snippet from accepted answer gives the nearest midnight in the past:

var d = new Date();
d.setHours(0,0,0,0); // last midnight

If you want to get the nearest midnight in future, use the following code:

var d = new Date();
d.setHours(24,0,0,0); // next midnight
86
votes

A one-liner for object configs:

new Date(new Date().setHours(0,0,0,0));

When creating an element:

dateFieldConfig = {
      name: "mydate",
      value: new Date(new Date().setHours(0, 0, 0, 0)),
}
24
votes

Just going to add this here because I landed on this page looking for how to do this in moment.js and others may do too.

[Rationale: the word "moment" already appears elsewhere on this page so search engines direct here, and moment.js is widespread enough to warrant to being covered going on how often it is mentioned in other date-related SO questions]

So, in version 2.0.0 and above:

date.startOf('day');

For earlier versions:

date.sod();

Docs:

http://momentjs.com/docs/#/manipulating/start-of/

13
votes

You can probably use

new Date().setUTCHours(0,0,0,0)

if you need the value only once.

4
votes

Adding usefulness to @Dan's example, I had the need to find the next midday or midnight.

var d = new Date();
if(d.getHours() < 12) {
   d.setHours(12,0,0,0); // next midnight/midday is midday
} else {
   d.setHours(24,0,0,0); // next midnight/midday is midnight
}

This allowed me to set a frequency cap for an event, only allowing it to happen once in the morning and once in the afternoon for any visitor to my site. The date captured was used to set the expiration of the cookie.

4
votes

If calculating with dates summertime will cause often 1 uur more or one hour less than midnight (CEST). This causes 1 day difference when dates return. So the dates have to round to the nearest midnight. So the code will be (ths to jamisOn):

    var d = new Date();
    if(d.getHours() < 12) {
    d.setHours(0,0,0,0); // previous midnight day
    } else {
    d.setHours(24,0,0,0); // next midnight day
    }
4
votes

I have made a couple prototypes to handle this for me.

// This is a safety check to make sure the prototype is not already defined.
Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
        return this;
    }
};

Date.method('endOfDay', function () {
    var date = new Date(this);
    date.setHours(23, 59, 59, 999);
    return date;
});

Date.method('startOfDay', function () {
    var date = new Date(this);
    date.setHours(0, 0, 0, 0);
    return date;
});

if you dont want the saftey check, then you can just use

Date.prototype.startOfDay = function(){
  /*Method body here*/
};

Example usage:

var date = new Date($.now()); // $.now() requires jQuery
console.log('startOfDay: ' + date.startOfDay());
console.log('endOfDay: ' + date.endOfDay());
2
votes

In case you already have d3.js as a dependency in your project, or don't mind bringing it in, d3-time (d3.js library is modular as of v4.0.0) has got Intervals.

They might prove useful when setting dates to "default" values, e.g. midnight, 0.00 seconds, the first of the month, etc.

var d = new Date(); // Wed Aug 02 2017 15:01:07 GMT+0200 (CEST)
d3.timeHour(d) // Wed Aug 02 2017 00:00:00 GMT+0200 (CEST)
d3.timeMonth(d) // Tue Aug 01 2017 00:00:00 GMT+0200 (CEST)