Libraries for integration between the java.time
classes and common Scala libraries.
intime-core
provides integration with the core Scala libraryintime-cats
provides instances for the Cats FP libraryintime-argonaut
provides encoders and decoders for the Argonaut JSON libraryintime-scalacheck
provides instances for the Scalacheck property-based-testing library
Add the following to your build.sbt
file:
val intimeVersion = "2.2.0"
libraryDependencies += "au.id.tmm.intime" %% "intime-core" % intimeVersion
libraryDependencies += "au.id.tmm.intime" %% "intime-cats" % intimeVersion // Cats integration
libraryDependencies += "au.id.tmm.intime" %% "intime-argonaut" % intimeVersion // Argonaut integration
libraryDependencies += "au.id.tmm.intime" %% "intime-scalacheck" % intimeVersion % Test // Scalacheck integration
intime-core
adds integrations with the Scala standard library. Add it to your project with:
libraryDependencies += "au.id.tmm.intime" %% "intime-core" % "1.0.2"
intime-core
provides Ordering
instances for all classes in the java.time
package for which an ordering can be
defined. This includes the most common classes like Instant
and LocalDate
.
import java.time._
import au.id.tmm.intime.std.implicits._
val dates: List[LocalDate] = List(
LocalDate.of(2003, 3, 23),
LocalDate.of(2015, 3, 29),
LocalDate.of(2007, 4, 28),
)
dates.sorted // Sorts list of dates
Period
presents some problems when it comes to defining an Ordering
instance, as any two instances cannot
necessarily be compared (is 1 month longer or shorter than 30 days?). intime-core
provides a PartialOrdering
for
each, handling those cases where an ordering can be computed.
intime-core
provides overloaded operators for arithmetic and comparison operations on java.time
classes:
import java.time._
import au.id.tmm.intime.std.implicits._
LocalDate.of(1999, 6, 20) + Period.ofDays(3) // 1999-06-23
Instant.EPOCH - Duration.ofSeconds(5) // 1969-12-31T23:59:55Z
Period.ofDays(5) * 3 // P15D
- Duration.ofHours(42) // PT-42H
Duration.ofDays(30) / 10 // P3D
Instant.MAX > Instant.EPOCH // true
intime-cats
adds integrations with Cats. Add it to your project with:
libraryDependencies += "au.id.tmm.intime" %% "intime-cats" % "1.0.2"
All instances are tested with discipline.
intime-cats
provides Hash
and Show
instances for all classes in java.time
.
import java.time._
import au.id.tmm.intime.cats.implicits._
import cats.syntax.show._
import cats.syntax.eq._
LocalDate.of(1999, 6, 20).show // 1999-06-20
Instant.EPOCH === Instant.EPOCH // true
intime-cats
uses the orderings in intime-core
to define Cats Order
instances (PartialOrder
for Period
).
import java.time._
import au.id.tmm.intime.cats.implicits._
import cats.syntax.partialOrder._
LocalDate.of(2003, 3, 23) < LocalDate.of(2015, 3, 29) // true
Period.ofYears(1) < Period.ofMonths(13) // true
Period.ofDays(30) partialCompare Period.ofMonths(1) // NaN
import java.time._
import au.id.tmm.intime.cats.implicits._
import cats.syntax.group._
Duration.ofDays(1) |+| Duration.ofHours(2) // P1DT2H
Duration.ofDays(1) |-| Duration.ofHours(2) // PT22H
intime-scalacheck
adds integrations with Scalacheck. Add it to your project
with:
libraryDependencies += "au.id.tmm.intime" %% "intime-scalacheck" % "1.0.2" % "test"
intime-scalacheck
provides instances of Arbitrary
for all classes in java.time
. These can be used to generate
arbitrary instances for property-based testing.
import java.time._
import au.id.tmm.intime.scalacheck._
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks._
forAll { localDate: LocalDate =>
assert(localDate.plusDays(1) isAfter localDate)
}
intime-scalacheck
provides generators for "sensible" values of java.time
classes. The generated values are all
between 1900 and 2100, allowing property-based-tests that don't have to worry about peculiarities like
year zero or durations that overflow.
import java.time._
import au.id.tmm.intime.scalacheck._
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks._
forAll(genSensibleLocalDate) { localDate: LocalDate =>
assert(localDate.getYear >= 1900)
}
intime-scalacheck
provides instances of Choose
, which let you define your own generators that produce values within
a range.
import java.time._
import au.id.tmm.intime.scalacheck._
import org.scalacheck.Gen
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks._
val rangeGenerator: Gen[LocalDate] = Gen.choose(
min = LocalDate.of(2019, 5, 30),
max = LocalDate.of(2019, 7, 14),
)
forAll(rangeGenerator) { localDate: LocalDate =>
assert(localDate.getYear == 2019)
}
intime-scalacheck
provides instances for Shrink
, which Scalacheck will use to try to identify the smallest value for
which a test fails. These are used automatically as long as you have the import:
import au.id.tmm.intime.scalacheck._
intime-argonaut
provides integration with the Argonaut library for JSON
handling. Add it to your project with:
libraryDependencies += "au.id.tmm.intime" %% "intime-argonaut" % "1.0.2"
intime-argonaut
defines EncodeJson
and DecodeJson
instances for all classes in the java.time
package. They are
encoded and decoded to JSON strings according to the most obvious format (see
StandardCodecs
.
import java.time._
import au.id.tmm.intime.argonaut._
import argonaut.Argonaut._
LocalDate.of(2019, 7, 14).asJson // jString("2019-07-14")
jString("2019-07-14").as[LocalDate] // DecodeResult.ok(LocalDate.of(2019, 7, 14))
intime-argonaut
allows for the definition of custom EncodeJson
and DecodeJson
instances using instances of
DateTimeFormatter
.
import java.time._
import au.id.tmm.intime.argonaut._
import argonaut.Argonaut._
val formatter = DateTimeFormatter.ofPattern("MM-dd-uuuu")
implicit val customCodec = DateTimeFormatterCodecs.localDateCodecFrom(formatter)
LocalDate.of(2019, 7, 14).asJson // jString("07-14-2019")
jString("07-14-2019").as[LocalDate] // DecodeResult.ok(LocalDate.of(2019, 7, 14))
- In Java 8, the standard codec for
ZonedDateTime
will fail to decode when the zone isGMT
. This is fixed in Java 11. - In Java 8, the standard codec for
Duration
will drop the negative sign for durations between 0 and -1 seconds. This is fixed in Java 11.