Add Years - jalalvandi/ParsiDate GitHub Wiki
add_years
Method Adds a specified number of years to this ParsiDate
, returning a new ParsiDate
instance, handling leap day adjustments when necessary.
Description
This method calculates a new date by adding (or subtracting) a given number of years to the current ParsiDate
instance (self
). The operation primarily adjusts the year component.
The month and day components generally remain unchanged, with one important exception: leap day handling. If the original date is Esfand 30th (the leap day, which only exists in Persian leap years) and the target year (calculated as self.year() + years_to_add
) is not a leap year, then the day component of the resulting ParsiDate
will be clamped down to 29 (the last day of Esfand in a non-leap year).
In all other situations, the month and day are preserved exactly:
- If the original date is not Esfand 30th.
- If the original date is Esfand 30th, and the target year is also a leap year.
The years_to_add
argument can be positive to advance the date forward or negative to move the date backward in time.
Arguments
years_to_add
: The number of years to add to the current date's year component (i32
or a similar signed integer type).- A positive value moves the date forward in years.
- A negative value moves the date backward in years.
- A value of zero results in a
ParsiDate
identical to the original.
Returns
Ok(ParsiDate)
: If the startingParsiDate
is valid and the resulting date (after potential day clamping for leap year transitions) has a year within the supported range [1, 9999], returns the newParsiDate
wrapped inOk
.Err(DateError::InvalidDate)
: If the startingParsiDate
instance (self
) represents an invalid date according to Persian calendar rules.Err(DateError::ArithmeticOverflow)
: If addingyears_to_add
results in a year that falls outside the supported range [1, 9999].
Examples (Rust)
use parsidate::{ParsiDate, DateError}; // Assuming these types exist
// --- Leap Day Handling Examples ---
// Start with Esfand 30th in a known leap year (1403 is leap)
let leap_day_1403 = ParsiDate::new(1403, 12, 30).unwrap();
// Add 1 year -> Target year 1404 (NOT leap). Day is clamped from 30 to 29.
let result1 = leap_day_1403.add_years(1);
assert_eq!(result1, Ok(ParsiDate::new(1404, 12, 29).unwrap()));
// Add 4 years -> Target year 1407 (IS leap). Day remains 30.
let result2 = leap_day_1403.add_years(4);
assert_eq!(result2, Ok(ParsiDate::new(1407, 12, 30).unwrap()));
// Subtract 4 years -> Target year 1399 (IS leap). Day remains 30.
let result3 = leap_day_1403.add_years(-4);
assert_eq!(result3, Ok(ParsiDate::new(1399, 12, 30).unwrap()));
// Subtract 3 years -> Target year 1400 (NOT leap). Day is clamped from 30 to 29.
let result4 = leap_day_1403.add_years(-3);
assert_eq!(result4, Ok(ParsiDate::new(1400, 12, 29).unwrap()));
// --- Non-Leap Day Examples ---
let common_date = ParsiDate::new(1403, 5, 15).unwrap(); // Mordad 15th
// Add 1 year. Month and day remain unchanged.
assert_eq!(common_date.add_years(1), Ok(ParsiDate::new(1404, 5, 15).unwrap()));
// Subtract 1 year. Month and day remain unchanged.
assert_eq!(common_date.add_years(-1), Ok(ParsiDate::new(1402, 5, 15).unwrap()));
// Start on Esfand 29th of a non-leap year (1402)
let esfand_29_common = ParsiDate::new(1402, 12, 29).unwrap();
// Add 1 year -> Target year 1403 (leap year). Day stays 29 (no clamping needed).
assert_eq!(esfand_29_common.add_years(1), Ok(ParsiDate::new(1403, 12, 29).unwrap()));
// --- Zero Years ---
assert_eq!(leap_day_1403.add_years(0), Ok(ParsiDate::new(1403, 12, 30).unwrap()));
assert_eq!(common_date.add_years(0), Ok(ParsiDate::new(1403, 5, 15).unwrap()));
// --- Error Case: Resulting Year Out of Range ---
let early_date = ParsiDate::new(1, 1, 1).unwrap();
// Try to subtract years to go before the supported year 1
let result_too_early = early_date.add_years(-1);
assert!(result_too_early.is_err());
assert_eq!(result_too_early, Err(DateError::ArithmeticOverflow));
let late_date = ParsiDate::new(9999, 6, 1).unwrap();
// Try to add years resulting in a year beyond the supported range (e.g., > 9999)
let result_too_late = late_date.add_years(1);
assert!(result_too_late.is_err());
assert_eq!(result_too_late, Err(DateError::ArithmeticOverflow));