From Gregorian (ParsiDateTime) - parsicore/parsidate GitHub Wiki
ParsiDateTime::from_gregorian
Static Function Converts a Gregorian chrono::NaiveDateTime
to its equivalent ParsiDateTime
.
Description
This function takes a chrono::NaiveDateTime
instance, which represents a specific date and time in the Gregorian calendar (without timezone information), and converts it into the corresponding ParsiDateTime
in the Persian (Hejri-Shamsi) calendar.
The conversion process involves these steps:
- Extracts the date component (
chrono::NaiveDate
) from the inputgregorian_dt
. - Converts this
NaiveDate
into aParsiDate
using the logic provided byParsiDate::from_gregorian
. This handles the core calendar conversion logic. - Extracts the time components (hour, minute, second) directly from the input
gregorian_dt
. Note: Nanoseconds present in the inputNaiveDateTime
are ignored and not preserved in the resultingParsiDateTime
. - Combines the successfully converted
ParsiDate
and the extracted time components (hour, minute, second) to create the finalParsiDateTime
instance.
Arguments
gregorian_dt
: Thechrono::NaiveDateTime
instance to convert.
Returns
Ok(ParsiDateTime)
: If the conversion of the date part is successful, returns the resultingParsiDateTime
instance wrapped inOk
.Err(DateError::GregorianConversionError)
: If the conversion of the date part fails. This error is propagated from the underlying call toParsiDate::from_gregorian
.
Error Conditions
The primary reason for failure is an error during the conversion of the date component:
DateError::GregorianConversionError
: This typically occurs if the date part of the inputgregorian_dt
represents a Gregorian date that:- Falls before the start of the Persian calendar epoch (approximately March 21st, 622 CE).
- Results in a Persian date outside the year range supported by
ParsiDate
(e.g., year 0 or year 10000+).
Examples (Rust)
use chrono::{NaiveDate, NaiveTime, NaiveDateTime};
use parsidate::{ParsiDateTime, ParsiDate, DateError}; // Assuming these types exist
// --- Example 1: Standard Conversion ---
// Define a Gregorian NaiveDateTime
let g_date = NaiveDate::from_ymd_opt(2024, 7, 23).unwrap();
let g_time = NaiveTime::from_hms_opt(15, 30, 45).unwrap();
let g_dt = NaiveDateTime::new(g_date, g_time); // Gregorian: 2024-07-23 15:30:45
// Convert to ParsiDateTime
let pd_dt_result = ParsiDateTime::from_gregorian(g_dt);
assert!(pd_dt_result.is_ok());
let pd_dt = pd_dt_result.unwrap();
// Verify the Persian date and time components
// Expected Persian date: 1403-05-02 (Mordad 2nd, 1403)
assert_eq!(pd_dt.date(), ParsiDate::new(1403, 5, 2).unwrap());
assert_eq!(pd_dt.hour(), 15);
assert_eq!(pd_dt.minute(), 30);
assert_eq!(pd_dt.second(), 45);
// --- Example 2: Nanosecond Truncation ---
// Gregorian datetime with nanoseconds: March 21, 2023, 00:00:01.123456789
// This corresponds to the start of the Persian year 1402.
let g_dt_nano = NaiveDate::from_ymd_opt(2023, 3, 21).unwrap()
.and_hms_nano_opt(0, 0, 1, 123_456_789).unwrap();
// Convert to ParsiDateTime
let pd_dt_nano_result = ParsiDateTime::from_gregorian(g_dt_nano);
assert!(pd_dt_nano_result.is_ok());
let pd_dt_nano = pd_dt_nano_result.unwrap();
// Verify the components - nanoseconds should be lost
assert_eq!(pd_dt_nano.date(), ParsiDate::new(1402, 1, 1).unwrap()); // Farvardin 1st, 1402
assert_eq!(pd_dt_nano.hour(), 0);
assert_eq!(pd_dt_nano.minute(), 0);
assert_eq!(pd_dt_nano.second(), 1); // Seconds are kept, nanoseconds are truncated
// --- Example 3: Date Before Persian Epoch (Error Case) ---
// Define a Gregorian date well before the Persian epoch (~622 CE)
let g_dt_early = NaiveDate::from_ymd_opt(600, 1, 1).unwrap()
.and_hms_opt(0, 0, 0).unwrap(); // January 1st, 600 CE
// Attempt conversion
let result_early = ParsiDateTime::from_gregorian(g_dt_early);
// Expect an error because the date is out of the convertible range
assert!(result_early.is_err());
assert_eq!(result_early, Err(DateError::GregorianConversionError));