user3399023
user3399023

Reputation: 47

comparison operators vs comparison methods for ZonedDateTime

using <, >, and == is not always the same as using .isBefore, .isAfter and isEqual when comparing ZonedDateTimes as shown by the following example in Kotlin:

import java.time.ZonedDateTime
import java.time.ZoneId
import java.time.ZoneOffset

fun main() {
    val a = ZonedDateTime.of(2022, 1, 1, 13, 0, 0, 0, ZoneId.of("Europe/Oslo"))
    val b = ZonedDateTime.of(2022, 1, 1, 12, 0, 0, 0, ZoneOffset.UTC)
    println("a = $a")
    println("b = $b")
    println()
    println("a < b: ${a < b}")
    println("a > b: ${a > b}")
    println("a == b: ${a == b}")
    println()
    println("a.isBefore(b): ${a.isBefore(b)}")
    println("a.isAfter(b): ${a.isAfter(b)}")
    println("a.isEqual(b): ${a.isEqual(b)}")
}

Output:

a = 2022-01-01T13:00+01:00[Europe/Oslo]
b = 2022-01-01T12:00Z

a < b: false
a > b: true
a == b: false

a.isBefore(b): false
a.isAfter(b): false
a.isEqual(b): true

What is the difference?

Upvotes: 2

Views: 742

Answers (1)

Sweeper
Sweeper

Reputation: 273978

The operators <, >, >=, <= all translate to compareTo calls, and compareTo does a subtly different thing from isBefore and isAfter.

compareTo:

Compares this date-time to another date-time, including the chronology. The comparison is based first on the instant, then on the local date-time, then on the zone ID, then on the chronology. It is "consistent with equals", as defined by Comparable.

isBefore:

Checks if the instant of this date-time is before that of the specified date-time.

Basically, compareTo compares a lot more things. In other words, it has a lot more "tie-breakers". It even compares the chronology if it has to. On the other hand, isBefore/isAfter only compares the instants that the ZonedDateTimes represents.

The two dates in question, 2022-01-01T13:00+01:00[Europe/Oslo] and 2022-01-01T12:00Z represents the same instant in time, so isBefore and isAfter both return false. On the other hand, compareTo compares the local date times to break the tie. The local date time of 2022-01-01T13:00+01:00[Europe/Oslo] is later than that of 2022-01-01T12:00Z, so compareTo thinks the former is "bigger".

A similar distinction exists between equals (==) and isEqual - equals compares a lot more than isEqual.

Upvotes: 4

Related Questions