Perché le classi java.time di Java 8 mancano di un metodo getMillis ()?

62

Java 8 ha un'intera nuova libreria per le date e le ore nel pacchetto java.time che è una cosa molto gradita a chiunque abbia dovuto usare JodaTime o abbia complicato i propri metodi di helper per l'elaborazione della data. Molte classi in questo pacchetto rappresentano timestamp e hanno metodi di supporto come getHour() per ottenere ore da timestamp, getMinute() per ottenere minuti da timestamp, getNano() per ottenere nanos da timestamp ecc ...

Ho notato che non hanno un metodo chiamato getMillis() per ottenere il millisimosso del timestamp. Invece si dovrebbe chiamare il metodo get(ChronoField.MILLI_OF_SECOND) . A me sembra un'incongruenza nella biblioteca. Qualcuno sa perché manca un tale metodo o, visto che Java 8 è ancora in sviluppo, esiste la possibilità che venga aggiunto in seguito?

link

The classes defined here represent the principal date-time concepts, including instants, durations, dates, times, time-zones and periods. They are based on the ISO calendar system, which is the de facto world calendar following the proleptic Gregorian rules. All the classes are immutable and thread-safe.

Each date time instance is composed of fields that are conveniently made available by the APIs. For lower level access to the fields refer to the java.time.temporal package. Each class includes support for printing and parsing all manner of dates and times. Refer to the java.time.format package for customization options...

Esempio di questo tipo di classe:
link

A date-time without a time-zone in the ISO-8601 calendar system, such as 2007-12-03T10:15:30.

LocalDateTime is an immutable date-time object that represents a date-time, often viewed as year-month-day-hour-minute-second. Other date and time fields, such as day-of-year, day-of-week and week-of-year, can also be accessed. Time is represented to nanosecond precision. For example, the value "2nd October 2007 at 13:45.30.123456789" can be stored in a LocalDateTime...

    
posta Tarmo 24.01.2014 - 16:17
fonte

3 risposte

61

JSR-310 è basato su nanosecondi, non millisecondi. In quanto tale, l'insieme minimo di metodi sensibili si basa su ore, minuti, secondi e nanosecondi. La decisione di avere una base di nanosecondi è stata una delle decisioni originali del progetto, e credo fermamente che sia corretta.

L'aggiunta di un metodo per millis si sovrapporrebbe a quella del nanosecondo è un modo non ovvio. Gli utenti dovrebbero pensare se il campo nano fosse nano-di-secondo o nano-di-milli per esempio. L'aggiunta di un metodo aggiuntivo confuso non è auspicabile, quindi il metodo è stato omesso. Come indicato, è disponibile l'alternativa get(MILLI_OF_SECOND) .

FWIW, vorrei oppormi all'aggiunta del metodo getMillis() in futuro.

    
risposta data 03.02.2014 - 11:51
fonte
20

Prima di far parte di openJDK, threeten era in github e prima era su sourceforge. A quel tempo, Stephen Colebourne, che è una guida delle specifiche su jsr-310, ha fatto un sondaggio che è ancora possibile trovare sul sito sourceforge .

The fourth question on the survey covered the method names for LocalTime:
1) getHourOfDay(), getMinuteOfHour(), getSecondOfMinute(), getNanoOfSecond()
2) getHour(), getMinute(), getSecond(), getNanoOfSecond()
3) getHour(), getMinute(), getSecond(), getNano()
4) another idea

solo il 6,23% ha scelto la risposta n. 4 e tra questi circa il 15% ha chiesto un getMillis() , vale a dire meno dell'1% dei voti totali.

Questo è probabilmente il motivo per cui non c'era nessun getMillis in primo luogo e non sono riuscito a trovare nulla correlato sulla mailing list di openjdk, quindi la questione apparentemente non è stata discussa in seguito.

    
risposta data 25.01.2014 - 18:19
fonte
14

Le classi che rappresentano tempi UTC non ambigui (quelli Instant, OffsetDateTime, ZonedDateTime) hanno due metodi helper per accedere all'offset assoluto dell'epoca Java, ovvero quello che chiami 'millisecond time' in java.util.Date, che potresti usare per ottenere in millisecondi

long getEpochSecond()
int getNano()

1000L*getEpochSecond() + getNano() / 1000000L;

Sono stati discussi alcuni motivi per cui questo è stato scelto al posto di long getEpochMillis() su la mailing list di jsr 310 , alcuni dei quali ho estratto per comodità:

it seems reasonable to suppose that milliseconds precision won't be sufficient. However, anything greater than nanosecond precision seems excessive

...

In order to implement this, my preferred option would be 64 bit long seconds (signed) + 32 bit int nanoseconds (unsigned).

...

I prefer the split to be at the second level as that is the official SI unit of time in science, and the most universally agreed standard.

Splitting at the days level is problematic for instants as it doesn't handle leap seconds. Splitting at the milliseconds level, while integrating slightly better with the rest of Java, seems really rather odd. Plus it loses in the supported range.

Splitting at the second as proposed, gives a range of instants of nanoseconds over 290 billion years. While nobody should ever use that precision over that range of the time-line, I'd suggest its easier to support it than to block it.splitting at the days level is problematic for instants as it doesn't handle leap seconds

Ho la sensazione che un altro motivo fosse quello di rendere intenzionalmente difficile la conversione da classi java.util.Date a JSR310, sperando che gli sviluppatori provassero a capire le differenze tra le varie opzioni e non solo ciecamente (errare) ad usare il nuove classi.

Sul motivo per cui la classe LocalDateTime non ha quei metodi - non possono esistere in questo caso perché LocalDateTime non è legato alla timeline UTC finché non decidi in quale zona ti trovi o quale sia il tuo offset UTC è, a quel punto hai te stesso un OffsetDateTime o ZonedDateTime (entrambi hanno i metodi necessari).

In alternativa, potresti definire la tua LOCAL_EPOCH costante a 1970-01-01T00:00:00 e poi fare un MILLIS.between(LOCAL_EPOCH, localTime) per ottenere una sorta di durata in millisecondi. Questo valore, tuttavia, non sarà compatibile con qualsiasi valore restituito da System.currentTimeMilliseconds() o java.util.Date.getTime() , a meno che, naturalmente, non si definisca l'ora locale come ora UTC; ma in questo caso potresti usare anche Instant direttamente o OffsetDateTime con ZoneOffset.UTC.

    
risposta data 28.01.2014 - 01:34
fonte

Leggi altre domande sui tag