///|
/// The explicit zone spelling is retained. Local, UTC, hour-only shifts and
/// hour-minute shifts are distinct; no implicit host-timezone conversion occurs.
pub(all) enum TimeZone {
Local
Utc
Offset(Int, Int, Int, Bool)
} derive(Eq, @debug.Debug)
///|
/// A complete calendar date followed by HH:MM:SS and an optional zone.
/// Fractions, leap seconds and 24:00 are outside this documented subset.
pub(all) struct EdtfDateTime {
date : EdtfDate
hour : Int
minute : Int
second : Int
zone : TimeZone
} derive(Eq, @debug.Debug)
///|
fn two_digits(value : Int) -> String {
pad4(value)[2:4].to_owned()
}
///|
fn time_zone_to_string(zone : TimeZone) -> String {
match zone {
Local => ""
Utc => "Z"
Offset(sign, hours, minutes, has_minutes) => {
let prefix = if sign < 0 { "-" } else { "+" }
if has_minutes {
prefix + two_digits(hours) + ":" + two_digits(minutes)
} else {
prefix + two_digits(hours)
}
}
}
}
///|
fn date_time_to_string(value : EdtfDateTime) -> String {
date_to_string(value.date) +
"T" +
two_digits(value.hour) +
":" +
two_digits(value.minute) +
":" +
two_digits(value.second) +
time_zone_to_string(value.zone)
}