0

While using Reactive Relational Database Connectivity (R2DBC), I have written a method to convert Interval to Duration in Java, below is the implementation

import io.r2dbc.postgresql.codec.Interval;
import java.time.Duration;
Duration fromInterval(Interval data){
        return data == null ? null : Duration.ofMinutes(data.getMinutes());
}

and I am passing Interval as Interval.of(Duration.ofDays(365)) which is being received as 0 years 0 mons 365 days 0 hours 0 mins 0.0 secs inside function correctly, but the function is returning PT0S, is there something I am doing wrong in conversion from Interval to Duration? Thanks in advance.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 1
    Did you read [the documentation of the `Interval` class](https://javadoc.io/static/io.r2dbc/r2dbc-postgresql/0.8.8.RELEASE/io/r2dbc/postgresql/codec/Interval.html)? – Ole V.V. Feb 28 '23 at 17:56
  • 1
    If you want to handle one year, create the `Interval` from `Period.ofYears(1)` and convert it back to a `Period`, not a `Duration`. For other intervals you may still get surprises if you don’t study the documentation. If you are given an `Interval` created from a `Duration` of days only, according to the docs you can retrieve those days through `daa.getDays()` or `data.getPeriod()`. – Ole V.V. Feb 28 '23 at 17:58
  • My usecase requires conversion of Interval to Duration not Period, this function is written inside a mapper class that is used to map an Interval field in Entity to Duration field in Dto in auto generated MapperImp using @Mapper – Aditya Tiwari Feb 28 '23 at 18:03
  • 1
    Got that. So if the interval contains months and/or years, how do you want them converted? As explained in the docs, a month can be 28, 29, 30 or 31 days long, which the `Duration` class cannot handle. A `Duration` is primarily for hours, minutes, seconds and fraction of second and internally stores only seconds and nanoseconds. – Ole V.V. Feb 28 '23 at 18:06
  • 1
    Would it work for you first to check whether `data.getYears() != 0 || data.getMonths() != 0` and throw an exception if this is the case since you cannot make a proper conversion to `Duration`? After that you may do `Duration.ofDays(data.getDays()).plus(data.getDuration())`. This should handle all other cases. In your example it gives a `Duration` of `PT8760H`. When you convert ot to days using its `toDays` method, you get 365. Does it agree with your requirement? I am still assuming that a day is always 24 hours, which is also not always true, though. – Ole V.V. Feb 28 '23 at 18:16
  • 1
    Understand that the essence of the problem here is that time-of-day (hours-minutes-seconds) is naturally unrelated to the calendar (years-months-days). One is driven by the spin of the earth, the other by the orbit of Earth around the Sun. Add to that the effect of politicians defining and redefining "standard" time. The upshot is that the `java.time.Duration` and `java.time.Period` classes represent those two different conceptions of time, and converting back and forth is problematic (as described in the Comments above by Ole V.V.). That `Interval` class of R2DBC unfortunately mixes the two. – Basil Bourque Feb 28 '23 at 22:35

0 Answers0