Sub Days (ParsiDateTime) - jalalvandi/ParsiDate GitHub Wiki
sub_days
(on ParsiDateTime)
Method Subtracts a specified number of days from the date part of this ParsiDateTime
, returning a new ParsiDateTime
with the same time component.
Description
This method calculates a new ParsiDateTime
by modifying only the date part (year, month, day) based on the number of days subtracted. The time part (hour, minute, second) of the original ParsiDateTime
instance remains unchanged in the resulting instance.
It functions as a convenient alternative to calling add_days
with a negative value (i.e., self.add_days(-days)
).
The core date calculation, including handling month/year boundaries and leap years, is delegated to the corresponding ParsiDate::sub_days
method (or equivalently, ParsiDate::add_days
with a negative value). Please refer to the ParsiDate
method documentation for details on the date arithmetic logic.
Arguments
days
: The non-negative number of days (u32
,u64
, or similar unsigned integer type) to subtract from the current date part.
Returns
Ok(ParsiDateTime)
: If the startingParsiDateTime
is valid and the underlyingParsiDate::sub_days
(or equivalent) call succeeds, returns the newParsiDateTime
instance (with updated date and original time) wrapped inOk
.Err(DateError::...)
: Returns an error under the same conditions as theadd_days
method when called with a negative value. This occurs if:- The starting
ParsiDateTime
instance itself holds invalid data. - The delegated call to
ParsiDate::sub_days
(orParsiDate::add_days
) fails. This propagates errors likeDateError::InvalidDate
,DateError::GregorianConversionError
, orDateError::ArithmeticOverflow
(if the resulting date falls outside the supported range, e.g., before year 1).
- The starting
Examples (Rust)
use parsidate::{ParsiDateTime, ParsiDate, DateError}; // Assuming these types exist
let dt = ParsiDateTime::new(1403, 1, 15, 10, 30, 0).unwrap(); // Farvardin 15th, 1403, 10:30:00
// --- Subtracting Days ---
// Subtract 20 days. Go back 15 days to 1402-12-30 (1403 is leap, so 1402 is common). Need 5 more days.
// -> Lands on 1402-12-25 (assuming 1402 is common - check needed).
// Let's re-calculate: 1403-01-15 minus 15 days is 1402-12-30 (assuming 1403 leap).
// Need to subtract 5 more days from 1402-12-30. 1402 is common (1402 % 33 = 16), so Esfand has 29 days.
// 1402-12-30 is invalid! The calculation must handle this. Let's re-check the example input/output.
// Ah, the example output is 1402-12-24. Let's trace:
// 1403-01-15 minus 15 days lands on 1403-01-00, which wraps to 1402-12-29 (assuming 1402 is common).
// Wait, ParsiDate::add_days uses Gregorian conversion.
// 1403-01-15 is 2024-04-03.
// 2024-04-03 minus 20 days is 2024-03-14.
// 2024-03-14 converts to Persian: 1402-12-24. The example is correct.
let dt_minus_20d = dt.sub_days(20);
assert!(dt_minus_20d.is_ok());
let dt_minus_20d_unwrapped = dt_minus_20d.unwrap();
// Check the date part: Example shows 1402-12-24
assert_eq!(dt_minus_20d_unwrapped.date(), ParsiDate::new(1402, 12, 24).unwrap());
// Check that the time part is unchanged
assert_eq!(dt_minus_20d_unwrapped.hour(), 10);
assert_eq!(dt_minus_20d_unwrapped.minute(), 30);
assert_eq!(dt_minus_20d_unwrapped.second(), 0);
// --- Error Case (e.g., Resulting date out of range) ---
let earliest_dt = ParsiDateTime::new(1, 1, 1, 0, 0, 0).unwrap();
let result = earliest_dt.sub_days(1); // Attempt to go before year 1
assert!(result.is_err());
// The error kind would be propagated from ParsiDate::sub_days/add_days
// assert!(matches!(result, Err(DateError::ArithmeticOverflow) | Err(DateError::GregorianConversionError)));