-
Notifications
You must be signed in to change notification settings - Fork 18
/
ZonedDateTimeScheduler.scala
57 lines (48 loc) · 1.92 KB
/
ZonedDateTimeScheduler.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
* Copyright 2018-2023 fs2-cron contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.timepit.fs2cron
import cats.effect.{Sync, Temporal}
import cats.syntax.all._
import java.time.temporal.ChronoUnit
import java.time.{Instant, ZoneId, ZoneOffset, ZonedDateTime}
import java.util.concurrent.TimeUnit
import scala.concurrent.duration.FiniteDuration
abstract class ZonedDateTimeScheduler[F[_], Schedule](zoneId: F[ZoneId])(implicit
override val temporal: Temporal[F]
) extends Scheduler[F, Schedule] {
def next(from: ZonedDateTime, schedule: Schedule): F[ZonedDateTime]
override def fromNowUntilNext(schedule: Schedule): F[FiniteDuration] =
now.flatMap { from =>
next(from, schedule).map { to =>
val durationInMillis = from.until(to, ChronoUnit.MILLIS)
FiniteDuration(durationInMillis, TimeUnit.MILLISECONDS)
}
}
private val now: F[ZonedDateTime] =
(temporal.realTime, zoneId).mapN((d, z) => Instant.EPOCH.plusNanos(d.toNanos).atZone(z))
}
object ZonedDateTimeScheduler {
trait Companion[Schedule] {
final def systemDefault[F[_]](implicit
temporal: Temporal[F],
F: Sync[F]
): Scheduler[F, Schedule] =
from(F.delay(ZoneId.systemDefault()))
final def utc[F[_]](implicit F: Temporal[F]): Scheduler[F, Schedule] =
from(F.pure(ZoneOffset.UTC))
def from[F[_]](zoneId: F[ZoneId])(implicit F: Temporal[F]): Scheduler[F, Schedule]
}
}