Nombre de jours entre deux dates en Joda-Time

Comment trouver la différence en jours entre deux Joda-Time DateTime des exemples? Avec " différence dans les jours’ je veux dire si le début est le lundi et la fin est le mardi je m'attends à une valeur de retour de 1 indépendamment de l'heure/minute/secondes des dates de début et de fin.

Days.daysBetween(start, end).getDays() me donne 0 si le départ est le soir et se termine le matin.

j'ai aussi le même problème avec d'autres champs de date donc j'espérais qu'il y aurait une façon générique d'ignorer les champs de moindre importance.

en d'autres termes, les mois entre février et 4 Mars serait également 1, comme le serait les heures entre 14:45 et 15:12 être. Cependant, la différence d'heure entre 14:01 et 14:55 serait 0.

287
demandé sur Basil Bourque 2010-09-27 14:21:30
la source

6 ответов

fâcheusement, la réponse de withTimeAtStartOfDay est fausse, mais seulement de temps en temps. Vous voulez:

Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays()

il s'avère que" minuit/début de journée " signifie Parfois 1am (l'heure d'été se passe de cette façon dans certains endroits), quels jours.daysbet between ne fonctionne pas correctement.

// 5am on the 20th to 1pm on the 21st, October 2013, Brazil
DateTimeZone BRAZIL = DateTimeZone.forID("America/Sao_Paulo");
DateTime start = new DateTime(2013, 10, 20, 5, 0, 0, BRAZIL);
DateTime end = new DateTime(2013, 10, 21, 13, 0, 0, BRAZIL);
System.out.println(daysBetween(start.withTimeAtStartOfDay(),
                               end.withTimeAtStartOfDay()).getDays());
// prints 0
System.out.println(daysBetween(start.toLocalDate(),
                               end.toLocalDate()).getDays());
// prints 1

passant par un LocalDate esquive toute la question.

345
répondu Alice Purcell 2015-02-12 02:28:26
la source

Days Classe

utilisant la classe Days avec la classe withTimeAtStartOfDay la méthode doit fonctionner:

Days.daysBetween(start.withTimeAtStartOfDay() , end.withTimeAtStartOfDay() ).getDays() 
183
répondu Michael Borgwardt 2014-12-25 12:29:40
la source

vous pouvez utiliser LocalDate :

Days.daysBetween(new LocalDate(start), new LocalDate(end)).getDays() 
82
répondu Bozho 2014-12-25 12:34:18
la source

tl; dr

java.time.temporal.ChronoUnit.DAYS.between( 
    earlier.truncatedTo( ChronoUnit.DAYS )  , 
    later.truncatedTo( ChronoUnit.DAYS ) 
)

... ou ...

java.time.temporal.ChronoUnit.HOURS.between( 
    earlier.truncatedTo( ChronoUnit.HOURS )  , 
    later.truncatedTo( ChronoUnit.HOURS ) 
)

de java.heure

POUR INFORMATION , Le projet Joda-Time est maintenant en mode maintenance , avec l'équipe conseillant la migration vers le java.temps des classes.

l'équivalent du temps Joda DateTime est ZonedDateTime .

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;

apparemment vous voulez compter les jours par des dates, ce qui signifie que vous voulez ignorer l'heure de la journée. Par exemple, commencer une minute avant minuit et se terminer une minute après minuit devrait se traduire par une seule journée. Pour ce comportement, extraire un LocalDate de votre ZonedDateTime . La classe LocalDate représente une date sans Heure de la journée et sans fuseau horaire.

LocalDate localDateStart = zdtStart.toLocalDate() ;
LocalDate localDateStop = zdtStop.toLocalDate() ;

utilisez le ChronoUnit enum pour calculer jours écoulés ou autres unités.

long days = ChronoUnit.DAYS.between( localDateStart , localDateStop ) ;

tronqué

pour ce qui est de vous demander une façon plus générale de faire ce comptage où vous êtes intéressé le delta des heures comme Heure-de-l'horloge plutôt que des heures complètes comme des périodes de temps de soixante minutes, utilisez la méthode truncatedTo .

voici votre exemple de 14: 45 à 15: 12 le même jour.

