icu4x icon indicating copy to clipboard operation
icu4x copied to clipboard

Dates don't roundtrip when converting to ISO and back again with non-always-calculating IslamicObservational/IslamicUmmAlQura calendars

Open anba opened this issue 1 year ago • 2 comments

The following test case doesn't pass when checking converting to an ISO date and back again returns the same month. When switching to new_always_calculating the test case does succeed.

This is a regression in release 1.5. It still worked correctly in release 1.4.

Test case:

use icu::calendar::types::{Era, MonthCode};
use icu::calendar::Calendar;
use icu::calendar::Ref;

use icu::calendar::islamic::{IslamicObservational, IslamicUmmAlQura};

use std::str::FromStr;

fn test_IslamicObservational() {
  // let cal = IslamicObservational::new_always_calculating();
  let cal = IslamicObservational::new();

  let cal = Ref(&cal);

  let era = Era::from_str("ah").unwrap();
  let month_code = MonthCode::from_str("M01").unwrap();

  let dt = cal.date_from_codes(era, 1390, month_code, 30).unwrap();

  let month = cal.month(&dt);
  assert!(month.code == month_code);

  let iso = cal.date_to_iso(&dt);
  let dt2 = cal.date_from_iso(iso);

  let month = cal.month(&dt2);
  assert!(month.code == month_code);
}

fn test_IslamicUmmAlQura() {
  // let cal = IslamicUmmAlQura::new_always_calculating();
  let cal = IslamicUmmAlQura::new();

  let cal = Ref(&cal);

  let era = Era::from_str("ah").unwrap();
  let month_code = MonthCode::from_str("M01").unwrap();

  let dt = cal.date_from_codes(era, 1391, month_code, 30).unwrap();

  let month = cal.month(&dt);
  assert!(month.code == month_code);

  let iso = cal.date_to_iso(&dt);
  let dt2 = cal.date_from_iso(iso);

  let month = cal.month(&dt2);
  assert!(month.code == month_code);
}

fn main() {
  test_IslamicObservational();
  test_IslamicUmmAlQura();
}

anba avatar Jun 18 '24 07:06 anba

day_of_month can return zero for some dates when using the non-always-calculating constructor. That's probably a related issue:

use icu::calendar::Date;
use icu::calendar::Calendar;
use icu::calendar::islamic::IslamicObservational;

fn main() {
  // let cal = IslamicObservational::new_always_calculating();
  let cal = IslamicObservational::new();

  let iso = Date::try_new_iso_date(2000, 5, 5).unwrap();
  let date = cal.date_from_iso(iso);

  println!("month = {}", cal.month(&date).ordinal);
  println!("day = {}", cal.day_of_month(&date).0);
}

anba avatar Jun 18 '24 08:06 anba

cc @sffc

Manishearth avatar Jun 20 '24 21:06 Manishearth