Joda time plusDays ha sbagliato data
Sto usando questo codice:
DateTime(date)//Thu Aug 06 00:00:00 GMT+03:00 2020
.plusDays(days) // 103
.toDate()
E il risultato è Fri Dec 18 23:00:00 GMT+02:00 2020invece di Dec 19. Con alcune date funziona bene, con altre il risultato data-1, immagino che il problema sia con il numero di giorni nel mese, ma non plusDays()lo considera?
Risposte
Con alcune date funziona bene, con altre il risultato data-1, immagino che il problema sia con il numero di giorni nel mese, ma plusDays () non lo considera?
Lo considera. Il problema con le due stringhe di data e ora che hai menzionato è che appartengono a diversi Zone-Offset (la prima è con UTC + 3 e la seconda con UTC + 2). Di seguito viene illustrato come farlo con lo stesso offset di zona.
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss zZ yyyy");
DateTime dateTime = DateTime.parse("Thu Aug 06 00:00:00 GMT+03:00 2020", formatter);
System.out.println(dateTime);
// With Zone-Offset of UTC+2
System.out.println(dateTime.withZone(DateTimeZone.forOffsetHours(2)));
// Add 103 days
DateTime dateTimeAfter103Days = dateTime.plusDays(103);
System.out.println(dateTimeAfter103Days);
System.out.println(dateTime.withZone(DateTimeZone.forOffsetHours(2)));
}
}
Produzione:
2020-08-05T21:00:00.000Z
2020-08-05T23:00:00.000+02:00
2020-11-16T21:00:00.000Z
2020-08-05T23:00:00.000+02:00
Ti consiglio di utilizzare la moderna java.time API data-ora e l'API di formattazione corrispondente (pacchetto, java.time.format). Ulteriori informazioni sulla moderna API data-ora da Trail: Date Time . Se il tuo livello di API Android non è ancora conforme a Java8, controlla Come utilizzare ThreeTenABP in Android Project e le API Java 8+ disponibili tramite desugaring .
La tabella seguente mostra una panoramica delle moderne classi di data e ora :
Con la moderna API data-ora:
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
// Define formatter for your date-time string
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O u");
// Parse the given date0-time string into OffsetDateTime object
OffsetDateTime dateTime = OffsetDateTime.parse("Thu Aug 06 00:00:00 GMT+03:00 2020", formatter);
System.out.println(dateTime);
// Add 103 days to the OffsetDateTime object
OffsetDateTime dateTimeAfter103Days = dateTime.plusDays(103);
System.out.println(dateTimeAfter103Days);
}
}
Produzione:
2020-08-06T00:00+03:00
2020-11-17T00:00+03:00
In alternativa,
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
// Define formatter for your date-time string
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy");
// If you do not need Zone Id or Zone Offset information, you can go for
// LocalDateTime
LocalDateTime dateTime = LocalDateTime.parse("Thu Aug 06 00:00:00 GMT+03:00 2020", formatter);
System.out.println(dateTime);
// You can convert LocalDateTime object into an OffsetDateTime by applying the
// Zone-Offset e.g. the following line applies UTC+03:00 hours to LocalDateTime
OffsetDateTime odt = dateTime.atOffset(ZoneOffset.ofHours(3));
System.out.println(odt);
// Add 103 days to the LocalDateTime object
LocalDateTime dateTimeAfter103Days = dateTime.plusDays(103);
System.out.println(dateTimeAfter103Days);
odt = dateTimeAfter103Days.atOffset(ZoneOffset.ofHours(3));
System.out.println(odt);
}
}
Produzione:
2020-08-06T00:00
2020-08-06T00:00+03:00
2020-11-17T00:00
2020-11-17T00:00+03:00
Potresti usarlo java.timeed è supportato nelle API Android inferiori, perché ora c'è l' API desugaring in Android .
C'è una classe sensibile alla zona ( java.time.ZonedDateTime) e una classe consapevole dell'offset ( java.time.OffsetDateTime), ma il tuo esempio Stringcontiene solo un offset da GMT / UTC. Ecco perché OffsetDateTimeuserei un che analizza il momento esatto nel tempo e poi aggiunge un giorno.
Ecco un semplice esempio che definisce un formattatore che analizza il dato Stringe lo usa per l'output:
public static void main(String[] args) {
// example String
String date = "Fri Dec 18 23:00:00 GMT+02:00 2020";
// create a formatter that is able to parse and output the String
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss OOOO uuuu",
Locale.ENGLISH);
// parse the String using the formatter defined above
OffsetDateTime odt = OffsetDateTime.parse(date, dtf);
System.out.println("OffsetDateTime parsed is\t" + odt.format(dtf));
// add a day to the date part
OffsetDateTime dayLater = odt.plusDays(1);
System.out.println("Adding a day results in\t\t" + dayLater.format(dtf));
}
Questo produce
OffsetDateTime parsed is Fri Dec 18 23:00:00 GMT+02:00 2020
Adding a day results in Sat Dec 19 23:00:00 GMT+02:00 2020
Se sei interessato a trasmettere solo le date (nessuna parte temporale o offset), c'è un'altra cosa utile in quelle classi, che è la facile estrazione della parte data o tempo. Puoi fare quanto segue con OffsetDateTime, ad esempio:
// extract the part that only holds information about day of month, month of year and year
LocalDate dateOnly = odt.toLocalDate();
// print the default format (ISO standard)
System.out.println(dateOnly);
// or define and use a totally custom format
System.out.println(dateOnly.format(
DateTimeFormatter.ofPattern("EEEE, 'the' dd. 'of' MMMM uuuu",
Locale.ENGLISH)
)
);
Ciò sarebbe risultato
2020-12-18
Friday, the 18. of December 2020
Nel caso tu abbia a che fare con a DatePicker datePicker, puoi ricevere i valori selezionati da getYear(), getMonth()e getDayOfMonth(), quindi creare un file
LocalDate localDate = LocalDate.of(datePicker.getYear(),
datePicker.getMonth(),
datePicker.getDayOfMonth());
e poi aggiungi semplicemente un giorno entro localDate.plusDays(1);