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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
//! Structured datetime pattern types for datagen and the data provider.
//!
//! <div class="stab unstable">
//! 🚧 This code is considered unstable; it may change at any time, in breaking or non-breaking ways,
//! including in SemVer minor releases. While the serde representation of data structs is guaranteed
//! to be stable, their Rust representation might not be. Use with caution.
//! </div>
mod common;
mod error;
mod hour_cycle;
mod item;
pub mod reference;
pub mod runtime;
use crate::fields;
pub use error::PatternError;
#[cfg(feature = "datagen")]
pub(crate) use hour_cycle::naively_apply_preferences;
pub use hour_cycle::CoarseHourCycle;
use icu_provider::prelude::*;
pub use item::{GenericPatternItem, PatternItem};
/// The granularity of time represented in a [`Pattern`](runtime::Pattern).
/// Ordered from least granular to most granular for comparison.
#[derive(
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, yoke::Yokeable, zerofrom::ZeroFrom,
)]
#[cfg_attr(feature = "datagen", derive(serde::Serialize, databake::Bake))]
#[cfg_attr(feature = "datagen", databake(path = icu_datetime::provider::pattern))]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[non_exhaustive]
pub enum TimeGranularity {
/// No time is in the pattern.
None,
/// Smallest time unit = hours.
Hours,
/// Smallest time unit = minutes.
Minutes,
/// Smallest time unit = seconds.
Seconds,
/// Smallest time unit = nanoseconds.
Nanoseconds,
}
impl Default for TimeGranularity {
fn default() -> Self {
Self::None
}
}
impl TimeGranularity {
/// Returns [`true`] if the most granular time being displayed will align with
/// the top of the hour, otherwise returns [`false`].
/// e.g. `12:00:00` is at the top of the hour for any display granularity.
/// e.g. `12:00:05` is only at the top of the hour if the seconds are not displayed.
pub fn is_top_of_hour(self, minute: u8, second: u8, nanosecond: u32) -> bool {
match self {
Self::None | Self::Hours => true,
Self::Minutes => minute == 0,
Self::Seconds => minute + second == 0,
Self::Nanoseconds => minute as u32 + second as u32 + nanosecond == 0,
}
}
#[inline]
pub(crate) fn from_ordinal(ordinal: u8) -> TimeGranularity {
use TimeGranularity::*;
match ordinal {
1 => Hours,
2 => Minutes,
3 => Seconds,
4 => Nanoseconds,
_ => None,
}
}
#[inline]
pub(crate) const fn ordinal(self) -> u8 {
use TimeGranularity::*;
match self {
None => 0,
Hours => 1,
Minutes => 2,
Seconds => 3,
Nanoseconds => 4,
}
}
}
impl From<PatternItem> for TimeGranularity {
/// Retrieves the granularity of time represented by a [`PatternItem`].
/// If the [`PatternItem`] is not time-related, returns [`None`].
fn from(item: PatternItem) -> Self {
match item {
PatternItem::Field(field) => match field.symbol {
fields::FieldSymbol::Hour(_) => Self::Hours,
fields::FieldSymbol::Minute => Self::Minutes,
fields::FieldSymbol::Second(_) => Self::Seconds,
fields::FieldSymbol::DecimalSecond(_) => Self::Nanoseconds,
_ => Self::None,
},
_ => Self::None,
}
}
}