2009-01-17 7 views
17

Je trouve amusant que Java (ou la bibliothèque java.util) n'ait pas de fonction intégrée pour calculer la différence de dates. Je veux soustraire une date d'une autre pour obtenir le temps écoulé entre eux. Quelle est la meilleure façon de procéder?Calcul de la différence des dates en Java

Je sais que le moyen le plus simple est de prendre la différence de temps en millisecondes, puis de la convertir en jours. Cependant, je voulais savoir si cela fonctionnait dans tous les cas (avec l'heure d'été, etc.).

+2

Voir http://www.xmission.com/~goodhill/dates/deltaDates.html pour quelques informations. –

+0

C'est un bon article. Merci! – Anirudh

+0

@Anirudh Recherche StackOverflow pour "joda" et terme tel que "span", "intervalle", "durée", "période". Vous trouverez de nombreux exemples avec discussion. –

Répondre

6

Je sais que le moyen simple est de prendre la différence du temps en millisecondes puis convertir en jours. Cependant, je voulais savoir si ce fonctionne dans tous les cas (avec la sauvegarde de la lumière du jour , etc.).

Si votre temps proviennent de dates UTC, ou ils sont juste la différence entre deux appels à System.getCurrentTimeMillis() mesurée sur le même système, vous obtiendrez un nombre valide de millisecondes que la différence, indépendamment de tous les problèmes de fuseau horaire. (c'est pourquoi tout devrait utiliser l'UTC comme format de stockage - il est beaucoup plus facile de passer de l'heure UTC à l'heure locale, si vous essayez de passer à autre chose, vous devez stocker le fuseau horaire local avec l'heure locale - ou tenter de l'inférer, gack!)

Pour ce qui est de transformer cela en un certain nombre de jours, vous devriez juste être en mesure de diviser par 86400000 ... avec la mise en garde qu'il existe un leap second tous les deux ans ou à l'occasion.

8

Java ne manque pas beaucoup, si vous regardez à l'open source: essayez Joda-Time.

+3

question à propos de Java date ==> réponse mention Joda! –

+1

Oui, c'est comme ça que ça fonctionne quand une langue a 2 classes date/heure défectueuses. – krosenvold

+0

J'ai regardé Joda - malheureusement, je ne suis pas autorisé à utiliser des bibliothèques non standard :( – Anirudh

0

Je suis en désaccord avec l'affirmation selon laquelle Java ne dispose pas d'un mécanisme de calcul de la différence entre les dates.

Java a été conçu pour une utilisation globale. Il a été conçu pour qu'il n'y ait pas de concept de date, il n'y a qu'un concept de "temps en millisecondes". Toute interprétation d'une heure aussi universelle que l'heure et la date dans un lieu spécifique en vertu d'une convention spécifique est simplement une projection ou une vue.

La classe calendar est utilisée pour transformer ce type d'heure absolue en dates. Vous pouvez également ajouter ou soustraire des composants de date, si vous en avez vraiment besoin. La seule façon de fournir une différence en termes de composants entre deux fois serait calendrier généré et spécifique. Ainsi, vous pourriez argumenter que la bibliothèque standard n'inclut pas un calendrier grégorien assez intelligent, et je suis d'accord que cela laisse à désirer. Cela étant dit, il existe de nombreuses implémentations de ce type de fonctionnalité, je vois que d'autres ont fourni des exemples.

+0

Je suis d'accord avec vous en principe. Ma revendication de Java ne possédant pas cette fonctionnalité était basée sur le fait que d'autres langages (Ruby, Python, etc.) ont une implémentation très simple (et fonctionnelle) d'ajout et de soustraction de dates dans les classes Date standard. – Anirudh

2

Avec la bibliothèque date4j:

int numDaysBetween = oneDate.numDaysFrom(anotherDate); 
1

Il est moyen simple de le mettre en œuvre. Nous pouvons utiliser la méthode Calendar.add avec une boucle. Par exemple, comme ci-dessous,

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 

Date beginDate = dateFormat.parse("2013-11-29"); 
Date endDate = dateFormat.parse("2013-12-4"); 

Calendar beginCalendar = Calendar.getInstance(); 
beginCalendar.setTime(beginDate); 

Calendar endCalendar = Calendar.getInstance(); 
endCalendar.setTime(endDate); 

Les jours moins entre beginDate et endDate, et le code comme ci-dessous,

int minusDays = 0; 
while (true) { 
    minusDays++; 

    // Day increasing by 1 
    beginCalendar.add(Calendar.DAY_OF_MONTH, 1); 

    if (dateFormat.format(beginCalendar.getTime()). 
      equals(dateFormat.format(endCalendar).getTime())) { 
    break; 
    } 
} 
System.out.println("The substractation between two days is " + (minusDays + 1)); 

Have Fun! @. @

+0

J'ai déjà utilisé cette méthode auparavant. Cependant, son exécution est O (N), où N est le nombre de jours entre beginDate et endDate. Je pense que l'utilisation de JodaTime donnera de meilleurs résultats. – jharig23

+0

Oui, vous avez raison. MAIS je pense que O (n) est acceptable pour certains projets. Parce que je ne veux pas importer de lib. Encore merci pour vos suggestions. –

4

Utilisez soit Joda-Time ou le nouveau package java.time en Java 8.

Les deux cadres utilisent l'demi-approche ouverte où le début est inclus alors que la fin est exclusive. Parfois notée comme [). C'est généralement la meilleure approche pour définir les intervalles de temps.

java.time

Le cadre java.time construit en Java 8 et a plus tard une classe Period pour représenter un laps de temps comme un certain nombre d'années, un certain nombre de mois, et un certain nombre de jours. Mais cette classe est limitée à des jours entiers, aucune représentation des heures, des minutes et des secondes.

Notez que nous spécifions un fuseau horaire, crucial pour déterminer une date. Par exemple, un nouveau jour apparaît plus tôt dans Paris que dans Montréal.

ZoneId zoneId = ZoneId.of("America/Montreal"); 
LocalDate now = LocalDate.now(zoneId); 
LocalDate then = LocalDate.of(2001, 1, 1); 
Period period = Period.between(then, now); 

Puis: 2001-01-01. Maintenant: 2015-09-07. Période: P14Y8M6D. Jours: 5362

Pour des jours entiers, alors Daylight Saving Time (DST) est sans importance.

Si vous souhaitez connaître le nombre total de jours, utilisez l'énumération ChronoUnit qui inclut des méthodes de calcul. Notez que les calculs reviennent longtemps.

long days = ChronoUnit.DAYS.between(then, now); // "5362" seen above. 

I have asked à faire une période complète à java.time, y compris les heures, minutes, secondes. Pas possible à partir de Java 8. Une solution de contournement surprenante utilisant les bibliothèques groupées was suggested par Meno Hochschild: Utilisez une classe Duration trouvée dans le javax.xml.datatype package.

Joda-Time

Voici quelques exemples de code dans Joda-Time 2.3.

DateTimeZone timeZone = DateTimeZone.forID("Europe/Paris"); 
DateTime start = new DateTime(2014, 1, 2, 3, 4, 5, timeZone); 
DateTime stop = new DateTime(2014, 5, 2, 3, 4, 5, timeZone); 
Period period = new Period(start, stop); 

appel toString vous obtiendrez une représentation de chaîne sous la forme définie par la norme ISO 8601, PnYnMnDTnHnMnS.