Sub Days - jalalvandi/ParsiDate GitHub Wiki

Method sub_days

Subtracts a specified number of days from this ParsiDate, returning a new ParsiDate.

Description

This method provides a convenient way to calculate the date that occurs a given number of days before the current ParsiDate instance.

It functions as a direct equivalent to calling the add_days method with a negative value for the number of days (i.e., self.add_days(-days) if add_days accepted negative values, or more realistically, it uses the same internal logic adapted for subtraction).

The calculation typically involves:

  1. Converting the current ParsiDate to an internal representation (like a Julian Day Number or using a compatible date/time library like chrono).
  2. Performing the subtraction arithmetic on that representation.
  3. Converting the result back into a ParsiDate.

Arguments

  • days: The non-negative number of days (u32, u64, or similar unsigned integer type) to subtract from the current date.

Returns

  • Ok(ParsiDate): If the subtraction results in a valid date within the supported range of the library (typically years 1 to 9999), returns the new ParsiDate instance wrapped in Ok.
  • Err(DateError::...): Returns an error under the same conditions as the add_days method (when performing the equivalent addition of a negative number). This primarily occurs if:
    • The resulting date falls outside the supported year range (e.g., subtracting days from an early date results in a year less than 1).
    • An arithmetic overflow or other internal error occurs during the calculation (though less common with subtraction unless dealing with extremely large days values relative to the internal representation). Refer to add_days documentation for specific error kinds like DateError::ArithmeticOverflow or DateError::InvalidDate.

Examples (Rust)

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

let date = ParsiDate::new(1404, 1, 3).unwrap(); // Farvardin 3rd, 1404 (a common year)

// --- Basic Subtraction ---

// Subtract 1 day
assert_eq!(
    date.sub_days(1),
    Ok(ParsiDate::new(1404, 1, 2).unwrap()) // -> 1404-01-02
);

// Subtract 2 days
assert_eq!(
    date.sub_days(2),
    Ok(ParsiDate::new(1404, 1, 1).unwrap()) // -> 1404-01-01
);


// --- Crossing Year Boundary ---

// Subtract 3 days: crosses into the previous year (1403, which was a leap year)
assert_eq!(
    date.sub_days(3),
    Ok(ParsiDate::new(1403, 12, 30).unwrap()) // -> Lands on the leap day of 1403
);

// Subtract 4 days
assert_eq!(
    date.sub_days(4),
    Ok(ParsiDate::new(1403, 12, 29).unwrap()) // -> 1403-12-29
);


// --- Subtracting a Larger Number ---

let date_mid_year = ParsiDate::new(1403, 6, 15).unwrap(); // Shahrivar 15th, 1403
// Calculate 100 days before 1403-06-15:
// Days remaining in Shahrivar: 15
// Days in Mordad: 31 (Total 46)
// Days in Tir: 31 (Total 77)
// Days needed from Khordad: 100 - 77 = 23
// Khordad has 31 days. Day = 31 - 23 = 8. -> Khordad 8th
assert_eq!(
    date_mid_year.sub_days(100),
    Ok(ParsiDate::new(1403, 3, 8).unwrap()) // -> 1403-03-08
);


// --- Example Resulting in Error (Going Below Year 1) ---

let earliest_date = ParsiDate::new(1, 1, 1).unwrap(); // The first supported date
let result = earliest_date.sub_days(1);
// Subtracting 1 day results in year 0, which is outside the supported range [1, 9999]
assert!(result.is_err());
// Optionally check the specific error type if needed and known
// assert_eq!(result, Err(DateError::InvalidDate)); // Or similar error

let result_large_sub = ParsiDate::new(5, 1, 1).unwrap().sub_days(5 * 366); // Subtracting > 5 years
assert!(result_large_sub.is_err()); // Likely goes below year 1