2017-08-11 1 views
0

Je suis un débutant et a récemment commencé à lire Beginning Javascript, par McPeak et Wilton. Les auteurs proposent un exercice sur le calcul des dates. C'est l'exerciceJavascript - comportement inattendu dans les calculs de dates

En utilisant le type Date, calculez la date dans 12 mois.

J'ai essayé de le résoudre avec ce code

//gets today's date 
    var today = new Date(); 

//this line transforms the date in milliseconds  
var daysAsMilliseconds = 1000* 60 * 60 * 24 * today.getDate(); 

//creates a new Date object 
    console.log(new Date(today.setDate(365) + daysAsMilliseconds)); 

Le résultat que je reçois ici est correct (du 11 Août 2018).

Plus tard, je me demande s'il était vraiment nécessaire de créer 2 variables et a essayé cette solution:

var today = new Date(); 
console.log(new Date(today.setDate(365) + (1000 * 60 * 60 * 24 * today.getDate()))); 

Ici, la solution était incorrecte. La console a montré le 31 août 2018. Pourquoi?

Si nécessaire, here you will find the repl.it with the code

+0

Etes-vous sûr ?? essayez ceci: console.log (nouvelle Date (nouvelle Date(). setDate (365) + (1000 * 60 * 60 * 24 * nouvelle Date(). getDate()))); Donne la sortie attendue – Winnie

+1

Veuillez utiliser les extraits de pile, pas repl.it. –

+1

@ T.J.Crowder, je ne savais pas Stack Snippets. Merci de m'avoir présenté –

Répondre

2

Vous appelez setDate, avant d'appeler getDate donc getDate toujours revenir 365. Il suffit Swapp il:

new Date((1000 * 60 * 60 * 24 * today.getDate()) + today.setDate(365)) 

Ou le plus facile à mai travailler directement avec les mois:

today.setMonth(today.getMonth() + 12); 
var intwelvemonths = today; 
+1

Non seulement "plus facile" de le faire avec des mois, faire cela en millisecondes et 'setDate (365)' est en fait ** faux **; votre approche des mois (ou l'approche de l'année de Pointy) est la bonne façon de le faire. Le faire avec des millisecondes ne tient pas compte de divers aléas en termes de durée d'une année (comme les années bissextiles). –

+1

Les années bissextiles, les secondes intercalaires, les quarts de jour/heure d'été, etc. Calculer des plages de temps avec «secondes math» est toujours risqué :) – Pointy

1

Vous appelez today.setDate(365) avant d'ajouter les résultats de today.getDate(): today.getDate() donnera la date que vous définissez, pas la date d'aujourd'hui.

Changer l'ordre des opérations fera l'affaire:

var today = new Date(); 
new Date((1000 * 60 * 60 * 24 * today.getDate()) + today.setDate(365)); 
+2

Sauf que les années ne durent pas exactement 365 jours. –

+0

C'est vrai, mais la racine du problème d'OP n'est pas une astuce du calendrier, c'est l'ordre des opérations. – ajm

+0

Oui, il semble que travailler avec des dates est plus subtile que je ne l'imaginais, comme l'explique Noah Sussman dans ce [post] (http://infiniteundo.com/post/25326999628/falsehoods-programmers-believe-about-time). –

2

Tout ce que vous devez faire est d'ajouter 1 à l'année:

var yearFromNow = new Date(); 
yearFromNow.setYear(yearFromNow.getFullYear() + 1); 

Réglage de la date à 365 n'a pas de sens; .setDate() est pour le jour du mois, donc en le mettant à cette constante déplace la date par an (habituellement) à partir du dernier jour du mois précédent. Et vous n'avez pas besoin de faire d'autres calculs en dehors de l'API de date; juste incrémenter l'année, et vous avez terminé.

+0

C'est un moyen plus facile que je pensais, merci –

0

Je vous recommande d'utiliser un paquet comme moment.js car il gère beaucoup de formats de date, et il a de très bonnes implémentations pour la gestion de la date.

Utilisation du moment js pour l'ajout.

moment().add(Number, String);

Exemple

var m = moment(new Date(2011, 2, 12, 5, 0, 0)); 
m.hours(); // 5 
m.add(1, 'days').hours(); // 5 

Pour plus de docs see moment().add() docs