From df1a2f7fcbdd85ac84162cf8eae8cdb6bb25cbb5 Mon Sep 17 00:00:00 2001 From: Sergey Nastich Date: Fri, 24 Aug 2018 13:41:27 -0400 Subject: Migration to `java.time.Instant` and `java.time.LocalDate`: Part 1 (#200) * Add semi-backwards-compatible JSON formats and path matchers for java.time.Instant and java.time.LocalDate * Use `Clock` in `ApplicationContext` instead of `TimeProvider`, deprecate `TimeProvider` * Add `ChangeableClock` in time package for tests * Add generators for instants and LocalDates --- src/main/scala/xyz/driver/core/time.scala | 45 ++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 6 deletions(-) (limited to 'src/main/scala/xyz/driver/core/time.scala') diff --git a/src/main/scala/xyz/driver/core/time.scala b/src/main/scala/xyz/driver/core/time.scala index 6dbd173..c7a32ad 100644 --- a/src/main/scala/xyz/driver/core/time.scala +++ b/src/main/scala/xyz/driver/core/time.scala @@ -1,6 +1,7 @@ package xyz.driver.core import java.text.SimpleDateFormat +import java.time.{Clock, Instant, ZoneId, ZoneOffset} import java.util._ import java.util.concurrent.TimeUnit @@ -40,6 +41,14 @@ object time { cal.setTimeInMillis(millis) date.Date(cal.get(Calendar.YEAR), date.Month(cal.get(Calendar.MONTH)), cal.get(Calendar.DAY_OF_MONTH)) } + + def toInstant: Instant = Instant.ofEpochMilli(millis) + } + + object Time { + implicit def timeOrdering: Ordering[Time] = Ordering.by(_.millis) + + implicit def apply(instant: Instant): Time = Time(instant.toEpochMilli) } /** @@ -127,11 +136,6 @@ object time { } } - object Time { - - implicit def timeOrdering: Ordering[Time] = Ordering.by(_.millis) - } - final case class TimeRange(start: Time, end: Time) { def duration: Duration = FiniteDuration(end.millis - start.millis, MILLISECONDS) } @@ -149,6 +153,18 @@ object time { def textualTime(timezone: TimeZone)(time: Time): String = make(new SimpleDateFormat("MMM dd, yyyy hh:mm:ss a"))(_.setTimeZone(timezone)).format(new Date(time.millis)) + class ChangeableClock(@volatile var instant: Instant, val zone: ZoneId = ZoneOffset.UTC) extends Clock { + + def tick(duration: FiniteDuration): Unit = + instant = instant.plusNanos(duration.toNanos) + + val getZone: ZoneId = zone + + def withZone(zone: ZoneId): Clock = new ChangeableClock(instant, zone = zone) + + override def toString: String = "ChangeableClock(" + instant + "," + zone + ")" + } + object provider { /** @@ -159,17 +175,34 @@ object time { * All the calls to receive current time must be made using time * provider injected to the caller. */ + @deprecated( + "Use java.time.Clock instead. Note that xyz.driver.core.Time and xyz.driver.core.date.Date will also be deprecated soon!", + "0.13.0") trait TimeProvider { def currentTime(): Time + def toClock: Clock + } + + final implicit class ClockTimeProvider(clock: Clock) extends TimeProvider { + def currentTime(): Time = Time(clock.instant().toEpochMilli) + + val toClock: Clock = clock } final class SystemTimeProvider extends TimeProvider { def currentTime() = Time(System.currentTimeMillis()) + + lazy val toClock: Clock = Clock.systemUTC() } + final val SystemTimeProvider = new SystemTimeProvider final class SpecificTimeProvider(time: Time) extends TimeProvider { - def currentTime() = time + + def currentTime(): Time = time + + lazy val toClock: Clock = Clock.fixed(time.toInstant, ZoneOffset.UTC) } + } } -- cgit v1.2.3