猿问

所有时区的同一日期

我在所有时区显示相同日期时遇到问题。例如,用户输入的是 01-01-2002,我将其存储为带Eureope/Berlin时区 的日期parseFromTimeZone(String(birthDate), { timeZone: 'Europe/Berlin' }) ,结果parseFromTimeZone是这个字符串'2001-12-31T23:00:00.000Z'。字符串日期与柏林的时区一起计算,这就是为什么它会移动一小时。

我需要在所有时区都从中得到'2001-12-31T23:00:00.000Z'帮助01-01-2002

当我的时 区 formatISO(new Date(date), { representation: 'date' }))是或01-01-2002Europe/PragueEurope/Berlin

但是当我将时区更改为America/Tijuana然后formatISO返回时2001-12-31,这是错误的,我需要与Europe/Berlin始终保持相同的日期!Bud 对于Asia/Tokyo这个函数返回01-01-2002是正确的......

一些想法?我尝试了很多解决方案,但没有一个适用于所有时区......

我正在使用 "date-fns": "^2.15.0""date-fns-timezone": "^0.1.4"


12345678_0001
浏览 136回答 2
2回答

蝴蝶不菲

该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();  // 2002var m = dt.getUTCMonth() + 1; // 1var d = dt.getUTCDate();      // 1var 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 阶段,因此今天无法使用,但这个问题最终会得到解决!

白板的微信

使用 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; }
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答