ZoneId z = ZoneId.of( "America/Montreal" ); 
ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 14 , 45 , 0 , 0 , z );
ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 17 , 15 , 12 , 0 , 0 , z );

long hours = ChronoUnit.HOURS.between( start.truncatedTo( ChronoUnit.HOURS ) , stop.truncatedTo( ChronoUnit.HOURS ) );

1

pour un décompte de jours par dates, tronqué à ChronoUnit.DAYS . Voici un exemple qui tourne sur minuit de cinq minutes avant à cinq minutes après, pour les jours écoulés de 1 .

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 23 , 55 , 0 , 0 , z );
ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 18 , 00 , 05 , 0 , 0 , z );

long days = ChronoUnit.DAYS.between( start.truncatedTo( ChronoUnit.DAYS ) , stop.truncatedTo( ChronoUnit.DAYS ) );

1


à Propos de de java.heure

Le de java.heure framework est intégré à Java 8 et plus tard. Ces classes remplacent les anciennes classes de date legacy telles que java.util.Date , Calendar , & SimpleDateFormat .

le Joda-Time projet, maintenant en mode maintenance , conseille la migration vers le java.temps des classes.

pour en savoir plus, voir le Oracle Tutorial . Et rechercher le débordement de la pile pour de nombreux exemples et explications. La spécification est JSR 310 .

vous pouvez échanger java.temps objets directement avec votre base de données. Utiliser un JDBC driver conforme à JDBC 4.2 ou plus tard. Aucun besoin de Chaînes, pas besoin de classes java.sql.* .

où obtenir le java.les classes de temps?

Le ThreeTen-Extra le projet s'étend java.temps avec des cours supplémentaires. Ce projet est un terrain d'expérimentation pour d'éventuelles futures additions à java.temps. Vous pouvez trouver ici quelques cours utiles tels que: Interval , YearWeek , YearQuarter , et plus .

le projet ThreeTen-Extra étend java.temps avec des cours supplémentaires. Ce projet est un terrain d'expérimentation pour d'éventuelles futures additions à java.temps. Vous pouvez trouver ici quelques cours utiles tels que: Interval , YearWeek , YearQuarter , et plus .

6
répondu Basil Bourque 2018-05-03 04:19:16
la source

la réponse acceptée construit deux LocalDate objets, qui sont assez coûteux si vous lisez beaucoup de données. J'utilise ceci:

  public static int getDaysBetween(DateTime earlier, DateTime later)
  {
    return (int) TimeUnit.MILLISECONDS.toDays(later.getMillis()- earlier.getMillis());
  }

en appelant getMillis() vous utilisez des variables déjà existantes.

MILLISECONDS.toDays() ensuite, utilise un calcul arithmétique simple, ne crée aucun objet.

2
répondu JBoy 2016-06-21 15:37:31
la source
public static int getDifferenceIndays(long timestamp1, long timestamp2) {
    final int SECONDS = 60;
    final int MINUTES = 60;
    final int HOURS = 24;
    final int MILLIES = 1000;
    long temp;
    if (timestamp1 < timestamp2) {
        temp = timestamp1;
        timestamp1 = timestamp2;
        timestamp2 = temp;
    }
    Calendar startDate = Calendar.getInstance(TimeZone.getDefault());
    Calendar endDate = Calendar.getInstance(TimeZone.getDefault());
    endDate.setTimeInMillis(timestamp1);
    startDate.setTimeInMillis(timestamp2);
    if ((timestamp1 - timestamp2) < 1 * HOURS * MINUTES * SECONDS * MILLIES) {
        int day1 = endDate.get(Calendar.DAY_OF_MONTH);
        int day2 = startDate.get(Calendar.DAY_OF_MONTH);
        if (day1 == day2) {
            return 0;
        } else {
            return 1;
        }
    }
    int diffDays = 0;
    startDate.add(Calendar.DAY_OF_MONTH, diffDays);
    while (startDate.before(endDate)) {
        startDate.add(Calendar.DAY_OF_MONTH, 1);
        diffDays++;
    }
    return diffDays;
}
-11
répondu user1091978 2014-12-24 20:38:04
la source

Autres questions sur