With Month - jalalvandi/ParsiDate GitHub Wiki
with_month
Method Creates a new ParsiDate
instance by replacing the month component, adjusting the day if necessary (day clamping).
Description
This method creates a new ParsiDate
based on the current instance (self
), but with the month component changed to the specified month
value. The year component is copied directly from the original self
instance.
The day component is initially copied from self.day()
, but it is then subject to day clamping:
- If the original
day
value is greater than the number of days allowed in the targetmonth
(within the sameyear
), theday
in the newParsiDate
is adjusted downwards to the last valid day of that target month.- Example: Changing month from Farvardin (31 days) to Mehr (30 days) when the original day was 31 will result in the new day being 30.
- Example: Changing month from Ordibehesht (31 days) to Esfand (month 12) in a common year (29 days) when the original day was 30 or 31 will result in the new day being 29.
This method also performs validation to ensure the starting ParsiDate
is valid and the target month
is within the acceptable range [1, 12].
Arguments
month
: The desired month for the newParsiDate
(u8
or similar integer type). Must be between 1 and 12 (inclusive).
Returns
Ok(ParsiDate)
: If the originalParsiDate
(self
) is valid and the targetmonth
is valid (1-12), returns the newParsiDate
instance (with potentially clamped day) wrapped inOk
.Err(DateError::InvalidDate)
: Returns an error if either of the following conditions is met:- The starting
ParsiDate
instance (self
) is invalid (e.g., contains invalid day or month data, potentially fromunsafe
creation). - The provided target
month
is outside the valid range [1, 12] (e.g., 0 or 13).
- The starting
Examples (Rust)
use parsidate::{ParsiDate, DateError}; // Assuming these types exist
let date = ParsiDate::new(1403, 1, 31).unwrap(); // Farvardin 31st, 1403 (1403 is leap)
// --- Success Cases with Clamping ---
// Change month to Mehr (Month 7, 30 days). Original day 31 is > 30, so clamped to 30.
let date_mehr = date.with_month(7);
assert!(date_mehr.is_ok());
assert_eq!(date_mehr.unwrap(), ParsiDate::new(1403, 7, 30).unwrap()); // Day becomes 30
// Change month to Esfand (Month 12). Year 1403 is leap (Esfand has 30 days).
// Original day 31 is > 30, so clamped to 30.
let date_esfand_leap = date.with_month(12);
assert!(date_esfand_leap.is_ok());
assert_eq!(date_esfand_leap.unwrap(), ParsiDate::new(1403, 12, 30).unwrap()); // Day becomes 30
// --- Success Case with Clamping (Common Year) ---
let date_common_year = ParsiDate::new(1404, 1, 31).unwrap(); // Farvardin 31st, 1404 (common)
// Change month to Esfand (Month 12). Year 1404 is common (Esfand has 29 days).
// Original day 31 is > 29, so clamped to 29.
let date_esfand_common = date_common_year.with_month(12);
assert!(date_esfand_common.is_ok());
assert_eq!(date_esfand_common.unwrap(), ParsiDate::new(1404, 12, 29).unwrap()); // Day becomes 29
// --- Success Case without Clamping ---
// Change month to Ordibehesht (Month 2, 31 days). Original day 31 is valid.
let date_ordibehesht = date.with_month(2);
assert!(date_ordibehesht.is_ok());
assert_eq!(date_ordibehesht.unwrap(), ParsiDate::new(1403, 2, 31).unwrap()); // Day remains 31
// --- Error Cases ---
// Target month 0 is out of range [1, 12]
assert_eq!(
date.with_month(0),
Err(DateError::InvalidDate)
);
// Target month 13 is out of range [1, 12]
assert_eq!(
date.with_month(13),
Err(DateError::InvalidDate)
);
// --- Error Case: Starting date is invalid ---
// Create an invalid date unsafely (e.g., invalid day 32)
let invalid_start = unsafe { ParsiDate::new_unchecked(1400, 1, 32) };
// Trying to change the month of an invalid date should fail validation
assert_eq!(
invalid_start.with_month(2),
Err(DateError::InvalidDate) // Original date is invalid
);