With Month (ParsiDateTime) - parsicore/parsidate GitHub Wiki

Method with_month (on ParsiDateTime)

Creates a new ParsiDateTime instance with only the month component of the date changed, preserving the time and adjusting the day if necessary.

Description

This method creates a new ParsiDateTime based on the current instance (self), replacing only the month component of the date part. The year, the initial day, and all time components (hour, minute, second) are copied directly from the original self instance.

The crucial logic for changing the month, validating the target month, and handling day clamping (adjusting the day down if it's invalid for the new month, e.g., day 31 when moving to Mehr) is delegated to the underlying ParsiDate::with_month method. Please refer to its documentation for details on the day clamping behavior.

Arguments

  • month: The desired new Persian month (u8 or similar integer type) for the new ParsiDateTime. Must be between 1 and 12 (inclusive).

Returns

  • Ok(ParsiDateTime): If the underlying call to ParsiDate::with_month on the date component is successful (meaning the original date was valid, the target month is valid, and day clamping succeeded if needed), returns the new ParsiDateTime instance (with updated month, potentially clamped day, and original time) wrapped in Ok.
  • Err(DateError::InvalidDate): Returns an error if the underlying call to ParsiDate::with_month fails. This occurs if:
    • The original date part of self was invalid.
    • The specified month is outside the valid range [1, 12].

Examples (Rust)

use parsidate::{ParsiDateTime, DateError, ParsiDate}; // Assuming these types exist

let dt = ParsiDateTime::new(1403, 1, 31, 10, 0, 0).unwrap(); // Farvardin 31st, 10:00:00

// --- Success Case: Change Month with Day Clamping ---
// Change month to Mehr (Month 7). Mehr has 30 days. Original day 31 > 30, so clamp.
let dt_clamped_month_result = dt.with_month(7);
assert!(dt_clamped_month_result.is_ok());
let dt_clamped_month = dt_clamped_month_result.unwrap();

// Verify the new month, clamped day, and preserved time
assert_eq!(dt_clamped_month.month(), 7);
assert_eq!(dt_clamped_month.day(), 30); // Day clamped from 31
assert_eq!(dt_clamped_month.date(), ParsiDate::new(1403, 7, 30).unwrap()); // Verify full date
assert_eq!(dt_clamped_month.time(), (10, 0, 0)); // Time unchanged


// --- Success Case: Change Month without Clamping ---
let dt_day15 = ParsiDateTime::new(1403, 5, 15, 11, 22, 33).unwrap(); // Mordad 15th
// Change month to Bahman (Month 11, 30 days). Original day 15 is valid.
let dt_bahman_result = dt_day15.with_month(11);
assert!(dt_bahman_result.is_ok());
let dt_bahman = dt_bahman_result.unwrap();
assert_eq!(dt_bahman.month(), 11);
assert_eq!(dt_bahman.day(), 15); // Day unchanged
assert_eq!(dt_bahman.time(), (11, 22, 33));


// --- Error Case: Attempting to Set an Invalid Month ---
// Try setting month to 13 (valid range is 1-12).
let result_invalid_month = dt.with_month(13);
assert!(result_invalid_month.is_err());
assert!(matches!(result_invalid_month, Err(DateError::InvalidDate))); // Check error type

// Try setting month to 0
let result_month_zero = dt.with_month(0);
assert!(matches!(result_month_zero, Err(DateError::InvalidDate)));


// --- Error Case: Starting date is invalid ---
// Create an invalid DateTime unsafely (invalid date part)
// let invalid_start_dt = unsafe { ParsiDateTime::new_unchecked(1400, 1, 32, 10, 0, 0) }; // Invalid day 32
// assert!(!invalid_start_dt.is_valid());
// Attempting to change the month should fail because the original date is invalid
// assert_eq!(invalid_start_dt.with_month(2), Err(DateError::InvalidDate));