Numero di giorni tra due date in Joda-Time
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.
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;
}