Domanda

Come trovo la differenza in giorni tra due Joda-Time DateTime istanze?Con "differenza di giorni" intendo che se l'inizio è lunedì e la fine è martedì mi aspetto un valore restituito pari a 1 indipendentemente dall'ora/minuto/secondi delle date di inizio e fine.

Days.daysBetween(start, end).getDays() mi dà 0 se l'inizio è la sera e la fine la mattina.

Sto riscontrando lo stesso problema anche con altri campi data, quindi speravo che ci fosse un modo generico per "ignorare" i campi di minore importanza.

In altre parole, anche i mesi tra febbraio e il 4 marzo sarebbero 1, così come lo sarebbero le ore tra le 14:45 e le 15:12.Tuttavia la differenza oraria tra le 14:01 e le 14:55 sarebbe 0.

È stato utile?

Soluzione

Fastidiosamente, la risposta withTimeAtStartOfDay è sbagliato, ma solo occasionalmente. Si desidera:

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

Si scopre che "la mezzanotte / inizio del giorno" a volte significa 1:00 (ora legale avvengono in questo modo in alcuni luoghi), che Days.daysBetween non gestisce correttamente.

// 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

Andando attraverso un LocalDate elude l'intera questione.

Altri suggerimenti

Days Classe

Uso della href="http://www.joda.org/joda-time/apidocs/org/joda/time/Days.html" rel="noreferrer"> Days classe withTimeAtStartOfDay metodo dovrebbe funzionare:

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

è possibile utilizzare LocalDate :

Days.daysBetween(new LocalDate(start), new LocalDate(end)).getDays() 

tl; dott

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

…O…

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

java.time

Per tua informazione, il Joda-Time il progetto è ora disponibile Modalità di manutenzione, con il team che consiglia la migrazione a java.time classi.

L'equivalente di Joda-Time DateTime È ZonedDateTime.

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

Apparentemente vuoi contare i giorni in base alle date, il che significa che vuoi ignorare l'ora del giorno.Ad esempio, se si inizia un minuto prima di mezzanotte e si termina un minuto dopo mezzanotte, il giorno dovrebbe essere un solo.Per questo comportamento, estrarre a LocalDate dal tuo ZonedDateTime.IL LocalDate La classe rappresenta un valore di sola data senza ora del giorno e senza fuso orario.

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

Usa il ChronoUnit enum per calcolare i giorni trascorsi o altre unità.

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

Troncare

Per quanto riguarda la domanda su un modo più generale per eseguire questo conteggio laddove ti interessa il delta delle ore come ora dell'orologio anziché le ore complete come intervalli di tempo di sessanta minuti, utilizza l'opzione truncatedTo metodo.

Ecco il tuo esempio dalle 14:45 alle 15:12 dello stesso giorno.

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

Per il conteggio dei giorni per data, troncare a ChronoUnit.DAYS.Ecco un esempio che scorre sopra la mezzanotte da cinque minuti prima a cinque minuti dopo, per i giorni trascorsi di 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


Di java.time

IL java.time framework è integrato in Java 8 e versioni successive.Queste classi soppiantano quelle vecchie e fastidiose eredità classi data-ora come java.util.Date, Calendar, & SimpleDateFormat.

IL Joda-Time progetto, ora in Modalità di manutenzione, consiglia la migrazione al java.time classi.

Per saperne di più, vedere il Tutorial sull'Oracolo.E cerca Stack Overflow per molti esempi e spiegazioni.La specifica è JSR310.

Puoi scambiare java.time oggetti direttamente con il tuo database.Usare un driver JDBC conforme a JDBC4.2 o più tardi.Non c'è bisogno di stringhe, non c'è bisogno di java.sql.* classi.

Dove ottenere le classi java.time?

  • JavaSE8, JavaSE9, JavaSE10, e più tardi
    • Integrato.
    • Parte dell'API Java standard con un'implementazione in bundle.
    • Java 9 aggiunge alcune funzionalità e correzioni minori.
  • JavaSE6 E JavaSE7
    • Gran parte della funzionalità java.time è retroportata su Java 6 e 7 in ThreeTen-Backport.
  • Androide
    • Versioni successive delle implementazioni dei bundle Android delle classi java.time.
    • Per Android precedenti (<26), il file TredieciABP il progetto si adatta ThreeTen-Backport (menzionato sopra).Vedere Come utilizzare ThreeTenABP....

IL Tredieci-Extra il progetto estende java.time con classi aggiuntive.Questo progetto è un banco di prova per possibili future aggiunte a java.time.Potresti trovare alcune classi utili qui come Interval, YearWeek, YearQuarter, E Di più.

IL Tredieci-Extra il progetto estende java.time con classi aggiuntive.Questo progetto è un banco di prova per possibili future aggiunte a java.time.Potresti trovare alcune classi utili qui come Interval, YearWeek, YearQuarter, E Di più.

La risposta accettata costruisce due oggetti LocalDate, che sono piuttosto costosi se si sta leggendo molti dati. Io uso questo:

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

Chiamando getMillis() si utilizza già variabili esistenti.
MILLISECONDS.toDays() poi, utilizza un calcolo aritmetico semplice, non crea alcun oggetto.

java.time.Period

Utilizzare la classe java.time.Period per conteggio giorni .

Dal momento che Java 8 calcolando la differenza è più intuitivo utilizzando LocalDate, LocalDateTime per rappresentare le due date

    LocalDate now = LocalDate.now();
    LocalDate inputDate = LocalDate.of(2018, 11, 28);

    Period period = Period.between( inputDate, now);
    int diff = period.getDays();
    System.out.println("diff = " + diff);
DateTime  dt  = new DateTime(laterDate);        

DateTime newDate = dt.minus( new  DateTime ( previousDate ).getMillis());

System.out.println("No of days : " + newDate.getDayOfYear() - 1 );    
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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top