Skip to main content

deep_time/dt/
arithmetic_calendar.rs

1use crate::Dt;
2
3#[cfg(any(feature = "jiff-tz-bundle", feature = "jiff-tz"))]
4use crate::DtErr;
5
6impl Dt {
7    /// Adds (or subtracts) calendar years, preserving month and day-of-month.
8    /// - Uses standard last-day-of-month clamping.
9    /// - Negative values subtract.
10    #[inline(always)]
11    pub const fn add_yr(&self, n: i64) -> Self {
12        self.to_ymd().add_yr(n).to_dt()
13    }
14
15    /// Adds (or subtracts) calendar months.
16    /// Negative values subtract.
17    #[inline(always)]
18    pub const fn add_mo(&self, n: i64) -> Self {
19        self.to_ymd().add_mo(n).to_dt()
20    }
21
22    /// Adds (or subtracts) calendar weeks.
23    /// Negative values subtract.
24    #[inline(always)]
25    pub const fn add_wk(&self, n: i64) -> Self {
26        self.to_ymd().add_wk(n).to_dt()
27    }
28
29    /// Adds (or subtracts) calendar days.
30    /// Negative values subtract.
31    #[inline(always)]
32    pub const fn add_days(&self, n: i64) -> Self {
33        self.to_ymd().add_days(n).to_dt()
34    }
35}
36
37#[cfg(any(feature = "jiff-tz-bundle", feature = "jiff-tz"))]
38impl Dt {
39    /// Adds the given number of years in the specified IANA timezone,
40    /// respecting timezone rules (including DST) and calendar arithmetic.
41    ///
42    /// ## Notes
43    ///
44    /// - Requires the `jiff-tz` feature.
45    /// - Assumes this [`Dt`] is counting seconds from the library's
46    ///   `2000-01-01 12:00:00` epoch.
47    ///
48    /// ## Errors
49    ///
50    /// - [`DtErrKind::YearOutOfRange`] if the year of the date is outside the
51    ///   `-9999..=9999` range (checked before involving Jiff).
52    /// - Specific errors for invalid time components when preparing values for Jiff:
53    ///   [`DtErrKind::InvalidHour`], [`DtErrKind::InvalidMinute`],
54    ///   [`DtErrKind::InvalidSecond`], [`DtErrKind::InvalidMonth`], or [`DtErrKind::InvalidDay`].
55    /// - [`DtErrKind::InvalidTimeZone`] if Jiff cannot find/resolve the IANA timezone name.
56    /// - [`DtErrKind::OutOfRange`] if the result of the calendar arithmetic operation
57    ///   would be outside the range supported by Jiff (the checked_add fails).
58    #[inline(always)]
59    pub fn add_yr_tz(&self, n: i64, tz: &str) -> Result<Self, DtErr> {
60        Ok(self.to_ymd().add_yr_tz(n, tz)?.to_dt())
61    }
62
63    /// Adds the given number of months in the specified IANA timezone,
64    /// respecting timezone rules and calendar month-end clamping.
65    ///
66    /// ## Notes
67    ///
68    /// - Requires the `jiff-tz` feature.
69    /// - Assumes this [`Dt`] is counting seconds from the library's
70    ///   `2000-01-01 12:00:00` epoch.
71    ///
72    /// ## Errors
73    ///
74    /// - [`DtErrKind::YearOutOfRange`] if the year of the date is outside the
75    ///   `-9999..=9999` range (checked before involving Jiff).
76    /// - Specific errors for invalid time components when preparing values for Jiff:
77    ///   [`DtErrKind::InvalidHour`], [`DtErrKind::InvalidMinute`],
78    ///   [`DtErrKind::InvalidSecond`], [`DtErrKind::InvalidMonth`], or [`DtErrKind::InvalidDay`].
79    /// - [`DtErrKind::InvalidTimeZone`] if Jiff cannot find/resolve the IANA timezone name.
80    /// - [`DtErrKind::OutOfRange`] if the result of the calendar arithmetic operation
81    ///   would be outside the range supported by Jiff (the checked_add fails).
82    #[inline(always)]
83    pub fn add_mo_tz(&self, n: i64, tz: &str) -> Result<Self, DtErr> {
84        Ok(self.to_ymd().add_mo_tz(n, tz)?.to_dt())
85    }
86
87    /// Adds the given number of weeks in the specified IANA timezone,
88    /// respecting timezone rules (including DST).
89    ///
90    /// ## Notes
91    ///
92    /// - Requires the `jiff-tz` feature.
93    /// - Assumes this [`Dt`] is counting seconds from the library's
94    ///   `2000-01-01 12:00:00` epoch.
95    ///
96    /// ## Errors
97    ///
98    /// - [`DtErrKind::YearOutOfRange`] if the year of the date is outside the
99    ///   `-9999..=9999` range (checked before involving Jiff).
100    /// - Specific errors for invalid time components when preparing values for Jiff:
101    ///   [`DtErrKind::InvalidHour`], [`DtErrKind::InvalidMinute`],
102    ///   [`DtErrKind::InvalidSecond`], [`DtErrKind::InvalidMonth`], or [`DtErrKind::InvalidDay`].
103    /// - [`DtErrKind::InvalidTimeZone`] if Jiff cannot find/resolve the IANA timezone name.
104    /// - [`DtErrKind::OutOfRange`] if the result of the calendar arithmetic operation
105    ///   would be outside the range supported by Jiff (the checked_add fails).
106    #[inline(always)]
107    pub fn add_wk_tz(&self, n: i64, tz: &str) -> Result<Self, DtErr> {
108        Ok(self.to_ymd().add_wk_tz(n, tz)?.to_dt())
109    }
110
111    /// Adds the given number of calendar days in the specified IANA timezone,
112    /// respecting timezone rules (including DST).
113    ///
114    /// ## Notes
115    ///
116    /// - Requires the `jiff-tz` feature.
117    /// - Assumes this [`Dt`] is counting seconds from the library's
118    ///   `2000-01-01 12:00:00` epoch.
119    ///
120    /// ## Errors
121    ///
122    /// - [`DtErrKind::YearOutOfRange`] if the year of the date is outside the
123    ///   `-9999..=9999` range (checked before involving Jiff).
124    /// - Specific errors for invalid time components when preparing values for Jiff:
125    ///   [`DtErrKind::InvalidHour`], [`DtErrKind::InvalidMinute`],
126    ///   [`DtErrKind::InvalidSecond`], [`DtErrKind::InvalidMonth`], or [`DtErrKind::InvalidDay`].
127    /// - [`DtErrKind::InvalidTimeZone`] if Jiff cannot find/resolve the IANA timezone name.
128    /// - [`DtErrKind::OutOfRange`] if the result of the calendar arithmetic operation
129    ///   would be outside the range supported by Jiff (the checked_add fails).
130    #[inline(always)]
131    pub fn add_days_tz(&self, n: i64, tz: &str) -> Result<Self, DtErr> {
132        Ok(self.to_ymd().add_days_tz(n, tz)?.to_dt())
133    }
134
135    /// Adds the given number of hours in the specified IANA timezone,
136    /// respecting timezone rules (including DST).
137    ///
138    /// ## Notes
139    ///
140    /// - Requires the `jiff-tz` feature.
141    /// - Assumes this [`Dt`] is counting seconds from the library's
142    ///   `2000-01-01 12:00:00` epoch.
143    ///
144    /// ## Errors
145    ///
146    /// - [`DtErrKind::YearOutOfRange`] if the year of the date is outside the
147    ///   `-9999..=9999` range (checked before involving Jiff).
148    /// - Specific errors for invalid time components when preparing values for Jiff:
149    ///   [`DtErrKind::InvalidHour`], [`DtErrKind::InvalidMinute`],
150    ///   [`DtErrKind::InvalidSecond`], [`DtErrKind::InvalidMonth`], or [`DtErrKind::InvalidDay`].
151    /// - [`DtErrKind::InvalidTimeZone`] if Jiff cannot find/resolve the IANA timezone name.
152    /// - [`DtErrKind::OutOfRange`] if the result of the calendar arithmetic operation
153    ///   would be outside the range supported by Jiff (the checked_add fails).
154    #[inline(always)]
155    pub fn add_hr_tz(&self, n: i64, tz: &str) -> Result<Self, DtErr> {
156        Ok(self.to_ymd().add_hr_tz(n, tz)?.to_dt())
157    }
158
159    /// Adds the given number of minutes in the specified IANA timezone,
160    /// respecting timezone rules (including DST).
161    ///
162    /// ## Notes
163    ///
164    /// - Requires the `jiff-tz` feature.
165    /// - Assumes this [`Dt`] is counting seconds from the library's
166    ///   `2000-01-01 12:00:00` epoch.
167    ///
168    /// ## Errors
169    ///
170    /// - [`DtErrKind::YearOutOfRange`] if the year of the date is outside the
171    ///   `-9999..=9999` range (checked before involving Jiff).
172    /// - Specific errors for invalid time components when preparing values for Jiff:
173    ///   [`DtErrKind::InvalidHour`], [`DtErrKind::InvalidMinute`],
174    ///   [`DtErrKind::InvalidSecond`], [`DtErrKind::InvalidMonth`], or [`DtErrKind::InvalidDay`].
175    /// - [`DtErrKind::InvalidTimeZone`] if Jiff cannot find/resolve the IANA timezone name.
176    /// - [`DtErrKind::OutOfRange`] if the result of the calendar arithmetic operation
177    ///   would be outside the range supported by Jiff (the checked_add fails).
178    #[inline(always)]
179    pub fn add_min_tz(&self, n: i64, tz: &str) -> Result<Self, DtErr> {
180        Ok(self.to_ymd().add_min_tz(n, tz)?.to_dt())
181    }
182
183    /// Adds the given number of seconds in the specified IANA timezone,
184    /// respecting timezone rules (including DST).
185    ///
186    /// ## Notes
187    ///
188    /// - Requires the `jiff-tz` feature.
189    /// - Assumes this [`Dt`] is counting seconds from the library's
190    ///   `2000-01-01 12:00:00` epoch.
191    ///
192    /// ## Errors
193    ///
194    /// - [`DtErrKind::YearOutOfRange`] if the year of the date is outside the
195    ///   `-9999..=9999` range (checked before involving Jiff).
196    /// - Specific errors for invalid time components when preparing values for Jiff:
197    ///   [`DtErrKind::InvalidHour`], [`DtErrKind::InvalidMinute`],
198    ///   [`DtErrKind::InvalidSecond`], [`DtErrKind::InvalidMonth`], or [`DtErrKind::InvalidDay`].
199    /// - [`DtErrKind::InvalidTimeZone`] if Jiff cannot find/resolve the IANA timezone name.
200    /// - [`DtErrKind::OutOfRange`] if the result of the calendar arithmetic operation
201    ///   would be outside the range supported by Jiff (the checked_add fails).
202    #[inline(always)]
203    pub fn add_sec_tz(&self, n: i64, tz: &str) -> Result<Self, DtErr> {
204        Ok(self.to_ymd().add_sec_tz(n, tz)?.to_dt())
205    }
206}