Is Valid - parsicore/parsidate GitHub Wiki

Method is_valid

Checks whether the date represented by this ParsiDate instance (self) is valid according to the rules of the Persian calendar and the supported range of this library.

Description

This method performs a comprehensive validation of the year, month, and day components stored within the ParsiDate instance (self). It verifies the date against the following criteria:

  1. Year Range: The year must be within the supported range, typically 1 to 9999 (inclusive).
  2. Month Range: The month must be between 1 and 12 (inclusive).
  3. Day Range: The day must be:
    • At least 1.
    • Not greater than the number of days in the specified month of the specified year. This check correctly accounts for:
      • Months 1-6 having 31 days.
      • Months 7-11 having 30 days.
      • Month 12 (Esfand) having 30 days if the year is a Persian leap year, and 29 days if it is a common year.

This method is crucial for validating ParsiDate instances, especially those potentially created using unsafe constructors like new_unchecked which bypass standard validation. It is typically used internally by safe constructors like ParsiDate::new to ensure only valid dates are created.

Arguments

This method takes no arguments other than the implicit self reference to the ParsiDate instance it is called on.

Returns

  • true if the combination of year, month, and day stored in self represents a valid date within the Persian calendar and the library's supported range.
  • false otherwise (if any of the validation criteria listed above are not met).

Note: This method performs checks and returns a boolean; it does not return a Result or indicate specific error types.

Examples (Rust)

use parsidate::ParsiDate; // Assuming ParsiDate and its constructors exist

// --- Valid Dates ---

// Standard valid date
let valid_date_1 = ParsiDate::new(1403, 1, 1).unwrap();
assert!(valid_date_1.is_valid());

// Valid leap day (Esfand 30th in a leap year like 1403)
let valid_leap_day = ParsiDate::new(1403, 12, 30).unwrap();
assert!(valid_leap_day.is_valid());

// Valid last day of Esfand in a common year (1404)
let valid_common_esfand_end = ParsiDate::new(1404, 12, 29).unwrap();
assert!(valid_common_esfand_end.is_valid());

// Valid date at the edge of the supported year range (assuming 9999 is max)
// 9999 is likely a common year in the 33-year cycle; adjust if needed based on lib's rule
let valid_max_year_date = ParsiDate::new(9999, 12, 29).unwrap(); // Assuming 9999 is common
assert!(valid_max_year_date.is_valid());

// First supported year
let valid_min_year_date = ParsiDate::new(1, 1, 1).unwrap();
assert!(valid_min_year_date.is_valid());


// --- Invalid Dates (Potentially Created with `unsafe new_unchecked`) ---

// Requires `unsafe` block to bypass standard ParsiDate::new() validation
unsafe {
    // Invalid day: Esfand 30th in a common year (1404)
    let invalid_day = ParsiDate::new_unchecked(1404, 12, 30);
    assert!(!invalid_day.is_valid());

    // Invalid day: Day 32 in a 31-day month
    let invalid_day_32 = ParsiDate::new_unchecked(1403, 1, 32);
    assert!(!invalid_day_32.is_valid());

    // Invalid day: Day 31 in a 30-day month
    let invalid_day_31 = ParsiDate::new_unchecked(1403, 7, 31);
    assert!(!invalid_day_31.is_valid());

    // Invalid day: Day 0
    let invalid_day_zero = ParsiDate::new_unchecked(1403, 1, 0);
    assert!(!invalid_day_zero.is_valid());

    // Invalid month: Month 13
    let invalid_month_13 = ParsiDate::new_unchecked(1403, 13, 1);
    assert!(!invalid_month_13.is_valid());

    // Invalid month: Month 0
    let invalid_month_zero = ParsiDate::new_unchecked(1403, 0, 1);
    assert!(!invalid_month_zero.is_valid());

    // Invalid year: Year 0 (below minimum supported year 1)
    let invalid_year_zero = ParsiDate::new_unchecked(0, 1, 1);
    assert!(!invalid_year_zero.is_valid());

    // Invalid year: Year 10000 (above maximum supported year 9999)
    let invalid_year_high = ParsiDate::new_unchecked(10000, 1, 1);
    assert!(!invalid_year_high.is_valid());
}