2 回答

TA貢獻1810條經驗 獲得超4個贊
該Date對象,盡管它的名字,并不代表一個“日期”。它代表一個時間戳。它在內部存儲的所有內容都是自 Unix 紀元(基于 UTC)以來的毫秒數。它根據正在調用的函數,根據 UTC 或運行機器的本地時區輸出值。
因此,如果您Date從僅限日期的值構造對象,那么您實際上是從該時區獲取“午夜時間”并將其調整為 UTC。2002-01-01您的in示例證明了這一點Europe/Berlin。您將其視為2002-01-01T00:00:00.000+01:00,它確實具有相當于 的 UTC 2001-12-31T23:00:00.000Z,因此不包含與預期時區相同的年、月和日元素。
如果你想防止它們移動,你真的只有兩個選項來處理僅限日期的值:
您的第一個選擇是使用該Date對象,但將輸入視為 UTC 并且僅使用基于 UTC 的函數。例如:
var dt = new Date(Date.UTC(2002, 0, 1));? // "2002-01-01T00:00:00.000Z"
var y = dt.getUTCFullYear();? // 2002
var m = dt.getUTCMonth() + 1; // 1
var d = dt.getUTCDate();? ? ? // 1
var dtString = d.toISOString().substring(0, 10) // "2002-01-01"
如果您需要解析日期字符串,請注意當前的ECMAScript 規范將僅限日期的值視為 UTC(這正是您想要的),但在過去這種行為是未定義的。因此,某些瀏覽器可能會從
new Date('2002-01-01')
.?Z
為了new Date('2002-01-01' + 'T00:00:00.000Z')
安全起見,您可能希望明確添加時間和。如果您打算使用 date-fns,請小心 -
parseISO
和formatISO
函數使用本地時間,而不是 UTC。
第二種選擇是不使用該
Date
對象。將日期保存為字符串形式(采用 ISO 8601 yyyy-mm-dd 格式),或者將它們保存在您自己構造的或來自庫的不同對象中。
ECMAScript TC39?Temporal 提案旨在修復 JavaScript 中的此類缺陷。特別是,該Temporal.Date
對象(初步名稱)將能夠用于僅限日期的值,而不會出現您和許多其他人遇到的轉移問題。該提案目前處于 ECMAScript 進程的第 2 階段,因此今天無法使用,但這個問題最終會得到解決!

TA貢獻1883條經驗 獲得超3個贊
使用 ISO_8601 日期嘗試此功能,然后更改計算機設置中的時區并使用新時區重試。它應該在您的網頁上為兩個時區打印相同的日期。
getDateFromISO(iso_string: string): string | Date {
if (!iso_string)
return null;
const isIsoDate = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/.test(iso_string); // check if string is in format 2022-01-01T00:00:00.000Z
const isDateTimeWithoutZone = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(iso_string); // check if string is in format 2022-01-01T00:00:00
const isDateYMD = /\d{4}-\d{2}-\d{2}/.test(iso_string); // check if string is in format 2022-01-01
if (!isIsoDate && isDateTimeWithoutZone)
iso_string += '.000Z';
else if (!isIsoDate && isDateYMD)
iso_string += 'T00:00:00.000Z';
else if (isIsoDate)
iso_string = iso_string;
else
return iso_string;
const dateFromServer = new Date(iso_string);
const localOffset = new Date().getTimezoneOffset(); // in minutes
const localOffsetMillis = 60 * 1000 * localOffset;
const localDate = new Date(dateFromServer.getTime() + localOffsetMillis);
return localDate;
}
添加回答
舉報