Moh*_*fei 16 javascript calendar date hijri ecmascript-temporal
在 StackOverflow 和 CodeReview 网站上搜索,尚未尝试过此问题/帖子中描述的方法;它将 5 个伊斯兰日历的日期转换为 Javascript 中 18 个可用日历中的任何一个,而无需使用外部日期库或使用复杂的数学/天文公式。
\n我们都知道 Javascript 有一个内置方法(Intl.DateTimeFormat())将公历日期转换为各种日历日期(18 个世界日历),包括输出字符串的格式。
\n然而,Javascript并没有提供反向操作的内置方法,即将18个世界日历日期转换回公历日期(包括伊斯兰历日期)或其他日历。为此,您需要使用外部日期库来进行转换,例如“moment.js”等。
\n这里使用的方法/代码不使用外部库,而是使用Javascript Calendar Conversion by Target Approximation Method。下面的流程图总结了该方法的概念,该方法可用于将其他日历转换为剩余日历。
\n下面的简短 Javascript 函数提供了将五 (5) 个伊斯兰 (Hijri) 日历日期(从伊斯兰教纪年 -280,803 到 +281,510 AH)中的任何一个转换为以下 18 个 Javascript 日历中的任何一个的功能,并提供格式化选项结果输出:
\n"buddhist", "chinese", "coptic", "dangi", "ethioaa", "ethiopic", "gregory", "hebrew", "indian", "islamic", "islamic-umalqura", "islamic-tbla", "islamic-civil", "islamic-rgsa", "iso8601", "japanese", "persian", "roc", "islamicc".
该方法不使用外部库,也不使用复杂的数学或天文公式,仅依赖于 Javascript 内置日历转换算法,而这些算法又基于 ICU 代码 [https://icu.unicode.org/]。
\n这种方法可确保输出始终准确且完全符合 Javascript 引擎输出。
\n虽然一些外部库非常好,但随着时间的推移,它们往往会失去更新和支持;最近的“moment.js”库就是一个例子。
\n该函数语法为:
\nhijriToCalendars(year, month, day, [options])\nRun Code Online (Sandbox Code Playgroud)\n在最简单的形式中,该函数默认转换\'islamic-umalqura\'日历,这是最常见和最新使用的伊斯兰日历。
它还默认Gregorian使用 ISO 日期格式转换为日历。
示例:将伊斯兰日期 21 Rajab 1443(即 21/07/1443)转换为公历。
\nhijriToCalendars(1443,7,21);\n\noutput: 2022-02-22T00:00:00.000Z // default output Gregorian ISO format\nRun Code Online (Sandbox Code Playgroud)\n要将伊斯兰日期转换为另一个日历(例如“波斯”日历):
\n hijriToCalendars(1443,7,21, { toCal: "persian" });\n\n output: 12/3/1400 AP\nRun Code Online (Sandbox Code Playgroud)\n要向输出添加格式,请使用\'dateStyle\'JavascriptIntl.DateTimeFormat()方法中的选项。
示例:使用完整的 dateStyle 将伊斯兰日期转换为波斯日期
\n hijriToCalendars(1443,7,21, { toCal: "persian", dateStyle: "full" });\n\n output: Tuesday, Esfand 3, 1400 AP\nRun Code Online (Sandbox Code Playgroud)\n示例:使用阿拉伯语区域设置将伊斯兰日期转换为希伯来语
\n hijriToCalendars(1443,7,21,{ toCal:"hebrew", dateStyle: "full", locale:"ar"})\n\n output: \xd8\xa7\xd9\x84\xd8\xab\xd9\x84\xd8\xa7\xd8\xab\xd8\xa7\xd8\xa1\xd8\x8c \xd9\xa2\xd9\xa1 \xd8\xa2\xd8\xb0\xd8\xa7\xd8\xb1 \xd8\xa7\xd9\x84\xd8\xa3\xd9\x88\xd9\x84 \xd9\xa5\xd9\xa7\xd9\xa8\xd9\xa2 \xd8\xb5\nRun Code Online (Sandbox Code Playgroud)\n上述操作可用于所有其他 18 个日历。
\n一个附加功能是能够将伊斯兰日期格式化为任何可用的日期\'dateStyles\'且\'locales\' 无需转换。
为此,请指定\'toCal\'与伊斯兰输入日历相同,默认使用:\'islamic-umalqura\'。
示例:使用波斯语区域设置格式化伊斯兰日期
\n hijriToCalendars(1443,7,21,{toCal:"islamic-umalqura",dateStyle:"full", locale:"fa"}));\n\n output: \xd8\xb3\xd9\x87\xe2\x80\x8c\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87 \xdb\xb2\xdb\xb1 \xd8\xb1\xd8\xac\xd8\xa8 \xdb\xb1\xdb\xb4\xdb\xb4\xdb\xb3 \xd9\x87\xe2\x80\x8d.\xd9\x82. // mind the RTL requirements\nRun Code Online (Sandbox Code Playgroud)\n示例:在印地语语言环境中格式化伊斯兰日期
\n hijriToCalendars(1443,7,21,{ toCal : "islamic-umalqura", dateStyle : "full", locale : "hi"}));\n\n output: AH \xe0\xa4\xae\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xb2\xe0\xa4\xb5\xe0\xa4\xbe\xe0\xa4\xb0, 21 \xe0\xa4\xb0\xe0\xa4\x9c\xe0\xa4\xac 1443\nRun Code Online (Sandbox Code Playgroud)\n默认输入伊斯兰日历为\'islamic-umalqura\',但是,您可以使用该选项将其更改为五 (5) 个伊斯兰日历中的任何一个\'fromCal\'。
示例:将Islamic-Civil日期 21 Rajab 1443 (即 21/07/1443)转换为公历。
hijriToCalendars(1443,7,21, {fromCal : "islamic-civil" });\n\n output: 2022-02-23T00:00:00.000Z\nRun Code Online (Sandbox Code Playgroud)\n从上面可以看出,islamic-civil日期与islamic-umalqura日期相差1天。
您可以使用 中的所有可用选项Intl.DateTimeFormat()来格式化输出日期。
如果将无效的伊斯兰日期传递给函数,Invalid islamic-xxxxx date!则会生成错误。
无效的伊斯兰日期是指当月中的日期不正确或者日期或月份不正确的日期。
\n例如,伊斯兰日期 1443/2/30 无效,因为回历的第 2 个月(“Safar”月)始终为 29 天,不能为 30 天。
\n另外,例如,伊斯兰日期 1442/12/30 将引发错误,因为 1442 年是非闰年,而 12 月只有 29 天。
\n如果您认为内部 Javascript ICU C++ 代码可靠且准确,则此方法仅使用 Javascript 引擎内部生成的日期。无需担心外部不正确的数学或代码中的错误/错误,除非它们位于 Javascript 引擎本身内部。
\n下面是带有可以运行和测试的转换和格式化示例测试用例的函数。
\n给出了将恰好是今天日期的伊斯兰日期 (1443/7/21) 转换为所有其他日历格式的示例。
\n如有任何改进/建议/替代方案,我们将不胜感激。
\nhijriToCalendars(year, month, day, [options])\nRun Code Online (Sandbox Code Playgroud)\r\n
一位工程师、物理学家和数学家在一辆驶过英国乡村的火车上,当工程师向窗外望去,看到山坡上有一只孤独的害群之马时,他惊呼道:“嘿,看,英国有害群之马!” 物理学家很快劝告他:“我们所能确定的是,英国有一只害群之马。” 于是数学家告诫他们俩,宣称:“我们所能得出的结论是,英国至少有一只一侧是黑色的羊……”
我很抱歉,因为我是一名数学家......
经过一番研究,我相信长期答案在于被称为“临时”的 ECMAScript 提案,该提案目前(截至 2022 年 2 月 24 日星期四)处于活跃提案的第 3 阶段。临时提案的完整第三阶段草案提供了有关提案动机的一些背景信息以及整个技术规范,临时文档提供了更容易理解的目的和操作用途。后一个文档是一个很好的起点......
文档中的一些值得注意的内容:
Temporal.Instant抽象一个时间点,而不考虑日历或位置。即,这是所有日历和时区必须引用的绝对时间,以呈现指定区域设置中的日期和时间。
Temporal.Calendar是日历系统的表示,它提供了日历的详细信息以及对日历进行操作的方法。存在许多预先构建的日历,例如“格雷戈里”、“伊斯兰”、“希伯来”等。此外,临时提案还使您可以实现自己的日历。
话虽这么说,CookBook示例都使用现代时间框架,所以我实际上有兴趣尝试实现从公元 4 年到公元 1752 年的儒略历,在此期间使用了儒略历。概念是引用儒略历的同期日期可以直接作为儒略日期输入,并且可以轻松操作并与其他日历中的日期进行比较,并确信这些日期引用相同的基本Temporal.Instant参考框架......例如,什么是威廉·莎士比亚出生的伊斯兰日期?
作为 ECMAScript 第 3 阶段提案,Temporal 仍处于实验阶段,但鼓励在非生产环境中使用,报告任何错误。由于Temporal.Instant无论日历或位置如何,日历都是基本时间点,因此日历之间的转换成为Temporal.Instant通过不同日历呈现的自然结果。
<script type='module'>
import * as TemporalModule from 'https://cdn.jsdelivr.net/npm/@js-temporal/polyfill@0.3.0/dist/index.umd.js'
const Temporal = temporal.Temporal;
let islamicDate = Temporal.ZonedDateTime.from( {
year: 1440,
monthCode: 'M06',
day: 2,
hour:12,
minute: 45,
timeZone: 'Asia/Dubai',
calendar: 'islamic'
} );
let hebrewDate = Temporal.ZonedDateTime.from( islamicDate ).withCalendar( 'hebrew' );
let gregoryDate = Temporal.ZonedDateTime.from( islamicDate ).withCalendar( 'gregory' );
console.log( `Date in Islamic: ${ islamicDate.toPlainDate().toLocaleString( 'en-US', { calendar: 'islamic' } ) }` );
console.log( `DateTime in Islamic in Dubai: ${ islamicDate.toLocaleString( 'en-US', { calendar: 'islamic' } ) }` );
console.log( `DateTime in Islamic in London: ${ islamicDate.toInstant().toZonedDateTimeISO( 'Europe/London' ).toLocaleString('en-US', { calendar: 'islamic' } ) }` );
console.log( `Date in Hebrew: ${ hebrewDate.toPlainDate().toLocaleString( 'en-US', { calendar: 'hebrew' } ) }` );
console.log( `DateTime in Hebrew in Dubai: ${ hebrewDate.toLocaleString( 'en-US', { calendar: 'hebrew' } ) }` );
console.log( `DateTime in Hebrew in London: ${ hebrewDate.toInstant().toZonedDateTimeISO( 'Europe/London' ).toLocaleString('en-US', { calendar: 'hebrew' } ) }` );
console.log( `Date in Gregorian: ${ gregoryDate.toPlainDate().toLocaleString( 'en-US' ) }` );
console.log( `DateTime in Gregorian: ${ gregoryDate.toLocaleString( 'en-US' ) }` );
console.log( `Islamic Date in English (United States) Locale:\n${ islamicDate.toPlainDate().toString() }` );
console.log( `Islamic DateTime in English (United States) Locale:\n${ islamicDate.toString() }` );
</script>Run Code Online (Sandbox Code Playgroud)
(更新了代码片段,以更好地举例说明时区和日历之间的转换,以及显示日期的各种方法。)
| 归档时间: |
|
| 查看次数: |
3831 次 |
| 最近记录: |