With Day - jalalvandi/ParsiDate GitHub Wiki

Method with_day

Creates a new ParsiDate instance by replacing the day component, validating the result.

Description

This method creates a new ParsiDate based on the current instance (self), but with the day of the month changed to the specified day value. The year and month components are copied directly from the original self instance.

Crucially, this method performs validation on the resulting date (original year, original month, new day) to ensure it is a valid date within the Persian calendar rules. It also implicitly checks if the starting self instance is valid before proceeding.

Arguments

  • day: The desired day of the month (u8 or similar integer type) for the new ParsiDate.

Returns

  • Ok(ParsiDate): If the original ParsiDate (self) is valid and the combination of self.year(), self.month(), and the new day forms a valid Persian date, returns the new ParsiDate instance wrapped in Ok.
  • Err(DateError::InvalidDate): Returns an error if either of the following conditions is met:
    1. The starting ParsiDate instance (self) is invalid (e.g., contains month 0 or 13, potentially from unsafe creation).
    2. The provided day value is invalid for the specific self.year() and self.month(). This includes:
      • day is 0.
      • day is greater than 31 for months 1-6.
      • day is greater than 30 for months 7-11.
      • day is greater than 30 for month 12 (Esfand) in a leap year.
      • day is greater than 29 for month 12 (Esfand) in a common year.

Examples (Rust)

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

let date = ParsiDate::new(1403, 7, 1).unwrap(); // Mehr 1st, 1403 (Mehr has 30 days)

// --- Success Cases ---

// Change day to 15 (valid for Mehr)
let date_mid_month = date.with_day(15);
assert!(date_mid_month.is_ok());
assert_eq!(date_mid_month.unwrap(), ParsiDate::new(1403, 7, 15).unwrap());

// Change day to 30 (last valid day of Mehr)
let date_end_month = date.with_day(30);
assert!(date_end_month.is_ok());
assert_eq!(date_end_month.unwrap(), ParsiDate::new(1403, 7, 30).unwrap());


// --- Error Cases ---

// Try setting day to 31 in Mehr (which only has 30 days)
assert_eq!(
    date.with_day(31),
    Err(DateError::InvalidDate) // Day 31 is invalid for month 7
);

// Try setting day to 0 (always invalid)
assert_eq!(
    date.with_day(0),
    Err(DateError::InvalidDate) // Day 0 is invalid
);

// --- Examples with Esfand (Month 12) ---

// Leap year: 1403 is leap, Esfand has 30 days
let date_esfand_leap = ParsiDate::new(1403, 12, 1).unwrap();
// Setting day to 30 is OK
assert!(date_esfand_leap.with_day(30).is_ok());
assert_eq!(date_esfand_leap.with_day(30).unwrap(), ParsiDate::new(1403, 12, 30).unwrap());
// Setting day to 31 is invalid
assert_eq!(
    date_esfand_leap.with_day(31),
    Err(DateError::InvalidDate)
);

// Common year: 1404 is common, Esfand has 29 days
let date_esfand_common = ParsiDate::new(1404, 12, 1).unwrap();
// Setting day to 29 is OK
assert!(date_esfand_common.with_day(29).is_ok());
assert_eq!(date_esfand_common.with_day(29).unwrap(), ParsiDate::new(1404, 12, 29).unwrap());
// Setting day to 30 is invalid
assert_eq!(
    date_esfand_common.with_day(30),
    Err(DateError::InvalidDate)
);


// --- Error Case: Starting date is invalid ---
let invalid_start = unsafe { ParsiDate::new_unchecked(1400, 13, 1) }; // Invalid month 13
// Trying to change the day of an already invalid date should fail
assert_eq!(
    invalid_start.with_day(15),
    Err(DateError::InvalidDate) // Original date invalid
);