commonMain.io.islandtime.ranges.TimePointInterval.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core-metadata Show documentation
Show all versions of core-metadata Show documentation
A multiplatform library for working with dates and times
The newest version!
package io.islandtime.ranges
import io.islandtime.base.TimePoint
import io.islandtime.measures.*
import io.islandtime.measures.internal.minusWithOverflow
import io.islandtime.ranges.internal.*
/**
* A half-open interval of time points.
*/
abstract class TimePointInterval> internal constructor(
override val start: T,
override val endExclusive: T
) : Interval {
override val endInclusive: T
get() = if (hasUnboundedEnd()) endExclusive else endExclusive - 1.nanoseconds
override fun equals(other: Any?): Boolean {
return other is TimePointInterval<*> && (isEmpty() && other.isEmpty() ||
((hasUnboundedStart() && other.hasUnboundedStart()) || start == other.start) &&
((hasUnboundedEnd() && other.hasUnboundedEnd()) || endExclusive == other.endExclusive))
}
override fun hashCode(): Int {
return if (isEmpty()) -1 else (31 * start.hashCode() + endExclusive.hashCode())
}
override fun contains(value: T): Boolean {
return (value >= start || hasUnboundedStart()) && (value < endExclusive || hasUnboundedEnd())
}
override fun isEmpty(): Boolean = start >= endExclusive
/**
* Converts this interval into a [Duration] of the same length.
* @throws UnsupportedOperationException if the interval isn't bounded
*/
fun asDuration(): Duration {
return when {
isEmpty() -> Duration.ZERO
isBounded() -> durationBetween(start, endExclusive)
else -> throwUnboundedIntervalException()
}
}
/**
* The number of 24-hour days in this interval.
* @throws UnsupportedOperationException if the interval isn't bounded
*/
open val lengthInDays: LongDays
get() = when {
isEmpty() -> 0L.days
isBounded() -> daysBetween(start, endExclusive)
else -> throwUnboundedIntervalException()
}
/**
* The number of whole hours in this interval.
* @throws UnsupportedOperationException if the interval isn't bounded
*/
val lengthInHours: LongHours
get() = when {
isEmpty() -> 0L.hours
isBounded() -> hoursBetween(start, endExclusive)
else -> throwUnboundedIntervalException()
}
/**
* The number of whole minutes in this interval.
* @throws UnsupportedOperationException if the interval isn't bounded
*/
val lengthInMinutes: LongMinutes
get() = when {
isEmpty() -> 0L.minutes
isBounded() -> minutesBetween(start, endExclusive)
else -> throwUnboundedIntervalException()
}
/**
* The number of whole seconds in this interval.
* @throws UnsupportedOperationException if the interval isn't bounded
*/
val lengthInSeconds: LongSeconds
get() = when {
isEmpty() -> 0L.seconds
isBounded() -> secondsBetween(start, endExclusive)
else -> throwUnboundedIntervalException()
}
/**
* The number of whole milliseconds in this interval.
* @throws UnsupportedOperationException if the interval isn't bounded
*/
val lengthInMilliseconds: LongMilliseconds
get() = when {
isEmpty() -> 0L.milliseconds
isBounded() -> millisecondsBetween(start, endExclusive)
else -> throwUnboundedIntervalException()
}
/**
* The number of whole microseconds in this interval.
* @throws UnsupportedOperationException if the interval isn't bounded
*/
val lengthInMicroseconds: LongMicroseconds
get() = when {
isEmpty() -> 0L.microseconds
isBounded() -> microsecondsBetween(start, endExclusive)
else -> throwUnboundedIntervalException()
}
/**
* The number of whole nanoseconds in this interval.
* @throws UnsupportedOperationException if the interval isn't bounded
*/
val lengthInNanoseconds: LongNanoseconds
get() = when {
isEmpty() -> 0L.nanoseconds
isBounded() -> nanosecondsBetween(start, endExclusive)
else -> throwUnboundedIntervalException()
}
}
/**
* Checks if this interval contains [value]. This will always return `false` if [value] is `null`.
*/
operator fun > TimePointInterval.contains(value: TimePoint<*>?): Boolean {
return value != null &&
(value >= start || hasUnboundedStart()) &&
(value < endExclusive || hasUnboundedEnd())
}
/**
* Gets the [Duration] between two time points.
*/
fun durationBetween(start: TimePoint, endExclusive: TimePoint): Duration {
val secondDiff = endExclusive.secondsSinceUnixEpoch - start.secondsSinceUnixEpoch
val nanoDiff =
endExclusive.additionalNanosecondsSinceUnixEpoch minusWithOverflow start.additionalNanosecondsSinceUnixEpoch
return durationOf(secondDiff, nanoDiff)
}
/**
* Gets the number of 24-hour days between two time points.
*/
fun daysBetween(start: TimePoint, endExclusive: TimePoint): LongDays {
return secondsBetween(start, endExclusive).inDays
}
/**
* Gets the number of whole hours between two time points.
*/
fun hoursBetween(start: TimePoint, endExclusive: TimePoint): LongHours {
return secondsBetween(start, endExclusive).inHours
}
/**
* Gets the number of whole minutes between two time points.
*/
fun minutesBetween(start: TimePoint, endExclusive: TimePoint): LongMinutes {
return secondsBetween(start, endExclusive).inMinutes
}
/**
* Gets the number of whole seconds between two time points.
* @throws ArithmeticException if the result overflows
*/
fun secondsBetween(start: TimePoint, endExclusive: TimePoint): LongSeconds {
return secondsBetween(
start.secondsSinceUnixEpoch,
start.additionalNanosecondsSinceUnixEpoch,
endExclusive.secondsSinceUnixEpoch,
endExclusive.additionalNanosecondsSinceUnixEpoch
)
}
/**
* Gets the number of whole milliseconds between two time points.
* @throws ArithmeticException if the result overflows
*/
fun millisecondsBetween(
start: TimePoint,
endExclusive: TimePoint
): LongMilliseconds {
return millisecondsBetween(
start.secondsSinceUnixEpoch,
start.additionalNanosecondsSinceUnixEpoch,
endExclusive.secondsSinceUnixEpoch,
endExclusive.additionalNanosecondsSinceUnixEpoch
)
}
/**
* Gets the number of whole microseconds between two time points.
* @throws ArithmeticException if the result overflows
*/
fun microsecondsBetween(
start: TimePoint,
endExclusive: TimePoint
): LongMicroseconds {
return microsecondsBetween(
start.secondsSinceUnixEpoch,
start.additionalNanosecondsSinceUnixEpoch,
endExclusive.secondsSinceUnixEpoch,
endExclusive.additionalNanosecondsSinceUnixEpoch
)
}
/**
* Gets the number of nanoseconds between two time points.
* @throws ArithmeticException if the result overflows
*/
fun nanosecondsBetween(
start: TimePoint,
endExclusive: TimePoint
): LongNanoseconds {
return nanosecondsBetween(
start.secondsSinceUnixEpoch,
start.additionalNanosecondsSinceUnixEpoch,
endExclusive.secondsSinceUnixEpoch,
endExclusive.additionalNanosecondsSinceUnixEpoch
)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy