Sono nuovo del pacchetto temporale Java 8 e sto cercando di comprenderlo meglio e mi assicuro di utilizzarlo al meglio.
C'è una ragione specifica per cui LocalDateTime truncatedTo (TemporalUnit) non non supporta ChronoUnit valori dei giorni passati.
Penso di aver messo insieme un'implementazione di successo di tale metodo, ma ho avuto dubbi sulla divisione intera e sulle anomalie aritmetiche in virgola mobile. È qualcosa di cui dovrei occuparmi?
Inoltre, li capisco rendendo LocalDateTime e LocalDate sia immutable Objects
che significa che LocalDateTime
non può estendere LocalDate
, ma Non vedo che condividono un'interfaccia comune per tutti i componenti della data di LocalDateTime
, rendendo difficile capire perché l'abbiano fatto. Le uniche interfacce comuni che posso vedere sono Temporal , TemporalAccessor e TemporalAdjuster .
Se condividevano un'interfaccia comune per i componenti di data e ora, allora potresti facilmente scrivere codice nell'interfaccia che può utilizzare sia LocalDate
che LocalDateTime
istanze per cose che modificano la data senza preoccuparsi della parte temporale di l'istanza durante il runtime. C'è una buona ragione per non farlo, o mi manca qualcosa qui?
Ecco la mia implementazione del suddetto modo di troncare LocalDateTime
oltre DAYS
:
public static LocalDateTime truncateDate(LocalDateTime date, ChronoUnit unit) {
LocalDateTime truncatedDate = null;
// LocalDateTime only supports truncatedTo(TemporalUnit) up to ChronoUnit.DAYS.
switch (unit) {
case NANOS:
case MICROS:
case MILLIS:
case SECONDS:
case MINUTES:
case HOURS:
case HALF_DAYS:
case DAYS:
truncatedDate = date.truncatedTo(unit);
System.out.println("date = '" + String.valueOf(date) + "', unit = '" + String.valueOf(unit) + "', truncatedDate = '" + String.valueOf(truncatedDate) + "'.");
return truncatedDate; // break;
default: // else; we can't use LocalDateTime.truncatedTo(TemporalUnit) past ChronoUnit.DAYS, so lets truncate up to DAYS and continue from there.
truncatedDate = date.truncatedTo(ChronoUnit.DAYS);
break;
}
int year = 0;
switch (unit) {
case WEEKS:
truncatedDate = truncatedDate.plus(DayOfWeek.MONDAY.getValue()-truncatedDate.getDayOfWeek().getValue(), ChronoUnit.DAYS); // subtract days to the last Monday.
System.out.println("date = '" + String.valueOf(date) + "', unit = '" + String.valueOf(unit) + "', truncatedDate = '" + String.valueOf(truncatedDate) + "'.");
return truncatedDate; // break;
case MONTHS:
truncatedDate = truncatedDate.with(TemporalAdjusters.firstDayOfMonth());
System.out.println("date = '" + String.valueOf(date) + "', unit = '" + String.valueOf(unit) + "', truncatedDate = '" + String.valueOf(truncatedDate) + "'.");
return truncatedDate; // break;
case YEARS:
truncatedDate = truncatedDate.with(TemporalAdjusters.firstDayOfYear());
System.out.println("date = '" + String.valueOf(date) + "', unit = '" + String.valueOf(unit) + "', truncatedDate = '" + String.valueOf(truncatedDate) + "'.");
return truncatedDate; // break;
case DECADES:
truncatedDate = truncatedDate.with(TemporalAdjusters.firstDayOfYear());
year = truncatedDate.getYear();
int decadeYear = (year/10)*10; // int division rounds down, same as trunc(year/10)*10.
truncatedDate = truncatedDate.plus(decadeYear-year, ChronoUnit.YEARS);
System.out.println("date = '" + String.valueOf(date) + "', unit = '" + String.valueOf(unit) + "', truncatedDate = '" + String.valueOf(truncatedDate) + "'.");
return truncatedDate; // break;
case CENTURIES:
truncatedDate = truncatedDate.with(TemporalAdjusters.firstDayOfYear());
year = truncatedDate.getYear();
int centuryYear = (year/100)*100; // int division rounds down, same as trunc(year/100)*100.
truncatedDate = truncatedDate.plus(centuryYear-year, ChronoUnit.YEARS);
System.out.println("date = '" + String.valueOf(date) + "', unit = '" + String.valueOf(unit) + "', truncatedDate = '" + String.valueOf(truncatedDate) + "'.");
return truncatedDate; // break;
case MILLENNIA:
truncatedDate = truncatedDate.with(TemporalAdjusters.firstDayOfYear());
year = truncatedDate.getYear();
int millenniumYear = (year/1000)*1000; // int division rounds down, same as trunc(year/1000)*1000.
truncatedDate = truncatedDate.plus(millenniumYear-year, ChronoUnit.YEARS);
System.out.println("date = '" + String.valueOf(date) + "', unit = '" + String.valueOf(unit) + "', truncatedDate = '" + String.valueOf(truncatedDate) + "'.");
return truncatedDate; // break;
default: // ChronoUnit.ERA || ChronoUnit.FOREVER:
throw new UnsupportedTemporalTypeException("Unable to truncate to unit = '" + String.valueOf(unit) + "', not well supported!");
} // all switch paths return or throw an exception.
}
Con il seguente risultato da un programma di test main
:
$ java Main
date = '2016-08-26T10:51:58.828'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Nanos'.
date = '2016-08-26T10:51:58.828', unit = 'Nanos', truncatedDate = '2016-08-26T10:51:58.828'.
=> result = '2016-08-26T10:51:58.828'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Micros'.
date = '2016-08-26T10:51:58.828', unit = 'Micros', truncatedDate = '2016-08-26T10:51:58.828'.
=> result = '2016-08-26T10:51:58.828'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Millis'.
date = '2016-08-26T10:51:58.828', unit = 'Millis', truncatedDate = '2016-08-26T10:51:58.828'.
=> result = '2016-08-26T10:51:58.828'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Seconds'.
date = '2016-08-26T10:51:58.828', unit = 'Seconds', truncatedDate = '2016-08-26T10:51:58'.
=> result = '2016-08-26T10:51:58'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Minutes'.
date = '2016-08-26T10:51:58.828', unit = 'Minutes', truncatedDate = '2016-08-26T10:51'.
=> result = '2016-08-26T10:51'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Hours'.
date = '2016-08-26T10:51:58.828', unit = 'Hours', truncatedDate = '2016-08-26T10:00'.
=> result = '2016-08-26T10:00'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'HalfDays'.
date = '2016-08-26T10:51:58.828', unit = 'HalfDays', truncatedDate = '2016-08-26T00:00'.
=> result = '2016-08-26T00:00'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Days'.
date = '2016-08-26T10:51:58.828', unit = 'Days', truncatedDate = '2016-08-26T00:00'.
=> result = '2016-08-26T00:00'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Weeks'.
date = '2016-08-26T10:51:58.828', unit = 'Weeks', truncatedDate = '2016-08-22T00:00'.
=> result = '2016-08-22T00:00'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Months'.
date = '2016-08-26T10:51:58.828', unit = 'Months', truncatedDate = '2016-08-01T00:00'.
=> result = '2016-08-01T00:00'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Years'.
date = '2016-08-26T10:51:58.828', unit = 'Years', truncatedDate = '2016-01-01T00:00'.
=> result = '2016-01-01T00:00'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Decades'.
date = '2016-08-26T10:51:58.828', unit = 'Decades', truncatedDate = '2010-01-01T00:00'.
=> result = '2010-01-01T00:00'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Centuries'.
date = '2016-08-26T10:51:58.828', unit = 'Centuries', truncatedDate = '2000-01-01T00:00'.
=> result = '2000-01-01T00:00'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Millennia'.
date = '2016-08-26T10:51:58.828', unit = 'Millennia', truncatedDate = '2000-01-01T00:00'.
=> result = '2000-01-01T00:00'.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Eras'.
=> exception = 'UnsupportedTemporalTypeException' => {Unable to truncate to unit = 'Eras', not well supported!}.
Truncating date = '2016-08-26T10:51:58.828' by unit = 'Forever'.
=> exception = 'UnsupportedTemporalTypeException' => {Unable to truncate to unit = 'Forever', not well supported!}.
Sembra che tutto funzioni come previsto, mi chiedevo solo se l'implementazione non è raccomandata e perché la libreria predefinita non la supporta se lo è?
Grazie!