Are the both methods equivalent?
version 1:
var diff = Duration.between(begin, end).toHours();
version 2;
var diff = ChronoUnit.HOURS.between(begin, end);
Are there any implicit differences? If yes, which one should I prefer?
Are the both methods equivalent?
version 1:
var diff = Duration.between(begin, end).toHours();
version 2;
var diff = ChronoUnit.HOURS.between(begin, end);
Are there any implicit differences? If yes, which one should I prefer?
Analyzed implementation on open JDK 15.
Duration.between(begin, end).toHours()
Duration.between(begin, end)
first calls
// called with unit of NANOS or SECONDS if first one fails
long until(Temporal endExclusive, TemporalUnit unit);
and then parses the difference to create a Duration
based on nanos that have been calculated (or seconds if calculation of nanos failed):
public static Duration between(Temporal startInclusive, Temporal endExclusive) {
try {
return ofNanos(startInclusive.until(endExclusive, NANOS));
} catch (DateTimeException | ArithmeticException ex) {
long secs = startInclusive.until(endExclusive, SECONDS);
long nanos;
try {
nanos = endExclusive.getLong(NANO_OF_SECOND) - startInclusive.getLong(NANO_OF_SECOND);
if (secs > 0 && nanos < 0) {
secs++;
} else if (secs < 0 && nanos > 0) {
secs--;
}
} catch (DateTimeException ex2) {
nanos = 0;
}
return ofSeconds(secs, nanos);
}
Then you have to call toHours()
which then parses the created Duration
object to return the hours as long.
ChronoUnit.HOURS.between(begin, end)
Directly calls
// in this case it is called with unit of HOURS directly
long until(Temporal endExclusive, TemporalUnit unit);
which directly returns the hours as long
.
I would chose the solution B) as more efficient.
Duration.between(begin, end).toHours()
returns a long
; and ChronoUnit.HOURS.between(begin, end)
returns a long
. This is what the OP asked, as such your answer does not answer anything –
Biron It seems that both methods finally call Temporal#until
Duration#between
\
Temporal#until (used twice but some branching go for another implementation)
ChronoUnit.HOURS#between
\
Temporal#until (it is the only method underlying)
Beware: ChronoUnit.DAYS.between(...)
and Duration.between(...).toDays()
work differently!
... when you use timezones that have to respect daylight saving time:
Duration
ChronoUnits
retuns the accurate amount of daysDuration
is using its hour-calculation and calculates a wrong amount of days in the case of spring-forward DST (with a 'missing' hour)Here is a simple Spock-Test:
def "different behaviour of duration calculation in respect to DST"() {
when: "Interval with spring-forward DST between (March 2024)"
// Start of month
def startLocalTime = LocalDateTime.of(2024, month.value, 1, 0, 0);
def start = ZonedDateTime.of(startLocalTime, ZoneId.of("Europe/Berlin"))
// end of month (exclusive)
def endLocalTime = LocalDateTime.of(2024, month.value + 1, 1, 0, 0);
def end = ZonedDateTime.of(endLocalTime, ZoneId.of("Europe/Berlin"))
then: "creation of that interval was successful"
ChronoUnit.HOURS.between(start, end) == accurateHours
Duration.between(start, end).toHours() == accurateHours
ChronoUnit.DAYS.between(start, end) == accurateDays // ChronoUnits calculation DAYS-duration with respect to DST
Duration.between(start, end).toDays() == accurateDays + dayDifference // Duraction calculates DAYS-duraction based on HOUR-duration
where: "three months"
month || accurateDays | dayDifference | accurateHours
Month.MARCH || 31 | -1 | 31 * 24 - 1 // DST (spring-forward)
Month.JULY || 31 | 0 | 31 * 24
Month.OCTOBER || 31 | 0 | 31 * 24 + 1 // DST (fall-back)
}
© 2022 - 2024 — McMap. All rights reserved.
Duration
and the second one along
(the amount of time between temporal1Inclusive and temporal2Exclusive in terms of this unit; positive if temporal2Exclusive is later than temporal1Inclusive, negative if earlier)? – Commendhours
. – Biron