Coverage Report

Created: 2025-06-16 06:50

/rust/registry/src/index.crates.io-6f17d22bba15001f/icu_calendar-1.5.2/src/duration.rs
Line
Count
Source (jump to first uncovered line)
1
// This file is part of ICU4X. For terms of use, please see the file
2
// called LICENSE at the top level of the ICU4X source tree
3
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5
use crate::Calendar;
6
use core::fmt;
7
use core::marker::PhantomData;
8
9
/// A duration between two dates
10
///
11
/// Can be used to perform date arithmetic
12
///
13
/// # Example
14
///
15
/// ```rust
16
/// use icu::calendar::{
17
///     types::IsoWeekday, Date, DateDuration, DateDurationUnit,
18
/// };
19
///
20
/// // Creating ISO date: 1992-09-02.
21
/// let mut date_iso = Date::try_new_iso_date(1992, 9, 2)
22
///     .expect("Failed to initialize ISO Date instance.");
23
///
24
/// assert_eq!(date_iso.day_of_week(), IsoWeekday::Wednesday);
25
/// assert_eq!(date_iso.year().number, 1992);
26
/// assert_eq!(date_iso.month().ordinal, 9);
27
/// assert_eq!(date_iso.day_of_month().0, 2);
28
///
29
/// // Answering questions about days in month and year.
30
/// assert_eq!(date_iso.days_in_year(), 366);
31
/// assert_eq!(date_iso.days_in_month(), 30);
32
///
33
/// // Advancing date in-place by 1 year, 2 months, 3 weeks, 4 days.
34
/// date_iso.add(DateDuration::new(1, 2, 3, 4));
35
/// assert_eq!(date_iso.year().number, 1993);
36
/// assert_eq!(date_iso.month().ordinal, 11);
37
/// assert_eq!(date_iso.day_of_month().0, 27);
38
///
39
/// // Reverse date advancement.
40
/// date_iso.add(DateDuration::new(-1, -2, -3, -4));
41
/// assert_eq!(date_iso.year().number, 1992);
42
/// assert_eq!(date_iso.month().ordinal, 9);
43
/// assert_eq!(date_iso.day_of_month().0, 2);
44
///
45
/// // Creating ISO date: 2022-01-30.
46
/// let newer_date_iso = Date::try_new_iso_date(2022, 1, 30)
47
///     .expect("Failed to initialize ISO Date instance.");
48
///
49
/// // Comparing dates: 2022-01-30 and 1992-09-02.
50
/// let duration = newer_date_iso.until(
51
///     &date_iso,
52
///     DateDurationUnit::Years,
53
///     DateDurationUnit::Days,
54
/// );
55
/// assert_eq!(duration.years, 30);
56
/// assert_eq!(duration.months, -8);
57
/// assert_eq!(duration.days, 28);
58
///
59
/// // Create new date with date advancement. Reassign to new variable.
60
/// let mutated_date_iso = date_iso.added(DateDuration::new(1, 2, 3, 4));
61
/// assert_eq!(mutated_date_iso.year().number, 1993);
62
/// assert_eq!(mutated_date_iso.month().ordinal, 11);
63
/// assert_eq!(mutated_date_iso.day_of_month().0, 27);
64
/// ```
65
///
66
/// Currently unstable for ICU4X 1.0
67
#[derive(Eq, PartialEq)]
68
#[allow(clippy::exhaustive_structs)] // this type should be stable (and is intended to be constructed manually)
69
#[doc(hidden)]
70
pub struct DateDuration<C: Calendar + ?Sized> {
71
    /// The number of years
72
    pub years: i32,
73
    /// The number of months
74
    pub months: i32,
75
    /// The number of weeks
76
    pub weeks: i32,
77
    /// The number of days
78
    pub days: i32,
79
    /// A marker for the calendar
80
    pub marker: PhantomData<C>,
81
}
82
83
// Custom impl so that C need not be bound on Copy/Clone
84
impl<C: Calendar + ?Sized> Clone for DateDuration<C> {
85
0
    fn clone(&self) -> Self {
86
0
        *self
87
0
    }
88
}
89
90
// Custom impl so that C need not be bound on Copy/Clone
91
impl<C: Calendar + ?Sized> Copy for DateDuration<C> {}
92
93
/// A "duration unit" used to specify the minimum or maximum duration of time to
94
/// care about
95
///
96
/// Currently unstable for ICU4X 1.0
97
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
98
#[allow(clippy::exhaustive_enums)] // this type should be stable
99
#[doc(hidden)]
100
pub enum DateDurationUnit {
101
    /// Duration in years
102
    Years,
103
    /// Duration in months
104
    Months,
105
    /// Duration in weeks
106
    Weeks,
107
    /// Duration in days
108
    Days,
109
}
110
111
impl<C: Calendar + ?Sized> Default for DateDuration<C> {
112
0
    fn default() -> Self {
113
0
        Self {
114
0
            years: 0,
115
0
            months: 0,
116
0
            weeks: 0,
117
0
            days: 0,
118
0
            marker: PhantomData,
119
0
        }
120
0
    }
121
}
122
123
impl<C: Calendar + ?Sized> DateDuration<C> {
124
    /// Construct a DateDuration
125
    ///
126
    /// ```rust
127
    /// # use icu::calendar::*;
128
    /// // two years, three months, and five days
129
    /// let duration: DateDuration<Iso> = DateDuration::new(2, 3, 0, 5);
130
    /// ```
131
0
    pub fn new(years: i32, months: i32, weeks: i32, days: i32) -> Self {
132
0
        DateDuration {
133
0
            years,
134
0
            months,
135
0
            weeks,
136
0
            days,
137
0
            marker: PhantomData,
138
0
        }
139
0
    }
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::iso::Iso>>::new
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::dangi::Dangi>>::new
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::coptic::Coptic>>::new
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::hebrew::Hebrew>>::new
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::indian::Indian>>::new
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::julian::Julian>>::new
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::chinese::Chinese>>::new
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::islamic::IslamicCivil>>::new
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::islamic::IslamicTabular>>::new
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::islamic::IslamicUmmAlQura>>::new
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::islamic::IslamicObservational>>::new
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::persian::Persian>>::new
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::ethiopian::Ethiopian>>::new
140
141
    /// Explicitly cast duration to one for a different calendar
142
0
    pub fn cast_unit<C2: Calendar + ?Sized>(self) -> DateDuration<C2> {
143
0
        DateDuration {
144
0
            years: self.years,
145
0
            months: self.months,
146
0
            days: self.days,
147
0
            weeks: self.weeks,
148
0
            marker: PhantomData,
149
0
        }
150
0
    }
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::iso::Iso>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::roc::Roc>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::dangi::Dangi>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::coptic::Coptic>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::hebrew::Hebrew>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::indian::Indian>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::chinese::Chinese>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::islamic::IslamicCivil>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::islamic::IslamicTabular>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::islamic::IslamicUmmAlQura>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::islamic::IslamicObservational>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::persian::Persian>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::buddhist::Buddhist>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::japanese::JapaneseExtended>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::japanese::Japanese>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::ethiopian::Ethiopian>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::any_calendar::AnyCalendar>>::cast_unit::<icu_calendar::gregorian::Gregorian>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::iso::Iso>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::iso::Iso>>::cast_unit::<icu_calendar::roc::Roc>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::iso::Iso>>::cast_unit::<icu_calendar::buddhist::Buddhist>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::iso::Iso>>::cast_unit::<icu_calendar::japanese::Japanese>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::iso::Iso>>::cast_unit::<icu_calendar::gregorian::Gregorian>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::roc::Roc>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::roc::Roc>>::cast_unit::<icu_calendar::iso::Iso>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::dangi::Dangi>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::coptic::Coptic>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::hebrew::Hebrew>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::indian::Indian>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::chinese::Chinese>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::islamic::IslamicCivil>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::islamic::IslamicTabular>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::islamic::IslamicUmmAlQura>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::islamic::IslamicObservational>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::persian::Persian>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::buddhist::Buddhist>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::buddhist::Buddhist>>::cast_unit::<icu_calendar::iso::Iso>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::japanese::JapaneseExtended>>::cast_unit::<icu_calendar::japanese::Japanese>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::japanese::JapaneseExtended>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::japanese::Japanese>>::cast_unit::<icu_calendar::japanese::JapaneseExtended>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::japanese::Japanese>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::japanese::Japanese>>::cast_unit::<icu_calendar::iso::Iso>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::ethiopian::Ethiopian>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::gregorian::Gregorian>>::cast_unit::<icu_calendar::any_calendar::AnyCalendar>
Unexecuted instantiation: <icu_calendar::duration::DateDuration<icu_calendar::gregorian::Gregorian>>::cast_unit::<icu_calendar::iso::Iso>
151
}
152
153
impl<C: Calendar> fmt::Debug for DateDuration<C> {
154
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
155
0
        f.debug_struct("DateDuration")
156
0
            .field("years", &self.years)
157
0
            .field("months", &self.months)
158
0
            .field("weeks", &self.weeks)
159
0
            .field("days", &self.days)
160
0
            .finish()
161
0
    }
162
}