With Year (ParsiDateTime) - jalalvandi/ParsiDate GitHub Wiki

Method with_year (on ParsiDateTime)

Creates a new ParsiDateTime instance with only the year component of the date changed, preserving month, day, and all time components.

Description

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

The core logic for changing the year and handling date validation (specifically, adjustments for the 30th day of Esfand in non-leap vs. leap years) is delegated to the underlying ParsiDate::with_year method. If changing the year results in an invalid date (e.g., changing Esfand 30th from a leap year to a non-leap year), the underlying method will handle this, typically by adjusting the day or returning an error.

Arguments

  • year: The desired new Persian year (i32 or similar integer type) for the new ParsiDateTime.

Returns

  • Ok(ParsiDateTime): If the underlying ParsiDate::with_year call succeeds (meaning the resulting date is valid, considering leap year rules), returns the new ParsiDateTime instance (with the updated year and original month, day, and time) wrapped in Ok. The day might be adjusted (e.g., from Esfand 30th to 29th) if necessary due to leap year changes.
  • Err(DateError::InvalidDate): If the underlying call to ParsiDate::with_year fails. This typically happens if the combination of the new year and the original month/day results in an invalid date according to Persian calendar rules after potential adjustments (although ParsiDate::with_year usually adjusts the day for leap year changes rather than erroring directly, specific implementations might vary). It could also potentially return an error if the original date was somehow invalid.

Examples (Rust)

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

// --- Success Case: Change Year (Simple) ---
let dt = ParsiDateTime::new(1403, 5, 2, 10, 30, 0).unwrap(); // 1403-05-02 10:30:00

// Change year to 1399
let dt_new_year_result = dt.with_year(1399);
assert!(dt_new_year_result.is_ok());
let dt_new_year = dt_new_year_result.unwrap();

// Verify the new year and preserved components
assert_eq!(dt_new_year.year(), 1399);
assert_eq!(dt_new_year.month(), 5); // Month unchanged
assert_eq!(dt_new_year.day(), 2);   // Day unchanged
assert_eq!(dt_new_year.hour(), 10); // Hour unchanged
assert_eq!(dt_new_year.minute(), 30);// Minute unchanged
assert_eq!(dt_new_year.second(), 0); // Second unchanged
assert_eq!(dt_new_year.time(), (10, 30, 0)); // Verify time tuple


// --- Success Case: Change Year with Leap Day Adjustment ---
// 1403 is a leap year in the Persian calendar.
let dt_leap = ParsiDateTime::new(1403, 12, 30, 11, 0, 0).unwrap(); // Esfand 30th, 1403 (valid leap day)

// Change to 1404, which is NOT a leap year.
let dt_non_leap_year_result = dt_leap.with_year(1404);
assert!(dt_non_leap_year_result.is_ok());
let dt_non_leap_year = dt_non_leap_year_result.unwrap();

// The date should be adjusted to the last day of Esfand in a non-leap year (the 29th).
assert_eq!(dt_non_leap_year.year(), 1404);
assert_eq!(dt_non_leap_year.month(), 12);
assert_eq!(dt_non_leap_year.day(), 29); // Day adjusted from 30 to 29
assert_eq!(dt_non_leap_year.date(), ParsiDate::new(1404, 12, 29).unwrap()); // Verify full date
assert_eq!(dt_non_leap_year.time(), (11, 0, 0)); // Time unchanged


// --- Potential Error Case (Implementation Dependent) ---
// Although `with_year` usually adjusts, if it were designed to error on invalid combinations
// before adjustment, or if an extremely invalid year was passed, an error might occur.
// Example: If ParsiDate::with_year had stricter rules or limits.
// let result_invalid = dt.with_year(-10000); // Hypothetical invalid year
// assert!(result_invalid.is_err());
// assert_eq!(result_invalid, Err(DateError::InvalidDate)); // Or a different error?