New Unchecked (ParsiDateTime) - parsicore/parsidate GitHub Wiki

Constructor ParsiDateTime::new_unchecked (unsafe)

Creates a new ParsiDateTime instance from individual components without performing any validation checks.

⚠️ Warning: Unsafe Operation ⚠️

This function is marked unsafe because it completely bypasses the validation checks normally performed by the safe ParsiDateTime::new constructor for both the date and time components.

  • If you provide invalid components (e.g., month = 13, day = 32, hour = 25, minute = 60, or an impossible date like Esfand 30th in a common year), this function will still create a ParsiDateTime instance containing that invalid data.
  • Subsequent operations on such an invalid ParsiDateTime instance (like formatting, comparison, arithmetic, conversion, or even basic getters if they rely on internal consistency) can lead to unpredictable behavior, incorrect results, logic errors, or runtime panics.

Do not use this function unless you meet the following conditions:

  1. You have already rigorously validated all input components (year, month, day, hour, minute, second) through external means before calling this function.
  2. You have an absolute performance requirement that necessitates skipping the validation overhead of ParsiDateTime::new.

In almost all typical use cases, the safe ParsiDateTime::new constructor is the strongly preferred and recommended choice.

Safety Contract

The caller MUST guarantee that the provided components collectively represent a valid Persian date and time:

  1. Date Validity: The year, month, and day combination must form a logically valid date within the rules of the Persian (Hejri-Shamsi) calendar, including:
    • year is within the supported range (e.g., [1, 9999]).
    • month is between 1 and 12 (inclusive).
    • day is between 1 and the correct number of days for the given month and year (considering leap years for Esfand).
  2. Time Validity: The hour, minute, and second components must be within their standard ranges:
    • hour must be in the range 0-23 (inclusive).
    • minute must be in the range 0-59 (inclusive).
    • second must be in the range 0-59 (inclusive).

Failure to uphold this guarantee for any component violates the safety contract and invokes undefined behavior from the perspective of this library's date/time logic, potentially leading to the issues mentioned in the warning above.

Arguments

  • year (i32 or similar): The year component. Must be pre-validated by the caller.
  • month (u8 or similar): The month component. Must be pre-validated by the caller.
  • day (u8 or similar): The day component. Must be pre-validated by the caller.
  • hour (u8 or similar): The hour component. Must be pre-validated by the caller (0-23).
  • minute (u8 or similar): The minute component. Must be pre-validated by the caller (0-59).
  • second (u8 or similar): The second component. Must be pre-validated by the caller (0-59).

Returns

  • A ParsiDateTime instance containing the provided components, regardless of whether they form a valid date and time.

Examples (Rust)

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

// --- !!! Incorrect Usage Example !!! ---
// DO NOT DO THIS unless inputs are guaranteed valid elsewhere.
// Creating an object with multiple invalid components.
// let invalid_dt = unsafe { ParsiDateTime::new_unchecked(1404, 12, 30, 25, 61, 99) };
// This object `invalid_dt` now holds nonsensical data.
// assert!(!invalid_dt.is_valid()); // Checking validity later confirms it's bad.
// Using invalid_dt further could lead to panics or incorrect results.


// --- Correct Usage Example (with Prior Validation) ---

// Assume these components have been rigorously validated elsewhere
let p_year = 1403;   // Leap year
let p_month = 12;  // Esfand
let p_day = 30;    // Valid day for Esfand in 1403
let hour = 23;
let minute = 59;
let second = 59;

// --- Example Pre-validation (replace with robust validation) ---
// You might use ParsiDateTime::new().is_ok() or separate checks.
let is_valid_date = ParsiDate::new(p_year, p_month, p_day).is_ok();
let is_valid_time = hour <= 23 && minute <= 59 && second <= 59;
// --- End Example Pre-validation ---

// Only call new_unchecked if *all* validation passed
if is_valid_date && is_valid_time {
    println!("Validation passed, proceeding with unsafe construction.");
    // It's now considered safe to use new_unchecked because the caller
    // has upheld the safety contract by validating all components.
    let dt = unsafe {
        ParsiDateTime::new_unchecked(p_year, p_month, p_day, hour, minute, second)
    };

    // Verify the components were stored correctly
    assert_eq!(dt.year(), 1403);
    assert_eq!(dt.month(), 12);
    assert_eq!(dt.day(), 30);
    assert_eq!(dt.hour(), 23);
    assert_eq!(dt.minute(), 59);
    assert_eq!(dt.second(), 59);
    assert!(dt.is_valid()); // Should pass if pre-validation was correct

} else {
    // If validation failed for any component, DO NOT call new_unchecked.
    eprintln!(
        "Validation failed for Y={}, M={}, D={}, H={}, Min={}, S={}. Cannot use new_unchecked.",
        p_year, p_month, p_day, hour, minute, second
    );
    // Handle the error appropriately (e.g., return Err, panic, log).
}