问题
I have need for an interval data type representing years, months, weeks, days, hours, minutes, seconds. The first three (years, months, days) can be done with Period
and the last three (hours, minutes, seconds) can be done with Duration
however none of them seem to do both. Ideally I'd like to avoid having to implement a custom TemporalAmount
.
回答1:
There is a reason why there is no such type. There is no well defined time intervals such as "day", "month" or "year":
- day is not always 24 hours (depends on DST, timezone and leap seconds)
- every month has different number of days
- leap years have 366 days
Even if you implement a custom TemporalAmount there is high chance that your code will be incorrect in some cases. If you state your actual requirements you might get a better answer.
回答2:
The reason why no such class exists is that there are actually two different concepts of time: (1) a fixed number of (e. g.) seconds which is called a Duration in Java world or (2) a let's say variable number of seconds which is called a Period. The period tries to abstract from changing lengths of
- minutes (leap seconds, this isn't implemented)
- days (daylight savings)
- months (28, 29, 30, 31 days)
- years (leap years)
That's why Period
stores days, months, years and Duration
just seconds and nano seconds. Yes, they do share the same time unit DAY
, but a Duration
day is considered to be 24h and directly converted to seconds.
The period between 2016-02-01 and 2016-03-01 is 1 month. The duration is 696 hours, not 720 hours. You can say that a duration of a period may change.
So you need to define your application. Do you want a duration (fixed amount of seconds) or a period (something that "happens" once in a year)?
Here's an example how they do compute different instants after a daylight savings change:
Duration oneDayDuration = Duration.ofDays(1);
Period oneDayPeriod = Period.ofDays(1);
ZonedDateTime beforeChange = Instant.parse("2015-10-25T00:00:00.00Z").atZone(ZoneId.of("Europe/Berlin"));
System.out.println(beforeChange);
System.out.println(oneDayDuration.addTo(beforeChange));
System.out.println(oneDayPeriod.addTo(beforeChange));
will print
2015-10-25T02:00+02:00[Europe/Berlin]
2015-10-26T01:00+01:00[Europe/Berlin]
2015-10-26T02:00+01:00[Europe/Berlin]
来源:https://stackoverflow.com/questions/34595133/period-with-hours-minutes-and-seconds