2009-06-11 11 views
5

Je sais Date est la plupart du temps obsolète, mais je l'utilise encore de temps en temps (moins de code que d'utiliser Calendar). Je suis tombé sur un bug vraiment bizarre, et je me demande si quelqu'un peut m'expliquer cela.Que se passe-t-il avec la classe Java de Java? Est-ce un bug connu?

Ce code, qui ajoute 24 jours à l'heure actuelle:

long nowL = System.currentTimeMillis(); 
Date now = new Date(nowL); 
System.out.println("now = "+now); 
Date future = new Date(nowL+ 24*24*60*60*1000); 
System.out.println("future = "+future); 

donne cette sortie correcte:

maintenant = Jeu 11 juin 10:50:09 IDT 2009

future = Sun Jul 05 10:50:09 IDT 2009

alors que ce code, qui ajoute 2 5 jours:

long nowL = System.currentTimeMillis(); 
Date now = new Date(nowL); 
System.out.println("now = "+now); 
Date future = new Date(nowL+ 25*24*60*60*1000); 
System.out.println("future = "+future); 

donne cette sortie:

maintenant = Jeu 11 juin 2009 10:51:25 IDT

future = Sun 17 mai 2009 17:48:37 IDT

Je peux comprendre une différence d'heures, voire des jours, mais quelqu'un peut-il expliquer pourquoi ajouter trop de millisecondes provoque va dans le temps ?? Je suis déconcerté.

Répondre

27

25 * 24 * 60 * 60 * 1000 = 2160000000 = 0x80BEFC00

vous calculer une valeur entière, et obtenez un trop-plein. si elle était

25 * 24 * 60 * 60 * 1000L

tout devrait bien.

+0

très subtile - bien repéré! – belugabob

+0

Oui, j'ai eu la même pensée et je l'ai vérifié juste pour constater que vous l'aviez déjà compris. :) –

+6

TRWTF est que le compilateur ne vous avertit pas d'un débordement d'entier pour une constante .. – Thorarin

5

Ce n'est pas un bogue dans la classe Date, c'est un cas de dépassement d'entier. int s en Java ne peuvent être comprises entre -2 et 2 -1, mais 25 1000 est supérieure à 2 -1 de sorte qu'il déborde.

Si vous exécutez

System.out.println(24*24*60*60*1000); 
System.out.println(25*24*60*60*1000); 

vous obtenez les résultats

2073600000 
-2134967296 

Si vous spécifiez un des numéros que vous multiplions ensemble comme une long en ajoutant le suffixe L à lui, le produit sera également un long. long valeurs peuvent aller jusqu'à 2 - 1 de sorte que vous ne serez pas débordement sauf si vous ajoutez un lot de jours à votre Date s.Par exemple,

System.out.println(25L*24*60*60*1000); 

vous donne

2160000000 
Questions connexes