To Gregorian (ParsiDateTime) - parsicore/parsidate GitHub Wiki

Method to_gregorian (on ParsiDateTime)

Converts this ParsiDateTime instance to its equivalent Gregorian chrono::NaiveDateTime.

Description

This function performs a conversion from the Persian (Hejri-Shamsi) date and time represented by self to the corresponding Gregorian date and time, represented by chrono::NaiveDateTime (which has no timezone information).

The conversion process is typically:

  1. Validation: First, the method checks the validity of the current ParsiDateTime instance (self). It verifies both the date part (using logic similar to ParsiDate::is_valid) and the time part (hour 0-23, minute/second 0-59).
  2. Date Conversion: If the date part is valid, it converts the ParsiDate component into a chrono::NaiveDate using the underlying Gregorian conversion algorithm (similar to ParsiDate::to_gregorian).
  3. Time Combination: If the time part is also valid and the date conversion succeeded, it combines the resulting chrono::NaiveDate with the original hour, minute, and second values from self to create the final chrono::NaiveDateTime. Nanoseconds are typically not included unless the ParsiDateTime struct stores them.

Returns

  • Ok(chrono::NaiveDateTime): If the ParsiDateTime instance is valid (both date and time parts) and the conversion is successful, returns the equivalent Gregorian date and time wrapped in Ok.
  • Err(DateError::...): Returns an error if the validation or conversion fails. See the Errors section for details.

Errors

Returns Err in the following cases:

  • DateError::InvalidDate: If the date part of the ParsiDateTime instance (self.date()) is invalid. This typically occurs if the instance was created using unsafe ParsiDateTime::new_unchecked with invalid year, month, or day values (e.g., Esfand 30th in a common year).
  • DateError::InvalidTime: If the time part of the ParsiDateTime instance (self.hour(), self.minute(), self.second()) contains values outside their valid ranges (H: 0-23, M: 0-59, S: 0-59). This might also occur if the instance was created using unsafe.
  • DateError::GregorianConversionError: If the conversion of the (valid) ParsiDate component to a chrono::NaiveDate fails internally. This is generally unexpected for valid Persian dates within the library's supported range but could theoretically happen due to epoch boundary issues or internal conversion logic errors. It might also potentially occur if NaiveDate::and_hms_opt (or similar chrono function) fails when combining the date and time, although this is unlikely if the time components have already been validated.

Examples (Rust)

use chrono::{NaiveDate, NaiveTime, NaiveDateTime};
use parsidate::{ParsiDateTime, ParsiDate, DateError}; // Assuming these types exist

// --- Example 1: Successful Conversion ---
// Define a ParsiDateTime
let pd_dt = ParsiDateTime::new(1403, 5, 2, 15, 30, 45).unwrap(); // Mordad 2nd, 1403, 15:30:45

// Convert to Gregorian NaiveDateTime
let g_dt_result = pd_dt.to_gregorian();
assert!(g_dt_result.is_ok());
let g_dt = g_dt_result.unwrap();

// Define the expected Gregorian equivalent
let expected_g_date = NaiveDate::from_ymd_opt(2024, 7, 23).unwrap();
let expected_g_time = NaiveTime::from_hms_opt(15, 30, 45).unwrap();
let expected_g_dt = NaiveDateTime::new(expected_g_date, expected_g_time); // 2024-07-23 15:30:45

// Assert equality
assert_eq!(g_dt, expected_g_dt);


// --- Example 2: Error due to Invalid Date Part ---
// Create an invalid ParsiDateTime (invalid date) unsafely
let invalid_pd_dt = unsafe { ParsiDateTime::new_unchecked(1404, 12, 30, 10, 0, 0) }; // Esfand 30 in common year 1404
assert!(!invalid_pd_dt.is_valid()); // Verify it's considered invalid

// Attempt conversion - should fail due to invalid date
assert_eq!(
    invalid_pd_dt.to_gregorian(),
    Err(DateError::InvalidDate) // Expect InvalidDate error
);


// --- Example 3: Error due to Invalid Time Part ---
// Create an invalid ParsiDateTime (invalid time) unsafely
let invalid_time_pd_dt = unsafe { ParsiDateTime::new_unchecked(1403, 1, 1, 25, 0, 0) }; // Hour 25 is invalid
assert!(!invalid_time_pd_dt.is_valid()); // Verify it's considered invalid

// Attempt conversion - should fail due to invalid time
assert_eq!(
    invalid_time_pd_dt.to_gregorian(),
    Err(DateError::InvalidTime) // Expect InvalidTime error
);