Last Day Of Month - parsicore/parsidate GitHub Wiki

Method last_day_of_month

Returns a new ParsiDate instance representing the last day of the month for the date represented by self.

Description

This method calculates the date corresponding to the very end of the month in which the current date (self) resides. It preserves the year and month from the self instance but calculates and sets the day component to the actual last day of that specific month.

The calculation determines the correct last day number (29, 30, or 31) by considering the month and whether the year of self is a Persian leap year (this is particularly relevant for determining if Esfand, month 12, has 29 or 30 days). This is typically done using the logic equivalent to ParsiDate::days_in_month(self.year(), self.month()).

Safety & Performance: For performance, this method may utilize unsafe { ParsiDate::new_unchecked } or a similar internal, optimized constructor, bypassing standard validation.

This optimization is considered safe based on the assumption that the self instance is already a valid ParsiDate. The reasoning is:

  1. If self is valid (which may be checked via debug_assert!(self.is_valid()) in debug builds), its year and month are valid components.
  2. The calculation ParsiDate::days_in_month(self.year(), self.month()) correctly determines the actual number of days (e.g., 29, 30, or 31) that exist in that specific month and year.
  3. Constructing a new ParsiDate using the valid self.year, self.month, and this correctly calculated last day number will inherently result in a valid ParsiDate.

Arguments

This method takes no arguments other than the implicit self reference to the ParsiDate instance it is called on.

Returns

  • A new ParsiDate instance representing the last day (day 29, 30, or 31) of the same month and year as the self instance.

Note: Because it assumes self is valid and the calculated last day is inherently valid for that month/year, this method typically returns a ParsiDate directly, not a Result.

Examples (Rust)

use parsidate::ParsiDate; // Assuming ParsiDate exists

// --- Month with 31 days (e.g., Farvardin) ---
let date_farvardin = ParsiDate::new(1403, 1, 15).unwrap(); // Farvardin 15th
let last_day_farvardin = date_farvardin.last_day_of_month();
assert_eq!(last_day_farvardin.day(), 31);
assert_eq!(last_day_farvardin, ParsiDate::new(1403, 1, 31).unwrap());

// --- Month with 30 days (e.g., Mehr) ---
let date_mehr = ParsiDate::new(1403, 7, 10).unwrap(); // Mehr 10th
let last_day_mehr = date_mehr.last_day_of_month();
assert_eq!(last_day_mehr.day(), 30);
assert_eq!(last_day_mehr, ParsiDate::new(1403, 7, 30).unwrap());

// --- Month 12 (Esfand) in a Leap Year (1403 is leap) ---
// Esfand has 30 days in a leap year.
let date_esfand_leap = ParsiDate::new(1403, 12, 5).unwrap(); // Esfand 5th, 1403
let last_day_esfand_leap = date_esfand_leap.last_day_of_month();
assert_eq!(last_day_esfand_leap.day(), 30);
assert_eq!(last_day_esfand_leap, ParsiDate::new(1403, 12, 30).unwrap());

// --- Month 12 (Esfand) in a Common Year (1404 is common) ---
// Esfand has 29 days in a common year.
let date_esfand_common = ParsiDate::new(1404, 12, 5).unwrap(); // Esfand 5th, 1404
let last_day_esfand_common = date_esfand_common.last_day_of_month();
assert_eq!(last_day_esfand_common.day(), 29);
assert_eq!(last_day_esfand_common, ParsiDate::new(1404, 12, 29).unwrap());

// --- Calling on a date that is already the last day ---
let last_day_already = ParsiDate::new(1402, 9, 30).unwrap(); // Azar 30th
let result_last = last_day_already.last_day_of_month();
// Should return the same date
assert_eq!(result_last, ParsiDate::new(1402, 9, 30).unwrap());