Reputation: 4604
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
.
Upvotes: 7
Views: 7288
Reputation: 17048
The reason why there is no such class is that there are actually two different concepts of a time span. In Java, these two concepts are implemented in two different classes:
While a duration has always the same time length, the actual time length of a period depends on when and where it is applied. A period of one month can be 28, 29, 30 or 31 days - it's actual duration depends on the context. A period of one day may have 23, 24 or 25 hours (and more) when there's daylight savings in a given timezone.
Here's a small and likely incomplete list of factors that have an effect on the conversion of a period to a duration.
That's why Period
stores days, months and years seperately and Duration
just seconds (and nano seconds). They do share the same time unit DAY
, but a Duration
day is considered to be 24h and is directly converted to 86,400 seconds.
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, twice per month, every day at 2:00 am)?
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]
Upvotes: 5
Reputation: 9569
There is a reason why there is no such type. There is no well defined time intervals such as "day", "month" or "year":
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.
Upvotes: 6