Ish*_*ngi 4 javascript timezone datetime date
我正在开发一个基于云的应用程序,它为世界各地的用户广泛处理日期和时间值。
考虑一个场景,在 JavaScript 中,我的机器在印度 (GMT+05:30),我必须显示在加利福尼亚时区 (GMT-08:00) 运行的时钟。
在这种情况下,我必须获得一个新的日期对象,
let india_date = new Date()
添加它的时区偏移值,
let uts_ms = india_date.getTime() + india_date.getTimezoneOffset()
添加加利福尼亚的时区偏移值,
let california_ms = utc_ms + getCaliforniaTimezoneOffsetMS()
最后是日期对象。
let california_date: Date = new Date(california_ms)
有没有办法直接处理这些类型的时区而不必一次又一次地转换值?
JavaScript Date 对象以 UTC 格式存储日期和时间,但当toString()
日期表示为显示浏览器本地时区中的日期和时间的文本值时,会自动调用该方法。因此,当您想要将日期时间转换为本地时间以外的时区时,您实际上是从 UTC 转换为该时区(而不是从本地时区转换为另一个时区)。
如果您的用例仅限于特定浏览器并且您对格式很灵活(因为浏览器显示日期字符串格式的方式可能有所不同),那么您可能可以使用toLocaleString()
,但 Edge、Android webview 等浏览器不完全支持和locales
参数options
。
以下示例设置区域设置和时区以以本地格式输出日期,该格式可能因浏览器而异。
const dt = new Date();
const kolkata = dt.toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' });
const la = dt.toLocaleString('en-US', { timeZone: 'America/Los_Angeles' });
console.log('Kolkata:', kolkata);
// example output: Kolkata: 19/3/2019, 7:36:26 pm
console.log('Los Angeles:', la);
// example output: Los Angeles: 3/19/2019, 7:06:26 AM
Run Code Online (Sandbox Code Playgroud)
您还可以使用Moment.js和Moment Timezone将日期和时间转换为本地时区以外的时区。例如:
const dt = moment();
const kolkata = dt.tz('Asia/Kolkata').format();
const la = dt.tz('America/Los_Angeles').format();
console.log(kolkata);
// example output: 2019-03-19T19:37:11+05:30
console.log(la);
// example output: 2019-03-19T07:07:11-07:00
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data.min.js"></script>
Run Code Online (Sandbox Code Playgroud)
首先,让我们谈谈您的问题中的代码。
Run Code Online (Sandbox Code Playgroud)let india_date = new Date()
您已将此变量命名为india_date
,但Date
只有在设置为印度时区的计算机上运行代码时,该对象才会反映印度。如果它在具有不同时区的计算机上运行,它将改为反映该时区。请记住,在内部,该Date
对象仅跟踪基于 UTC 的时间戳。在调用需要本地时间的函数和属性时应用本地时区 - 而不是在Date
创建对象时。
添加它的时区偏移值
Run Code Online (Sandbox Code Playgroud)let uts_ms = india_date.getTime() + india_date.getTimezoneOffset()
这种做法是不正确的。 getTime()
已经返回基于 UTC 的时间戳。您不需要添加本地偏移量。(另外,缩写是 UTC,而不是 UTS。)
现在添加加利福尼亚的时区偏移值
Run Code Online (Sandbox Code Playgroud)let california_ms = utc_ms + getCaliforniaTimezoneOffsetMS()
同样,添加偏移量是不正确的。此外,与印度不同的是,加利福尼亚州遵守夏令时,因此一年中的一部分偏移量将是480
(UTC-8),而一年中的一部分偏移量将是420
(UTC-7)。任何像您getCaliforniatimezoneOffsetMS
这样的函数都需要将时间戳作为参数传入才能生效。
最后是日期对象
Run Code Online (Sandbox Code Playgroud)let california_date: Date = new Date(california_ms)
当Date
构造函数传递一个数字时间戳时,它必须是 UTC。传递这个california_ms
时间戳实际上只是选择了一个不同的时间点。您不能Date
仅通过添加或减去偏移量来更改对象的行为以使其使用不同的时区。对于任何需要本地时间的函数,例如.toString()
和其他函数,它仍将使用它运行所在位置的本地时区。
只有一种情况可以使这种调整有意义,即一种称为“时代转移”的技术。时间戳被调整以将基本纪元从 normal 移开1970-01-01T00:00:00Z
,从而允许利用Date
对象的 UTC 功能(例如getUTCHours
和其他功能)。问题是:一旦转移,您就不能在该Date
对象上使用任何本地时间函数,也不能将其传递给任何其他希望该Date
对象是正常对象的对象。正确完成时代转移是像Moment.js这样的库的动力。 这是另一个正确完成时代转移的例子。
但是在您的示例中,您正在移动(错误两次),然后将Date
对象用作正常而不是移动的对象。这只会导致错误,这在toString
输出中显示的时区很明显,并且会在本地时区和预期目标时区的任何 DST 转换附近在数学上出现。通常,您不想采用这种方法。
相反,请阅读我关于如何将 JavaScript 日期初始化为特定时区的答案。 您的选项列在那里。谢谢。
归档时间: |
|
查看次数: |
4749 次 |
最近记录: |