Days Between - jalalvandi/ParsiDate GitHub Wiki

Method days_between

Calculates the absolute difference in days between this ParsiDate (self) and another provided ParsiDate (other).

Description

This method computes the total number of days separating two distinct points in time represented by ParsiDate instances. The result is always non-negative, representing the magnitude of the duration between the two dates, regardless of which date occurs earlier chronologically.

The calculation is performed reliably by:

  1. Converting both the self ParsiDate and the other ParsiDate into their equivalent chrono::NaiveDate (Gregorian) representations.
  2. Calculating the duration between these two NaiveDate instances using chrono's functionality.
  3. Returning the absolute number of days from that duration.

This approach ensures accurate handling of varying month lengths and leap years (both Gregorian during calculation and implicitly Persian via the initial conversion).

Arguments

  • other: A reference (&ParsiDate) to the other ParsiDate instance against which the difference should be calculated.

Returns

  • Ok(i64): If both self and other are valid ParsiDate instances and their conversion to NaiveDate succeeds, returns the absolute number of days between the two dates as an i64, wrapped in Ok. Returns Ok(0) if self and other represent the exact same date.
  • Err(DateError::InvalidDate): If either the self instance or the other instance represents an invalid date according to Persian calendar rules.
  • Err(DateError::GregorianConversionError): If the conversion of either self or other from ParsiDate to chrono::NaiveDate fails. This is generally unlikely for valid dates but could occur in edge cases.

Examples (Rust)

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

// --- Basic Difference Calculation ---
let d1 = ParsiDate::new(1403, 1, 1).unwrap();   // Start of 1403
let d2 = ParsiDate::new(1403, 1, 11).unwrap();  // 10 days later
let d3 = ParsiDate::new(1403, 2, 1).unwrap();   // Start of next month (Farvardin has 31 days)

// Difference within the same month
let diff1_2 = d1.days_between(&d2);
assert_eq!(diff1_2, Ok(10));

// Difference across a month boundary
// Days = (31 - 1) [days left in Farvardin] + 1 [day in Ordibehesht] = 31
let diff1_3 = d1.days_between(&d3);
assert_eq!(diff1_3, Ok(31));

// The order doesn't matter (absolute difference)
let diff2_1 = d2.days_between(&d1);
assert_eq!(diff2_1, Ok(10));


// --- Difference Across Year Boundary (Handling Leap Year) ---
let d_start_1403 = ParsiDate::new(1403, 1, 1).unwrap();
let d_start_1404 = ParsiDate::new(1404, 1, 1).unwrap();

// 1403 is a leap year in the Persian calendar, so it has 366 days
let diff_year = d_start_1403.days_between(&d_start_1404);
assert_eq!(diff_year, Ok(366));

// Difference from a date within the leap year to the next year
let d_mid_1403 = ParsiDate::new(1403, 12, 30).unwrap(); // Leap day
let diff_leap_to_next = d_mid_1403.days_between(&d_start_1404);
assert_eq!(diff_leap_to_next, Ok(1));


// --- Identical Dates ---
let d_same1 = ParsiDate::new(1400, 6, 15).unwrap();
let d_same2 = ParsiDate::new(1400, 6, 15).unwrap();
let diff_same = d_same1.days_between(&d_same2);
assert_eq!(diff_same, Ok(0));


// --- Potential Error Cases ---
// If one date was invalid (hypothetical invalid constructor)
// let invalid_date = ParsiDate { year: 1400, month: 13, day: 1 }; // Invalid month
// let valid_date = ParsiDate::new(1400, 1, 1).unwrap();
// assert!(invalid_date.days_between(&valid_date).is_err());
// assert!(valid_date.days_between(&invalid_date).is_err());