我正在為 JavaScript提出的新 Temporal API苦苦掙扎。我想做的應該是直截了當的,但我找不到一個令人信服的解決方案。我肯定錯過了什么。
任務如下:從年、月、日、小時和分鐘的變數中實體化 UTC 日期時間的物件表示。
我的想法如下:
- 我們說的是 UTC,所以我需要一個
Temporal.Instant; new Temporal.Instant()需要以納秒為單位的時間戳,因此不起作用;Temporal.Instant.from()需要一個 ISO 日期時間字串,這將要求我從我擁有的五個變數中生成一段格式正確的文本——這是可能的,但有點 hack 并且有點違背使用日期時間庫的目的;Temporal.PlainDateTime.from()具有正確的設計,因為它接受像{ year, month, day, hour, minute };- 所以我們需要做的就是
Instant從這個創建一個PlainDateTime。這似乎不可能嗎?除了通過 - 再一次 - 日期時間字串或 ns 中的時間戳......?
這太傻了!這里的用例是超級基本的,但是(對我來說)如何解決它并不明顯。
我期望能夠簡單地執行以下操作: Temporal.Instant.from({ year, month, day, hour, minute });
現在我能想到的最好的是:Temporal.Instant.from(year '-' String(month).padStart(2, '0') '-' String(day).padStart(2, '0') 'T' String(hour).padStart(2, '0') ':' String(minute).padStart(2, '0') 'Z'); // ??
請告訴我我經常忽略一些東西。
uj5u.com熱心網友回復:
您PlainDateTime 代表“不攜帶時區資訊的日歷日期和掛鐘時間”。要將其轉換為準確的時間,您需要使用toZonedDateTime方法提供時區。然后通過toInstant方法忽略日歷和時區,您可以獲得所需的Instant實體。
所以有幾種方法可以實作這一點:
PlainDateTime從物件創建一個,通過假設時區將其轉換為瞬間UTC:Temporal.PlainDateTime.from({year, month, day, hour, minute}).toZonedDateTime("UTC").toInstant()PlainDateTime使用建構式創建一個,通過假設時區將其轉換為瞬間UTC:new Temporal.PlainDateTime(year, month, day, hour, minute).toZonedDateTime("UTC").toInstant()ZonedDateTime直接從物件創建一個,在其中提供時區,然后對其進行轉換:Temporal.ZonedDateTime.from({timeZone: 'UTC', year, month, day, hour, minute}).toInstant()除了通過磁區日期時間,您還可以獲得實體歸屬于物件的瞬間:
TimeZonePlainDateTimeTemporal.TimeZone.from("UTC").getInstantFor(Temporal.PlainDateTime.from({year, month, day, hour, minute})) new Temporal.TimeZone("UTC").getInstantFor(new Temporal.PlainDateTime(year, month, day, hour, minute))如果您想在代碼中硬編碼瞬間,您也可以直接從ISO 字串創建它:
Temporal.Instant.from("2022-10-23T02:50Z")如果您愿意包含舊
Date方法,您還可以使用Date.UTC計算瞬間的毫秒值- 請注意從零開始的月份:Temporal.Instant.fromEpochMilliseconds(Date.UTC(year, month-1, day, hour, minute));
用您的特定示例自己嘗試一下:
const year = 2022;
const month = 10;
const day = 23;
const hour = 2;
const minute = 50;
log(Temporal.PlainDateTime.from({year, month, day, hour, minute}).toZonedDateTime("UTC").toInstant());
log(new Temporal.PlainDateTime(year, month, day, hour, minute).toZonedDateTime("UTC").toInstant());
log(Temporal.ZonedDateTime.from({timeZone: 'UTC', year, month, day, hour, minute}).toInstant());
log(Temporal.TimeZone.from("UTC").getInstantFor(Temporal.PlainDateTime.from({year, month, day, hour, minute})));
log(new Temporal.TimeZone("UTC").getInstantFor(new Temporal.PlainDateTime(year, month, day, hour, minute)));
log(Temporal.Instant.from("2022-10-23T02:50Z"));
log(Temporal.Instant.fromEpochMilliseconds(Date.UTC(year, month-1, day, hour, minute)));
<script src="https://tc39.es/proposal-temporal/docs/playground.js"></script>
<script>function log(instant) { console.log(instant.epochSeconds); }</script>
uj5u.com熱心網友回復:
Date API將永遠存在并且非常方便,因此如果有幫助,使用它似乎是明智的。
Date.UTC回傳自 ECMAScript 紀元以來的毫秒數。Temporal.instant需要納秒,因此給定一個輸入物件,唯一麻煩的是使用BigInt{year, month, day, etc.}處理納秒,這并不難:
// Object for 7 December 2022
let d = {
year: 2022,
month: 12,
day: 7,
hour: 3,
minute: 24,
second: 30,
millisecond: 10,
microsecond: 3,
nanosecond: 500
}
// Convert to time value - nanoseconds since ECMAScript eopch
let timeValue = BigInt(Date.UTC(d.year, d.month-1, d.day,
d.hour, d.minute, d.second, d.millisecond)) * BigInt(1e6)
BigInt(d.microsecond * 1e3) BigInt(d.nanosecond);
// 1670383470010003500
console.log(timeValue.toString());
// 2023-01-07T03:24:30.010Z
console.log(new Date(Number(timeValue/BigInt(1e6))).toISOString());
然后可以將瞬間創建為:
let instant = new Temporal.Instant(timeValue);
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/521381.html
下一篇:如何使用日期時間索引洗掉多行?
