///|
/// A wall-clock time with no date and no time zone, such as "07:30".
///
/// Reference:
pub struct PlainTime {
iso : IsoTime
} derive(Eq, Compare)
///|
pub impl Show for PlainTime with fn output(self, logger) {
logger.write_string(
try! self.to_string_with_options(ToStringRoundingOptions::default()),
)
}
///|
pub impl Debug for PlainTime with fn to_repr(self) {
Repr::Repr(self.to_string())
}
///|
/// Midnight.
pub let plain_time_midnight : PlainTime = { iso: iso_time_midnight }
///|
/// Creates a time, rejecting out-of-range fields.
///
/// ```mbt check
/// test {
/// inspect(@temporal.PlainTime::try_new(hour=7, minute=30), content="07:30:00")
/// }
/// ```
pub fn PlainTime::try_new(
hour? : Int = 0,
minute? : Int = 0,
second? : Int = 0,
millisecond? : Int = 0,
microsecond? : Int = 0,
nanosecond? : Int = 0,
) -> PlainTime raise TemporalError {
PlainTime::new_with_overflow(
hour,
minute,
second,
millisecond,
microsecond,
nanosecond,
Reject,
)
}
///|
/// Creates a time, handling out-of-range fields according to `overflow`.
pub fn PlainTime::new_with_overflow(
hour : Int,
minute : Int,
second : Int,
millisecond : Int,
microsecond : Int,
nanosecond : Int,
overflow : Overflow,
) -> PlainTime raise TemporalError {
{
iso: IsoTime::new_with_overflow(
hour, minute, second, millisecond, microsecond, nanosecond, overflow,
),
}
}
///|
/// Creates a time from an already-validated ISO time.
pub fn PlainTime::from_iso(iso : IsoTime) -> PlainTime {
{ iso, }
}
///|
/// Returns the underlying ISO time.
pub fn PlainTime::iso(self : PlainTime) -> IsoTime {
self.iso
}
///|
/// Returns the hour.
pub fn PlainTime::hour(self : PlainTime) -> Int {
self.iso.hour
}
///|
/// Returns the minute.
pub fn PlainTime::minute(self : PlainTime) -> Int {
self.iso.minute
}
///|
/// Returns the second.
pub fn PlainTime::second(self : PlainTime) -> Int {
self.iso.second
}
///|
/// Returns the millisecond.
pub fn PlainTime::millisecond(self : PlainTime) -> Int {
self.iso.millisecond
}
///|
/// Returns the microsecond within the millisecond.
pub fn PlainTime::microsecond(self : PlainTime) -> Int {
self.iso.microsecond
}
///|
/// Returns the nanosecond within the microsecond.
pub fn PlainTime::nanosecond(self : PlainTime) -> Int {
self.iso.nanosecond
}
///|
/// Returns a copy with the given fields replaced.
pub fn PlainTime::with_fields(
self : PlainTime,
hour? : Int,
minute? : Int,
second? : Int,
millisecond? : Int,
microsecond? : Int,
nanosecond? : Int,
overflow? : Overflow = Constrain,
) -> PlainTime raise TemporalError {
PlainTime::new_with_overflow(
hour.unwrap_or(self.iso.hour),
minute.unwrap_or(self.iso.minute),
second.unwrap_or(self.iso.second),
millisecond.unwrap_or(self.iso.millisecond),
microsecond.unwrap_or(self.iso.microsecond),
nanosecond.unwrap_or(self.iso.nanosecond),
overflow,
)
}
///|
/// `AddDurationToTime`: adds a duration, wrapping around midnight.
///
/// Calendar components are ignored, since a time has no date to hang them on.
///
/// ```mbt check
/// test {
/// let t = @temporal.PlainTime::try_new(hour=23, minute=30)
/// inspect(t.add(@temporal.Duration::of(hours=1)), content="00:30:00")
/// }
/// ```
pub fn PlainTime::add(self : PlainTime, duration : Duration) -> PlainTime {
let (_, iso) = self.iso.add(TimeDuration::from_duration(duration))
{ iso, }
}
///|
/// Subtracts a duration, wrapping around midnight.
pub fn PlainTime::subtract(self : PlainTime, duration : Duration) -> PlainTime {
self.add(duration.negated())
}
///|
/// `DifferenceTemporalPlainTime`.
fn PlainTime::diff_time(
self : PlainTime,
operation : DifferenceOperation,
other : PlainTime,
settings : DifferenceSettings,
) -> Duration raise TemporalError {
let resolved = ResolvedRoundingOptions::from_diff_settings(
settings,
operation,
UnitGroup::Time,
Hour,
Nanosecond,
)
let mut time = self.iso.diff(other.iso)
if !resolved.is_noop() {
time = time.round(resolved)
}
let result = Duration::from_internal(
InternalDurationRecord::combine(DateDuration::default(), time),
resolved.largest_unit,
)
match operation {
Until => result
Since => result.negated()
}
}
///|
/// Returns the duration from this time until `other`.
pub fn PlainTime::until(
self : PlainTime,
other : PlainTime,
settings? : DifferenceSettings = DifferenceSettings::default(),
) -> Duration raise TemporalError {
self.diff_time(Until, other, settings)
}
///|
/// Returns the duration from `other` until this time.
pub fn PlainTime::since(
self : PlainTime,
other : PlainTime,
settings? : DifferenceSettings = DifferenceSettings::default(),
) -> Duration raise TemporalError {
self.diff_time(Since, other, settings)
}
///|
/// Rounds the time to a multiple of the given unit.
///
/// Rounding that carries past midnight wraps, since a time has no date to
/// carry into.
///
/// ```mbt check
/// test {
/// let t = @temporal.PlainTime::try_new(hour=12, minute=34, second=56)
/// let options = @temporal.RoundingOptions::new(smallest_unit=Minute)
/// inspect(t.round(options), content="12:35:00")
/// }
/// ```
pub fn PlainTime::round(
self : PlainTime,
options : RoundingOptions,
) -> PlainTime raise TemporalError {
let resolved = ResolvedRoundingOptions::from_time_options(options)
let (_, iso) = self.iso.round(resolved)
{ iso, }
}
///|
/// Renders the time as `HH:MM:SS`, extended with fractional digits as the
/// options require.
pub fn PlainTime::to_string_with_options(
self : PlainTime,
options : ToStringRoundingOptions,
) -> String raise TemporalError {
let resolved = options.resolve()
let rounding = ResolvedRoundingOptions::from_to_string_options(resolved)
let (_, iso) = self.iso.round(rounding)
let buf = StringBuilder::new()
write_time(
buf,
iso.hour,
iso.minute,
iso.second,
iso.subsecond_nanoseconds(),
resolved.precision,
true,
)
buf.to_string()
}
///|
/// Renders the time as `HH:MM:SS`, with as many fractional digits as it needs.
pub fn PlainTime::to_string(self : PlainTime) -> String {
try! self.to_string_with_options(ToStringRoundingOptions::default())
}