gpt4 book ai didi

javascript - 伊斯兰(回历)日历的 Javascript Intl.DateTimeFormat() 输出在 'islamic' 和 'ar-SA' 之间存在差异

转载 作者:行者123 更新时间:2023-12-05 00:28:42 26 4
gpt4 key购买 nike

2022 年 3 月 3 日是这个回历月的结束(今年 1443 AH 的 Rajab 月);即 30 Rajab 1443 AH。
根据伊斯兰(回历)日历,根据所有网站、应用程序、MS Office 和 Windows 日历,伊斯兰历 1443 年的 Rajab 月是 30 天。
使用 javascript Intl.DateTimeFormat() 时显示 的伊斯兰(回历)日期2022 年 3 月 3 日 使用 islamic日历选项,它将给出伊斯兰回历日期(1 Shaʻban 1443 AH )。此结果是 Rajab 月后的一天(即下个月的 1 日),它计算 Rajab 月为 29 天而不是 30 天。
但是,如果选项传递给 Intl.DateTimeFormat()ar-SA (即阿拉伯语-沙特阿拉伯),它将给出正确的结果。 这很奇怪,因为 ar-SA语言环境默认使用伊斯兰 (Hijri) 日历。
这是一个错误/错误还是 javascript 的正确内部工作方式?
除了使用 之外,还有更强大的方法可以在 Javascript 中获取伊斯兰日期吗? 'ar-SA' 语言环境(但不使用外部库)?
请参见下面的代码示例:
我已经在 node 和 chrome 中对此进行了测试,它给出了相同的结果差异。

let date = new Date("2022-03-03");
let options = {year:'numeric', month:'long',day:'numeric'};

let format = new Intl.DateTimeFormat('ar-SA-u-nu-latn', options);
console.log("3 March 2022 with 'ar-SA' :"+format.format(date)+ " ==> means: 30 Rajab 1443 AH");

format = new Intl.DateTimeFormat('en-u-ca-islamic-nu-latn', options);
console.log("3 March 2022 with Islamic Calendar: "+format.format(date));

最佳答案

您看到的“提前一晚”日期问题可能有以下三个原因:

  • 日期初始化和日期格式之间的时区不匹配
  • 使用错误的伊斯兰日历变体(JS 实现通常提供 5 种不同的伊斯兰日历!)
  • 用于 JS 日历计算的 ICU 库中的错误

  • 我将在下面介绍每一个。
    1. 日期初始化和日期格式时区不匹配
    一天错误的最常见原因是(正如他在上面的评论中指出的 @RobG)在声明 Date 时使用的时区不匹配。值和在所需日历中对其进行格式化时使用的时区。
    当您使用 ISO 8601 字符串初始化 Date 实例时,存储在 Date 实例中的实际值是自 1970 年 1 月 1 日 UTC 以来的毫秒数。根据您的系统时区, new Date('2022-02-03')可以是系统时区的 2 月 3 日或 2 月 2 日。避免此问题的一种方法是在格式化时也使用 UTC:
    new Date('2022-03-03').toLocaleDateString('en-US');
    // outputs '3/2/2022' when run in San Francisco

    new Date('2022-03-03').toLocaleDateString('en-US', { timeZone: 'UTC' });
    // outputs '3/3/2022' as expected. UTC is used both for declaring and formatting.

    new Date('2022-03-03').toLocaleDateString(
    'en-SA-u-ca-islamic-umalqura',
    { timeZone: 'UTC', month: 'long', day: 'numeric', year: 'numeric' }
    );
    // outputs 'Rajab 30, 1443 AH' as expected
    请注意,我使用的是 Date.toLocaleDateString上面,但结果与使用 Intl.DateTimeFormat.format 相同.两种方法的参数和实现是相同的。
    2. 使用错误的伊斯兰历法(JS 实现通常提供 5 种不同的伊斯兰历法!)
    第二个更微妙的问题是 JavaScript 中使用了多种伊斯兰日历。支持的日历列表在这里: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/calendars .摘自该页面,以下是受支持的伊斯兰日历变体:
    • islamic
      • Islamic calendar
    • islamic-umalqura
      • Islamic calendar, Umm al-Qura
    • islamic-tbla
      • Islamic calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - astronomical epoch)
    • islamic-civil
      • Islamic calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - civil epoch)
    • islamic-rgsa
      • Islamic calendar, Saudi Arabia sighting

    (还有一个已弃用的 islamicc 日历,但应该使用 islamic-civil。) ar-SA 的默认日历语言环境是 islamic-umalqura日历,而不是 islamic日历。验证:
    new Intl.DateTimeFormat('ar-SA').resolvedOptions();
    // {
    // calendar: "islamic-umalqura"
    // day: "numeric"
    // locale: "ar-SA"
    // month: "numeric"
    // numberingSystem: "arab"
    // timeZone: "America/Los_Angeles"
    // year: "numeric"
    // }
    不同的伊斯兰日历变化将产生不同的日历日期。例如:
    calendars = ["islamic", "islamic-umalqura", "islamic-tbla", "islamic-civil", "islamic-rgsa"];
    options = { timeZone: 'UTC', month: 'long', day: 'numeric', year: 'numeric' };
    date = new Date('2022-03-03');
    calendars.forEach(calendar => {
    formatted = date.toLocaleDateString(`en-SA-u-ca-${calendar}`, options);
    console.log(`${calendar}: ${formatted}`);
    });
    // The code above outputs the following:
    // islamic: Shaʻban 1, 1443 AH
    // islamic-umalqura: Rajab 30, 1443 AH
    // islamic-tbla: Rajab 30, 1443 AH
    // islamic-civil: Rajab 29, 1443 AH
    // islamic-rgsa: Shaʻban 1, 1443 AH
    3. 用于JS日历计算的ICU库中的Bug
    意外日期的第三个可能原因是 JS 引擎内部的日历计算代码中是否存在错误。据我所知,所有主流浏览器都将他们的日历计算委托(delegate)给一个名为 ICU 的库。 .如果您使用正确的时区和日历变化并且计算仍然存在问题,那么您可能需要尝试在 ICU JIRA 站点中提交问题: https://unicode-org.atlassian.net/jira/software/c/projects/ICU/issues/ .
    顺便说一句,在回答这个问题时,我注意到 Intl.DateTimeFormat constructor 的 MDN 文档中有一个错误。支持的日历列表错误的地方。我提交了 https://github.com/mdn/content/pull/12764修复内容。此 PR 已合并,但生产 MDN 站点可能需要一段时间才能更新为固定内容。

    关于javascript - 伊斯兰(回历)日历的 Javascript Intl.DateTimeFormat() 输出在 'islamic' 和 'ar-SA' 之间存在差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70996839/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com