J'utilise la java.util.Date
classe Java dans Scala et je veux comparer un Date
objet et l'heure actuelle. Je sais que je peux calculer le delta en utilisant getTime ():
(new java.util.Date()).getTime() - oldDate.getTime()
Cependant, cela me laisse juste un long
représentant des millisecondes. Existe-t-il un moyen plus simple et plus agréable d'obtenir un delta temporel?
Date
,Calendar
etSimpleDateFormat
».java.time.Period
et / ouDuration
. Voir la réponse de Basil Bourque ci-dessous .Réponses:
L'
Date
API JDK est malheureusement horriblement cassée. Je recommande d'utiliser la bibliothèque Joda Time .Joda Time a un concept d' intervalle de temps :
EDIT: Soit dit en passant, Joda a deux concepts:
Interval
pour représenter un intervalle de temps entre deux instants de temps (représentent le temps entre 8h et 10h), et unDuration
qui représente une durée sans les limites de temps réelles (par exemple, représentent deux heures!)Si vous ne vous souciez que des comparaisons de temps, la plupart des
Date
implémentations (y compris celle du JDK) implémentent uneComparable
interface qui vous permet d'utiliser leComparable.compareTo()
la source
Comparable.compareTo()
, pasComparable.compare()
.java.time
package de Java 8 est inspiré de Joda-Time mais n'est pas un remplacement direct. Chacun a ses avantages et ses inconvénients. Heureusement, vous n'avez pas à choisir entre eux. Utilisez chacun pour ses points forts tant que vous faites attention à vosimport
déclarations. Voir cette autre réponse par exemple de java.time.Diff simple (sans lib)
Et puis pouvez-vous appeler:
pour obtenir le diff des 2 dates en unité de minutes.
TimeUnit
estjava.util.concurrent.TimeUnit
, une énumération Java standard allant des nanos aux jours.Différence lisible par l'homme (sans lib)
http://ideone.com/5dXeu6
La sortie est quelque chose comme
Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}
, avec les unités commandées.Il vous suffit de convertir cette carte en une chaîne conviviale.
Attention
Les extraits de code ci-dessus calculent une différence simple entre 2 instants. Cela peut provoquer des problèmes lors d'un changement d'heure d'été, comme expliqué dans cet article . Cela signifie que si vous calculez la différence entre les dates sans heure, il se peut qu'il manque un jour / une heure.
À mon avis, la date diff est un peu subjective, surtout les jours. Tu peux:
compter le nombre de temps écoulé 24h: jour + 1 - jour = 1 jour = 24h
compter le nombre de temps écoulé, en prenant soin de l'heure d'été: jour + 1 - jour = 1 = 24h (mais en utilisant l'heure de minuit et l'heure d'été, il pourrait être 0 jour et 23h)
compter le nombre de
day switches
, ce qui signifie jour + 1 13h - jour 11h = 1 jour, même si le temps écoulé n'est que de 2h (ou 1h s'il y a une heure d'été: p)Ma réponse est valable si votre définition de date diff les jours correspond au 1er cas
Avec JodaTime
Si vous utilisez JodaTime, vous pouvez obtenir le diff pour 2 instants (millies soutenu ReadableInstant) dates avec:
Mais vous pouvez également obtenir le diff pour les dates / heures locales:
la source
Notez que cela fonctionne avec les dates UTC, donc la différence peut être un jour de congé si vous regardez les dates locales. Et le faire fonctionner correctement avec les dates locales nécessite une approche complètement différente en raison de l'heure d'été.
la source
(endDate.getTime() - startDate.getTime())
auint
lieu du résultat final, et vous obtenez un débordement d'entier.Utilisation du framework java.time intégré à Java 8+:
Production:
Pour plus d'informations, consultez le didacticiel Oracle et la norme ISO 8601 .
la source
Period
au lieu deDuration
pour les dates.Vous devez définir votre problème plus clairement. Vous pouvez simplement prendre le nombre de millisecondes entre les deux
Date
objets et diviser par le nombre de millisecondes en 24 heures, par exemple ... mais:Date
est toujours en UTCla source
tl; dr
Convertissez vos obsolètes
java.util.Date
objets à leur remplacement,java.time.Instant
. Ensuite, calculez le temps écoulé comme aDuration
.Format ISO 8601:
PnYnMnDTnHnMnS
La norme sensée ISO 8601 définit une représentation textuelle concise d'une période de temps en nombre d'années, mois, jours, heures, etc. La norme appelle une telle période une durée . Le format est l'
PnYnMnDTnHnMnS
endroit où leP
moyen "Période", leT
sépare la partie date de la partie heure, et entre les deux sont des nombres suivis d'une lettre.Exemples:
P3Y6M4DT12H30M5S
trois ans, six mois, quatre jours, douze heures, trente minutes et cinq secondes
PT4H30M
Quatre heures et demie
java.time
Le framework java.time intégré à Java 8 et versions ultérieures supplante les anciennes
java.util.Date
/java.util.Calendar
classes gênantes . Les nouvelles classes sont inspirées par le framework Joda-Time très réussi , destiné à lui succéder, de concept similaire mais ré-architecturé. Défini par JSR 310 . Prolongé par le projet ThreeTen-Extra . Voir le tutoriel .Moment
La
Instant
classe représente un moment sur la chronologie en UTC avec une résolution de nanosecondes (jusqu'à neuf (9) chiffres d'une fraction décimale).Mieux vaut éviter les anciennes classes telles que
Date
/Calendar
. Mais si vous devez interagir avec l'ancien code qui n'a pas encore été mis à jour vers java.time , convertissez-le d'avant en arrière. Appelez de nouvelles méthodes de conversion ajoutées aux anciennes classes. Pour passer d'unjava.util.Date
à unInstant
, appelezDate::toInstant
.Durée
Les classes java.time ont divisé cette idée de représenter une période de temps en nombre d'années, mois, jours, heures, minutes, secondes en deux moitiés:
Period
pendant des années, des mois, des joursDuration
pour jours, heures, minutes, secondesVoici un exemple.
Dump sur console.
Les deux
Period
etDuration
utiliser l' ISO 8601 standard pour générer une représentation chaîne de leur valeur.Java 9 ajoute des méthodes pour
Duration
obtenir la partie jours, la partie heures, la partie minutes et la partie secondes.Vous pouvez obtenir le nombre total de jours ou d'heures ou de minutes ou de secondes ou de millisecondes ou de nanosecondes sur toute la durée.
Dans Java 9, la
Duration
classe obtient de nouvelles méthodes pour renvoyer les différentes parties de jours, heures, minutes, secondes, millisecondes / nanosecondes. Appelez lesto…Part
méthodes suivantes :toDaysPart()
,toHoursPart()
et ainsi de suite.ChronoUnit
Si vous ne vous souciez que d'une granularité de temps plus simple et plus grande, comme le «nombre de jours écoulés», utilisez l'
ChronoUnit
énumération.Un autre exemple.
À propos de java.time
Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciens gênants hérités des classes date-heure tels que
java.util.Date
,Calendar
, etSimpleDateFormat
.Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers java.time.
Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .
Où obtenir les classes java.time?
Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour de futurs ajouts possibles à java.time. Vous trouverez peut - être des classes utiles ici, comme
Interval
,YearWeek
,YearQuarter
et plus .Joda-Time
MISE À JOUR: Le projet Joda-Time est maintenant en mode maintenance , l'équipe conseillant la migration vers les classes java.time . Je laisse cette section intacte pour l'histoire.
La bibliothèque Joda-Time utilise ISO 8601 pour ses valeurs par défaut. Sa
Period
classe analyse et génère ces chaînes PnYnMnDTnHnMnS.Rendu:
la source
Period
,Duration
etChronoUnit
, trois classes dont le but est de déterminer le delta entre les points de temps. Veuillez indiquer quelles parties de mon «mur de texte» ne sont pas pertinentes. Et vous avez tort de dire que la Question demandait un «delta entre les dates»: La Question demandait un delta entre lesDate
objets, qui sont des moments date-heure, pas des «dates» malgré le nom malheureux de cette classe.java.util.Date
en anInstant
(appelez simplement.toInstant
). Et j'ai ajouté laMoment
section pour expliquer. Vous avez mentionné une paire d'Date
objets, mais en fait, la question n'utilise qu'un seulDate
objet existant et capture ensuite l'instant actuel, alors j'ai fait la même chose. Merci pour les commentaires! Astuce: renoncez à l'utilisationDate
- Ces classes héritées sont vraiment un horrible gâchis.https://www.joda.org/joda-time/faq.html#datediff
la source
Une alternative un peu plus simple:
Quant à "plus joli": eh bien, de quoi avez-vous besoin exactement? Le problème de la représentation des durées en nombre d'heures et de jours, etc., est que cela peut conduire à des inexactitudes et à des attentes erronées en raison de la complexité des dates (par exemple, les jours peuvent avoir 23 ou 25 heures en raison de l'heure d'été).
la source
L'utilisation d'une approche en millisecondes peut entraîner des problèmes dans certains paramètres régionaux.
Prenons, par exemple, la différence entre les deux dates 24/03/2007 et 25/03/2007 devrait être de 1 jour;
Cependant, en utilisant la route en millisecondes, vous obtiendrez 0 jours, si vous exécutez cela au Royaume-Uni!
La meilleure façon de l'implémenter est d'utiliser java.util.Calendar
la source
Il existe de nombreuses façons de trouver la différence entre les dates et les heures. L'un des moyens les plus simples que je connaisse serait:
L'instruction print n'est qu'un exemple - vous pouvez la formater comme vous le souhaitez.
la source
Étant donné que toutes les réponses ici sont correctes mais utilisent des bibliothèques java héritées ou tierces comme joda ou similaire, je vais simplement laisser tomber une autre façon en utilisant de nouvelles classes java.time dans Java 8 et versions ultérieures. Voir Oracle Tutorial .
Utiliser
LocalDate
etChronoUnit
:la source
La soustraction des dates en millisecondes fonctionne (comme décrit dans un autre article), mais vous devez utiliser HOUR_OF_DAY et non HOUR lors de l'effacement des parties temporelles de vos dates:
la source
Si vous ne souhaitez pas utiliser JodaTime ou similaire, la meilleure solution est probablement la suivante:
Le nombre de ms par jour n'est pas toujours le même (en raison de l'heure d'été et des secondes intercalaires), mais il est très proche, et au moins les écarts dus à l'heure d'été s'annulent sur des périodes plus longues. Par conséquent, la division puis l'arrondi donneront un résultat correct (au moins tant que le calendrier local utilisé ne contient pas de sauts de temps étranges autres que l'heure d'été et les secondes intercalaires).
Notez que cela suppose toujours que
date1
etdate2
sont définis à la même heure de la journée. Pour différentes heures de la journée, vous devez d'abord définir ce que signifie «différence de date», comme l'a souligné Jon Skeet.la source
date1.getTime()
contredate2.getTime()
. Ainsi, la différence entre le 2016-03-03 et le 2016-03-31 calculera 27 jours alors que vous en voudriez 28.Math.round()
, qui semble sûre dans les calendriers du «monde réel». Désolé pour le bruit.Jetez un œil à Joda Time , qui est une API Date / Time améliorée pour Java et devrait fonctionner correctement avec Scala.
la source
Permettez-moi de montrer la différence entre Joda Interval et Days:
la source
Si vous avez besoin d'une chaîne de retour formatée comme "2 jours 03h 42m 07s", essayez ceci:
la source
std
ci-dessus n'est pas défini.Remarque: startDate et endDates sont -> java.util.Date
et date de fin
Comme pour les jours, vous pouvez également obtenir des heures, des minutes et des secondes
la source
Consultez l'exemple ici http://www.roseindia.net/java/beginners/DateDifferent.shtml Cet exemple vous donne la différence en jours, heures, minutes, secondes et milli secondes :).
la source
Utilisez le fuseau horaire GMT pour obtenir une instance de Calendar, définissez l'heure à l'aide de la méthode set de la classe Calendar. Le fuseau horaire GMT a 0 décalage (pas vraiment important) et l'indicateur d'heure d'été réglé sur faux.
la source
java.util.Date
etc. L'utilisation du hack pour définir le fuseau horaire sur GMT rend le code insensible aux effets de l'heure d'été.Le code suivant peut vous donner la sortie souhaitée:
la source
la source
la source
Date
, donc cette comparaison est la meilleure qui puisse être réalisée compte tenu des circonstances.La meilleure chose à faire est
Ce nombre est le nombre de millisecondes dans une journée.
Une date-autre date vous donne la différence en millisecondes.
Recueillez la réponse dans une double variable.
la source
Voici une solution Java 7 correcte dans O (1) sans aucune dépendance.
la source
C'est probablement la façon la plus simple de le faire - c'est peut-être parce que je code en Java (avec ses bibliothèques de date et d'heure certes maladroites) depuis un certain temps maintenant, mais ce code me semble "simple et agréable"!
Êtes-vous satisfait du retour du résultat en millisecondes, ou est-ce une partie de votre question que vous préféreriez qu'il soit retourné dans un autre format?
la source
Ne pas utiliser l'API standard, non. Vous pouvez lancer la vôtre en faisant quelque chose comme ceci:
Ou vous pouvez utiliser Joda :
la source
Juste pour répondre à la question initiale:
Mettez le code suivant dans une fonction comme Long getAge () {}
Le plus important ici est de travailler avec des nombres longs lors de la multiplication et de la division. Et bien sûr, le décalage que Java applique dans son calcul des dates.
:)
la source
Étant donné que la question est étiquetée avec Scala,
la source
Après avoir parcouru toutes les autres réponses, pour conserver le type de date Java 7 mais être plus précis / standard avec l'approche diff de Java 8,
la source
essaye ça:
vous pouvez éditer la chaîne dans le paramètre des méthodes parse ().
la source