Skip to content

Commit

Permalink
Added BoundedTime, timestamp + timespan
Browse files Browse the repository at this point in the history
  • Loading branch information
swalker2m committed Oct 8, 2024
1 parent bfb3396 commit 94e7021
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package lucuma.core.model.sequence

import cats.Order
import cats.derived.*
import lucuma.core.enums.ScienceBand

/**
* Pairs an optional science band with a categorized time. Because programs
* may have observations in distinct bands, at the top-level we must group by
* band.
*/
case class BandedTime(
band: Option[ScienceBand],
time: CategorizedTime
) derives Order

object BandedTime:
val Empty: BandedTime = BandedTime(None, CategorizedTime.Zero)
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import java.time.format.DateTimeParseException
import java.time.temporal.ChronoField
import java.time.temporal.ChronoUnit.MICROS
import java.util.Locale
import scala.annotation.targetName

/**
* Timestamp is an Instant truncated and limited to fit in a database
Expand Down Expand Up @@ -138,6 +139,22 @@ object Timestamp {
def plusSecondsOption(secondsToAdd: Long): Option[Timestamp] =
fromInstant(timestamp.plusSeconds(secondsToAdd))

/**
* Adds the given amount of time to the Timestamp, producing a new
* Timestamp that far in the future. The value is capped at Timestamp.Max.
*/
@targetName("boundedAdd")
def +|(time: TimeSpan): Timestamp =
plusMicrosOption(time.toMicroseconds).getOrElse(Timestamp.Max)

/**
* Subtracts the given amount of time from the Timestamp, producing a new
* Timestamp that far in the past. The value is limited at Timestamp.Min.
*/
@targetName("boundedSubtract")
def -|(time: TimeSpan): Timestamp =
plusMicrosOption(- time.toMicroseconds).getOrElse(Timestamp.Min)

/**
* The timestamp interval between this timestamp and the given
* `endExclusive` timestamp. If `endExclusive` comes before this
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package lucuma.core.model.sequence
package arb

import lucuma.core.enums.ScienceBand
import lucuma.core.util.arb.ArbEnumerated
import org.scalacheck.Arbitrary
import org.scalacheck.Arbitrary.*
import org.scalacheck.Cogen

trait ArbBandedTime:
import ArbCategorizedTime.given
import ArbEnumerated.given

given Arbitrary[BandedTime] =
Arbitrary {
arbitrary[(Option[ScienceBand], CategorizedTime)].map(BandedTime.apply)
}

given Cogen[BandedTime] =
Cogen[(Option[ScienceBand], CategorizedTime)].contramap(b => (b.band, b.time))

object ArbBandedTime extends ArbBandedTime
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package lucuma.core.model.sequence

import cats.kernel.laws.discipline.*
import lucuma.core.model.sequence.arb.ArbBandedTime
import munit.DisciplineSuite

final class BandedTimeSuite extends DisciplineSuite:

import ArbBandedTime.given

checkAll("Order[BandedTime]", OrderTests[BandedTime].order)
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import cats.syntax.option.*
import cats.syntax.order.*
import lucuma.core.arb.ArbTime.given
import lucuma.core.optics.laws.discipline.*
import lucuma.core.util.arb.ArbTimeSpan.given
import lucuma.core.util.arb.ArbTimestamp
import lucuma.core.util.arb.ArbTimestamp.given
import monocle.law.discipline.PrismTests
Expand Down Expand Up @@ -96,4 +97,14 @@ class TimestampSuite extends DisciplineSuite {
assert(t0 < t1 == ti.nonEmpty)
}
}

property("boundedAdd") {
forAll: (t: Timestamp, ts: TimeSpan) =>
assertEquals(t +| ts, t.plusMicrosOption(ts.toMicroseconds).getOrElse(Timestamp.Max))
}

property("boundedSubtract") {
forAll: (t: Timestamp, ts: TimeSpan) =>
assertEquals(t -| ts, t.plusMicrosOption(- ts.toMicroseconds).getOrElse(Timestamp.Min))
}
}

0 comments on commit 94e7021

Please sign in to comment.