Quelle est la meilleure façon d'initialiser une date JavaScript à minuit?

441

Quelle est la manière la plus simple d'obtenir une instance de new Date () mais de régler l'heure à minuit?

Sixty4Bit
la source

Réponses:

877

La setHoursméthode peut prendre en option minutes, secondset des msarguments, par exemple:

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

Cela définira l'heure 00:00:00.000de votre fuseau horaire actuel , si vous souhaitez travailler en heure UTC, vous pouvez utiliser la setUTCHoursméthode.

CMS
la source
42
Pour info, j'exécute cette méthode (d.setHours (0,0,0,0)) dans une fonction de réduction sur 270K lignes, et c'est plus de 20 secondes plus rapide que de faire d.setHours (0); d.setMinutes (0); d.setSeconds (0); Grande réponse @CMS!
jbnunn
32
Cela doit être fait sur deux lignes pour conserver d en tant qu'objet Date. J'ai récemment corrigé un bogue qui le faisait sur une seule ligne: var d = new Date (). SetHours (0, 0, 0, 0). Cependant, d était alors un nombre, pas une date puisque setHours renvoie un nombre.
Jason
9
Je viens de rencontrer cela (tard pour la fête que je connais), ayant également besoin d'une solution à une ligne renvoyant une date. Pour ceux qui cherchent ce, @ la réponse de Zon fonctionne parfaitement: new Date(new Date().setHours(0,0,0,0)).
SRack
227

Je voulais juste préciser que l'extrait de la réponse acceptée donne le minuit le plus proche dans le passé :

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

Si vous souhaitez obtenir le minuit le plus proche à l'avenir , utilisez le code suivant:

var d = new Date();
d.setHours(24,0,0,0); // next midnight
Dan
la source
6
Que se passe-t-il si la durée de la journée est de 25 heures (les horloges s'ajustent vers l'avant pour l'heure d'été)?
qntm
8
Ceci est un script côté client, minuit est minuit, malgré l'heure d'été. Également mention notable .. tous les endroits dans le monde n'utilisent pas l'heure d'été (heure d'été)
chris
2
@qntm: le changement d'heure d'été est toujours appliqué de 2h à 4h du matin, de sorte qu'il ne sera qu'une heure à minuit ce jour-là :). Mais oui, 3h du matin peut arriver deux fois dans la journée (facepalm)
Dan
@chris Non, je veux dire le deuxième extrait. "24 heures après minuit aujourd'hui" n'est pas toujours la même chose que "minuit demain". Dans ces cas, le deuxième extrait fonctionne-t-il?
qntm
3
@qntm: Date.setHours n'ajoute pas aveuglément 24 heures, c'est plus intelligent. Au lieu de cela, il renvoie un horodatage du moment, lorsque l'horloge affichera 24 la prochaine fois. Prise en compte du gain de temps. Essayez de jouer vous-même dans la console. Intéressant, setHours (25) renvoie l'horodatage des lendemains 1h
Dan
68

Une ligne pour les configurations d'objets:

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

Lors de la création d'un élément:

dateFieldConfig = {
      name: "mydate",
      value: new Date(new Date().setHours(0, 0, 0, 0)),
}
Zon
la source
6
Merci! je me demandais comment je pouvais le faire en une seule ligne parce que je définissais une propriété d'objet! Très bonne réponse.
Paulo Roberto Rosa
Merci Zon, cela m'a aidé à l'écrire sur une seule ligne.
HungrySoul
22

Je vais juste l'ajouter ici parce que j'ai atterri sur cette page en cherchant comment le faire dans moment.js et d'autres peuvent le faire aussi.

[Justification: le mot "moment" apparaît déjà ailleurs sur cette page, donc les moteurs de recherche dirigent ici, et moment.js est suffisamment répandu pour justifier d'être couvert à quelle fréquence il est mentionné dans d'autres questions SO liées à la date]

Donc, dans la version 2.0.0 et supérieure:

date.startOf('day');

Pour les versions antérieures:

date.sod();

Documents:

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

andyhasit
la source
pour récupérer un objet de date, utilisez cecimoment(DATE_OBJECT).startOf('day').toDate();
xinthose
2
oui, ajoutons une bibliothèque javascript 52kb pour faire quelque chose que vous pouvez faire en 2 lignes.
Bruce Lim
19
Et si vous utilisez déjà moment.js pour l'une des nombreuses bonnes raisons que vous pourriez ...? Que diriez-vous de lire la justification que j'ai donnée avant d'ajouter un commentaire sarcastique?
andyhasit
11

Vous pouvez probablement utiliser

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

si vous n'avez besoin de la valeur qu'une seule fois.

Stan
la source
1
Cela n'obtient pas une instance d'une date, comme l'OP requis.
cobberboy
C'est certainement la meilleure réponse, mais a besoin d'une petite modification pour renvoyer une instance d'une date. nouvelle date (nouvelle date (). setUTCHours (0, 0, 0, 0));
VitFL
4

Ajoutant de l'utilité à l'exemple de @ Dan, j'ai eu le besoin de trouver le prochain midi ou minuit.

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
}

Cela m'a permis de fixer une limite de fréquence pour un événement, ce qui ne pouvait se produire qu'une fois le matin et une fois l'après-midi pour tout visiteur de mon site. La date capturée a été utilisée pour définir l'expiration du cookie.

jamis0n
la source
4

Si le calcul avec des dates, l'heure d'été entraîne souvent 1 heure de plus ou une heure de moins que minuit (CEST). Cela entraîne une différence d'un jour lorsque les dates reviennent. Les dates doivent donc être arrondies à minuit le plus proche. Donc le code sera (ths à 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
    }
user3887038
la source
3

J'ai fait quelques prototypes pour gérer cela pour moi.

// 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;
});

si vous ne voulez pas le contrôle de sécurité, vous pouvez simplement utiliser

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

Exemple d'utilisation:

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

Dans le cas où vous avez déjà d3.js comme dépendance dans votre projet, ou si cela ne vous dérange pas de l'introduire, d3-time (la bibliothèque d3.js est modulaire à partir de la v4.0.0 ) a des intervalles .

Ils peuvent s'avérer utiles lors de la définition des dates sur des valeurs "par défaut", par exemple minuit, 0,00 seconde, le premier du mois, 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)
Peemster
la source
J'ai donc remarqué une tendance dans les questions liées à JavaScript postées sur SO: quelle que soit la complexité des solutions proposées en utilisant JS natif, toutes les réponses abordant le problème à l'aide d'une bibliothèque externe seront inévitablement à un moment donné sous-évaluées. En réalisant cela, j'ai pris soin de poster ma réponse avec la préface rapide: Au cas où vous avez déjà example.js comme dépendance . Et pourtant, le downvote, utilisateur SO anonyme? ça fait mal, l'homme: '- (
Peemster
Je suis tombé que cette réponse ne devrait pas être rejetée, d'autant plus que celle qui propose l'utilisation de moment.js dispose de 16 votes positifs (au moment de la rédaction de ce commentaire). Cela résout le problème d'une manière très concise et pas si évidente.
lukeatdesignworks