Java Calendrier: l'Obtention de la Différence Entre Deux Dates/heures - par Un
J'ai vu beaucoup de questions et de réponses sur ce sujet, mais aucun ne s'est attaqué mon problème particulier. J'ai étendu la java Calendrier de la classe (standard-pas de bibliothèques tierces), et le besoin de trouver la différence dans jours entre deux arbitraire dates.
Méthode:
- Modifier le délai de deux dates à minuit.
- Convertir les dates en millisecondes.
- Trouver la différence entre les deux dates.
- Diviser le résultat par le nombre de millisecondes dans une journée (24 * 60 *
60 * 1000). - Le résultat doit être la différence en jours.
Et elle l'est parfois, et parfois il ne l'est pas. Même les tests à la même date peut être désactivé par un. Ce qui se passe?
- Sur une note de côté, vous êtes sûr que c'était une bonne idée d'élargir
Calendar
par opposition à la production d'une bibliothèque d'assistance qui fonctionne surCalendar
instances? - Un des problèmes est que vous assumez il y a 86400000ms en une journée.
Vous devez vous connecter pour publier un commentaire.
Comme suggéré par d'autres utilisateurs, vous devez également définir la valeur en millisecondes des calendriers à zéro de comparer seulement les dates. Ceci peut être réalisé avec l'extrait de code suivant:
Notez également que les changements de fuseau horaire (par exemple, le déplacement de l'heure d'hiver à l'heure d'été) peut signifier qu'il y a plus ou moins de 86,400,000 ms en une journée.
java.util.Calendar
sont maintenant héritage, supplantée par la java.de temps les classes.La Joda Time Bibliothèque a un très bon soutien pour des problèmes tels:
Mise à JOUR (les commentaires de @basile-bourque):
De Java 8, la nouvelle bibliothèque d'
java.time
a été introduit, maintenant une option similaire sans dépendances externes est disponible:java.time
de JRE 8 bibliothèquesLocalDateTime
est pas la bonne catégorie pour ce. Cette classe perd délibérément offset et les informations de fuseau horaire. Si vous allez travailler avec des génériques de jours de 24 heures, et en ignorant les anomalies représentés dans le temps des zones telles que l'Heure d'été (DST). Voir ma Réponse pour plus de détails.tl;dr
Naïf calculs
Vous supposez dans votre code que chaque jour est exactement vingt-quatre heures de temps. Pas vrai. Les Anomalies telles que des Heure d'été (DST) signifie que les jours peut varier comme 23 heures, 25 heures, ou d'autres numéros. Le sens même d'un fuseau horaire est suivi d'un historique de ces anomalies.
Aussi, vous assumez la journée commence à minuit. Pas vrai. En raison d'anomalies, certains jours, de commencer à d'autres moments de la journée comme
01:00
.Éviter héritage de date-heure classes
Vous utilisez le gênants de longue date du temps des classes comme
java.util.Date
,java.util.Agenda
, etjava.text.SimpleTextFormat
sont maintenant héritage, supplanté par le java.le temps classes.Fuseau horaire
Spécifier un fuseau horaire nom dans le format de
continent/region
, commeAmerica/Montreal
,Africa/Casablanca
, ouPacific/Auckland
. Ne jamais utiliser de l'3-4 abréviation commeEST
ouIST
comme ils sont pas vrai fuseaux horaires, pas normalisée, et même pas unique(!).Ne s'étendent pas java.temps
Ne s'étend pas (sous-classe) de java.les classes de temps (ils sont marqués
final
).Et de ne pas généraliser à leurs interfaces de votre logique métier; bâton pour les classes concrètes de ce cadre. Alors que la généralisation de sens dans d'autres cadres tels que Java Collections, pas le cas en java.temps.
À l'aide de java.temps
Ce travail est beaucoup plus facile avec le java.les classes de temps.
ZonedDateTime
représente un moment sur la timeline avec une affectation de tim zone (ZoneId
).La
ChronoUnit
enum peut calculer le temps écoulé entre une paire de moments.Voir ce code à exécuter en direct à IdeOne.com.
Convertissez des instances de java.temps
Si vous êtes donné
GregorianCalendar
objets, de les convertir en java.le temps à l'aide de nouvelles méthodes ajoutées aux anciennes classes.Si vous connaissez un
Calendar
instance est en fait unGregorianCalendar
, de voter pour elle.À Moitié Ouverte
La java.les classes de temps de définir des intervalles de temps par la Demi-approche Ouverte où le début est inclusive alors que la fin est exclusif.
Sur java.temps
La java.le temps cadre est intégré dans Java 8 et les versions ultérieures. Ces classes permettent d'éviter la pénible vieux héritage date du temps des classes comme
java.util.Date
,Agenda
, &SimpleDateFormat
.La Joda-Time projet, maintenant dans le mode de maintenance, conseille la migration vers le java.le temps classes.
Pour en savoir plus, consultez les Oracle Tutoriel. Et de recherche de Débordement de Pile pour de nombreux exemples et des explications. La spécification est JSR 310.
Où obtenir le java.les classes de temps?
La ThreeTen-Extra projet s'étend java.temps avec d'autres classes. Ce projet est un terrain d'essai pour de possibles futurs ajouts à java.temps. Vous pouvez trouver quelques classes utiles ici comme
Intervalle
,YearWeek
,YearQuarter
, et plus.J'ai écrit beaucoup plus de moyen plus simple de s'attaquer à ce problème, même j'ai été confronté au même problème d'avoir un jour supplémentaire pour certaines dates.
C'est mon approche actuellement,
auparavant, j'étais à l'aide de cette pièce de la ligne, le reste est identique :-
Mais semble ne pas fonctionner pour moi.
Vous avez reconnu le problème de la première étape par la mise à l'heure de minuit: qui fait en sorte que toutes les heures, les minutes et les secondes à zéro. Mais vous n'allez pas assez loin! Vous devez également vous assurer que le millisecondes sont remis à zéro, trop.
Voici un peu de code pour faire exactement cela.
Calendar
cas avecset(Calendar.MILLISECOND, 0)
.Je crois que vous avez besoin de tronquer la partie à partir de la date avant le calcul de la différence en tant que ci-dessous:
Espère que cela fonctionne.
J'ai ma fonction en tant que but à votre demande. J'ai été en utilisant le calendrier, j'ai mis tout le temps de la partie à 0 avant de comparer.