I want to use java.time.LocalDate
and java.time.LocalDateTime
with an implicit Ordered
like:
val date1 = java.time.LocalDate.of(2000, 1, 1)
val date2 = java.time.LocalDate.of(2010, 10, 10)
if (date1 < date2) ...
import scala.math.Ordering.Implicits._
doesn't work, because LocalDate
inherits from Comparable<ChronoLocalDate>
instead of Comparable<LocalDate>
.
How can I write my own imlicit Orderd to use <, <=, >, >= operators/methods to compare LocalDate
's?
Edit:
I found a way with use of an implicit class:
import java.time.{LocalDate}
object MyDateTimeUtils {
implicit class MyLocalDateImprovements(val ld: LocalDate)
extends Ordered[LocalDate] {
def compare(that: LocalDate): Int = ld.compareTo(that)
}
}
// Test
import MyDateTimeUtils._
val d1 = LocalDate.of(2016, 1, 1)
val d2 = LocalDate.of(2017, 2, 3)
if (d1 < d2) println("d1 is less than d2")
But I would prefer a way like Scala is doing for all Java classes which implements Comparable<T>
. You just have to
import scala.math.Ordering.Implicits._
in your code. Scala implements it like:
implicit def ordered[A <% Comparable[A]]: Ordering[A] = new Ordering[A] {
def compare(x: A, y: A): Int = x compareTo y
}
But unfortunately LocalDate
implements Comparable<ChronoLocalDate>
instead of Comparable<LocalDate>
. I couldn't find a way to modify the above implicit ordered method to fit with LocalDate
/Comparable<ChronoLocalDate>
. Any idea?
You can use Ordering.by
to create ordering for any type, given a function from that type to something that already has an Ordering - in this case, to Long
:
implicit val localDateOrdering: Ordering[LocalDate] = Ordering.by(_.toEpochDay)