Pregunta

Java 8 has a whole new library for dates and times in the package java.time which is very welcome thing to anyone who has had to use JodaTime before or hassle with making it's own date processing helper methods. Many classes in this package represent timestamps and have helper methods like getHour() to get hours from timestamp, getMinute() to get minutes from timestamp, getNano() to get nanos from timestamp etc...

I noticed that they don't have a method called getMillis() to get the millis of the time stamp. Instead one would have to call method get(ChronoField.MILLI_OF_SECOND). To me it seems like an inconsistency in the library. Does anyone know why such a method is missing, or as Java 8 is still in development is there a possibility that it will be added later?

https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html

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

Example of this kind of class:
https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html

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

¿Fue útil?

Solución

JSR-310 is based on nanoseconds, not milliseconds. As such, the minimal set of sensible methods are based on hour, minutes, second and nanosecond. The decision to have a nanosecond base was one of the original decisions of the project, and one that I strongly believe to be correct.

Adding a method for millis would overlap that of nanosecond is a non-obvious way. Users would have to think about whether the nano field was nano-of-second or nano-of-milli for example. Adding a confusing additional method is not desirable, so the method was omitted. As pointed out, the alternative get(MILLI_OF_SECOND) is available.

FWIW, I would oppose adding the getMillis() method in the future.

Otros consejos

Before being part of openJDK, threeten was on github and before that it was on sourceforge. Back then, Stephen Colebourne, who is a specification lead on jsr-310, made a survey tha you can still find on the sourceforge site.

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

only 6.23% chose answer #4 and among them approximately 15% asked for a getMillis(), i.e. less than 1% of the total votes.

That is probably why there was no getMillis in the first place and I could not find anything related on the openjdk mailing list so the matter was apparently not discussed afterwards.

The classes that represent unambiguous UTC times (those are Instant, OffsetDateTime, ZonedDateTime) have two helper methods for accessing the absolute offset from the Java epoch, i.e. what you call 'millisecond time' in the java.util.Date, which you could use to get at milliseconds

long getEpochSecond()
int getNano()

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

Some reasons as to why this has been chosen instead of long getEpochMillis() were discussed on the jsr 310 mailing list, some of which I've extracted for convenience:

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

I have a feeling that another reason was to intentionally make it hard to convert from java.util.Date to JSR310 classes, hoping that developers would try to understand the differences between the various options and not just blindly (mis)use the new classes.

As to why the LocalDateTime class doesn't have those methods - they can't possibly exist there because LocalDateTime is not tied to the UTC timeline until you decide which zone you're in or what your UTC offset is, at which point you have yourself an OffsetDateTime or ZonedDateTime (both of which have the needed methods).

Alternatively, you could define you own LOCAL_EPOCH constant to 1970-01-01T00:00:00 and then do a MILLIS.between(LOCAL_EPOCH, localTime) to get some sort of duration in milliseconds. This value, however, will not be compatible with any value returned by System.currentTimeMilliseconds() or java.util.Date.getTime(), unless of course you define your local time to be UTC time; but in this case you might as well use Instant directly or OffsetDateTime with ZoneOffset.UTC.

Licenciado bajo: CC-BY-SA con atribución
scroll top