Java 1.8 time functionality

2019-05-11 23:46发布

问题:

So Java 1.8 comes with a whole new (and old) bunch of classes to manage time calculations: java.time.Instant, java.time.LocalTime, java.time.temporal.ChronoUnit, and maybe more...

But why is there no simple way to calculate the time difference between any of these? I would expect "time_later - time_earlier" to be the most used manipulation of time, but this is nowhere to be seen. I cannot subtract one LocalTime from the other and get a new LocalTime; I cannot subtract one Instant from the other to get a new Instant. Instead I have to fiddle with ChronoUnits.between, and long milliseconds and whatnots to achieve this very useful thing.

Why is this? There has to be something going on that I do not get? Or I'm just daft...?

回答1:

Before Java 8, the usual answer to your question was "use Joda Time"

  • http://joda-time.sourceforge.net/faq.html

But the author of Joda Time (Stephen Colebourne) was deeply involved in the new Java 8 time classes and methods. Here are two very good articles:

  • http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html

For your specific question, you might want to consider Java 8 "Duration" and "LocalTime", "LocalDate" and/or "LocalTimeDate" (among other options):

// A duration of 3 seconds and 5 nanoseconds
Duration duration = Duration.ofSeconds(3, 5);
Duration oneDay = Duration.between(today, yesterday);

// Tomorrow
LocalDate tomorrow = LocalDate.now().plusDays(1);

// Yesterday
LocalDate yesterday = LocalDate.now().plusDays(-1);

// before 5 houres and 30 minutes
LocalDateTime dateTime = LocalDateTime.now().minusHours(5).minusMinutes(30);


回答2:

Citation:

"I cannot subtract one LocalTime from the other and get a new LocalTime"

The main reason why this is a fundamentally wrong idea is a physical and mathematical one. Objects like LocalTime or Instant etc. represent a point in time on a time axis. But the difference between two points in time can only be a duration, that is a length in time. Mathematically you have the result in another dimension (point versus line). So the subtraction of two points in time cannot yield another point in time.

But measuring the distance between two points in time in terms of units makes sense, and this operation is supported by JSR-310 (aka java.time-package) as you have correctly seen. By the way, the duration/period-calculations are somehow limited (i.e. no mixed years, days, hours -between-operation like in Joda-Time), but in general between-methods like in class ChronoUnit are not something complex "to fiddle around". It is simple and easily understandable.



回答3:

Methods are provided to calculate the difference between two points in time.

Instant a = Instant.now().minusSeconds(2);
Instant b = Instant.now().plusSeconds(2);

Duration difference = Duration.between(a, b);

long secsBetween1 = a.until(b, ChronoUnit.SECONDS);
long secsBetween2 = ChronoUnit.SECONDS.between(a, b);

Duration is the main object for representing an amount of time, and Duration.between is the a key method for creating it.

ChronoUnit.between and Temporal.until are the slightly lower-level methods that return the difference as a long for a specific unit.



回答4:

You can get the functionality you want by using java.time.Instant.toEpochMilli(). This gets you the same functionality as the old java.util.Date.getTime().

As long as you don't have to deal with time zones, Instant is pretty much all you'll need. Don't get confused by all the rest of the stuff.

If you do have to deal with time zones, a lot of the complexity becomes necessary, though there's some extra complexity in the package due to overgenerality.