Sub Duration (ParsiDateTime) - parsicore/parsidate GitHub Wiki
Method sub_duration (on ParsiDateTime)
Subtracts a chrono::Duration from this ParsiDateTime, returning a new ParsiDateTime.
Description
This method calculates a new ParsiDateTime by subtracting a specified chrono::Duration from the current instance. It correctly handles both date and time adjustments, including rollovers across seconds, minutes, hours, and days.
It functions as a convenience method, equivalent to calling add_duration with the duration negated (i.e., self.add_duration(-duration)). The underlying calculation typically involves conversions to/from chrono::NaiveDateTime to leverage chrono's robust duration arithmetic.
Arguments
duration: Thechrono::Durationto subtract. Note thatDurationitself can be negative, so subtracting a negative duration is equivalent to adding a positive one.
Returns
Ok(ParsiDateTime): If the startingParsiDateTimeis valid, the conversions succeed, and the arithmetic results in a validParsiDateTimewithin the supported range, returns the newParsiDateTimewrapped inOk.Err(DateError::...): Returns an error under the same conditions as theadd_durationmethod. This includes:DateError::InvalidDate/DateError::InvalidTime: If the startingParsiDateTimeis invalid.DateError::GregorianConversionError: If intermediate conversions to/from Gregorian fail.DateError::ArithmeticOverflow: If the resulting date/time falls outside the supported range ofchronoorParsiDateTime.
Examples (Rust)
use parsidate::{ParsiDateTime, ParsiDate, DateError};
use chrono::Duration; // Make sure chrono is a dependency
// Example 1: Subtracting seconds that cross midnight backwards
let dt = ParsiDateTime::new(1403, 1, 1, 0, 0, 5).unwrap(); // Farvardin 1st, 5 seconds past midnight
// Subtract 10 seconds
let dt_prev_day_result = dt.sub_duration(Duration::seconds(10));
assert!(dt_prev_day_result.is_ok());
let dt_prev_day = dt_prev_day_result.unwrap();
// Expected: Goes back to the last second of the previous day.
// Previous day: 1402-12-29 (since 1403 is leap, 1402 is common, Esfand has 29 days).
// Time: 00:00:05 - 10s = wraps around to 23:59:55.
assert_eq!(dt_prev_day.date(), ParsiDate::new(1402, 12, 29).unwrap());
assert_eq!(dt_prev_day.time(), (23, 59, 55));
// Example 2: Subtracting hours
let dt2 = ParsiDateTime::new(1403, 5, 10, 2, 15, 0).unwrap(); // Mordad 10th, 02:15:00
// Subtract 4 hours
let dt_minus_4h = dt2.sub_duration(Duration::hours(4));
assert!(dt_minus_4h.is_ok());
let dt_minus_4h_unwrapped = dt_minus_4h.unwrap();
// Expected: Date goes back to Mordad 9th. Time wraps around (02:15 - 4h = -01:45 -> 22:15 prev day)
assert_eq!(dt_minus_4h_unwrapped.date(), ParsiDate::new(1403, 5, 9).unwrap());
assert_eq!(dt_minus_4h_unwrapped.time(), (22, 15, 0));
// Example 3: Error case (potential) - subtracting large duration
let earliest_dt = ParsiDateTime::new(1, 1, 1, 0, 0, 0).unwrap();
let very_long_ago = Duration::days(500 * 365); // Approx 500 years
let result = earliest_dt.sub_duration(very_long_ago);
// This will likely fail due to going before the supported epoch
assert!(result.is_err());
// assert!(matches!(result, Err(DateError::GregorianConversionError) | Err(DateError::ArithmeticOverflow)));