Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Period with hours, minutes and seconds [closed]

Tags:

java

jsr310

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.

like image 482
Philippe Marschall Avatar asked Jan 04 '16 16:01

Philippe Marschall


2 Answers

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.

like image 158
kostya Avatar answered Sep 20 '22 15:09

kostya


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]
like image 45
steffen Avatar answered Sep 18 '22 15:09

steffen