223

我正在使用Moment.js在我的网络应用程序中解析和格式化日期。作为 JSON 对象的一部分,我的后端服务器以 UTC 纪元(Unix 偏移量)的毫秒数发送日期。

解析特定时区中的日期很容易——只需在解析之前将 RFC 822 时区标识符附加到字符串的末尾:

// response varies according to your timezone
const m1 = moment('3/11/2012 13:00').utc().format("MM/DD HH:mm")

// problem solved, always "03/11 17:00"
const m2 = moment('3/11/2012 13:00 -0400').utc().format("MM/DD HH:mm")

console.log({ m1, m2 })
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

但是如何在特定时区格式化日期?

无论浏览器的当前时间如何,我都想要一致的结果,但我不想以 UTC 显示日期。

4

8 回答 8

300

正如Manto 的回答中所指出的,.utcOffset()从 Moment 2.9.0 开始是首选方法。此函数使用与 UTC 的实际偏移量,而不是反向偏移量(例如,DST 期间的纽约为 -240)。像“+0400”这样的偏移字符串的工作方式和以前一样:

// always "2013-05-23 00:55"
moment(1369266934311).utcOffset(60).format('YYYY-MM-DD HH:mm')
moment(1369266934311).utcOffset('+0100').format('YYYY-MM-DD HH:mm')

Moment.js 2.9.0中弃用了较旧.zone()的 setter 。它接受包含时区标识符的字符串(例如,-4 小时的“-0400”或“-04:00”)或代表 UTC 后分钟数的数字例如,DST 期间的纽约为 240)。

// always "2013-05-23 00:55"
moment(1369266934311).zone(-60).format('YYYY-MM-DD HH:mm')
moment(1369266934311).zone('+0100').format('YYYY-MM-DD HH:mm')

要使用命名时区而不是数字偏移量,请包含Moment Timezone.tz()改用:

// determines the correct offset for America/Phoenix at the given moment
// always "2013-05-22 16:55"
moment(1369266934311).tz('America/Phoenix').format('YYYY-MM-DD HH:mm')
于 2013-05-23T00:03:59.220 回答
83

一些答案已经提到时刻时区是使用命名时区的方式。我只是想澄清一些关于这个库的事情,这让我很困惑。这两种说法是有区别的:

moment.tz(date, format, timezone)

moment(date, format).tz(timezone)

假设传入的日期中未指定时区:

第一个代码接受日期并假设时区是传入的。第二个代码将接受日期,假设来自浏览器的时区,然后根据传入的时区更改时间和时区。

例子:

moment.tz('2018-07-17 19:00:00', 'YYYY-MM-DD HH:mm:ss', 'UTC').format() // "2018-07-17T19:00:00Z"

moment('2018-07-17 19:00:00', 'YYYY-MM-DD HH:mm:ss').tz('UTC').format() // "2018-07-18T00:00:00Z"

我的时区是 UTC 的 +5。因此,在第一种情况下,它不会更改,而是将日期和时间设置为 utc 时区。

在第二种情况下,它假设传入的日期为 -5,然后将其转换为 UTC,这就是它吐出日期“2018-07-18T00:00:00Z”的原因

注意:格式参数非常重要。如果省略时刻可能会退回到 Date 类,这可能会发生不可预测的行为


假设时区在传入的日期中指定:

在这种情况下,它们的行为相同


尽管现在我明白它为什么会这样工作,但我认为这是一个非常令人困惑的功能,值得解释。

于 2018-07-13T22:03:04.957 回答
66

使用时刻时区

moment(date).tz('Europe/Berlin').format(format)

在能够访问特定时区之前,您需要像这样加载它(或使用此处描述的替代方法)

moment.tz.add('Europe/Berlin|CET CEST CEMT|-10 -20 -30')
于 2015-04-18T18:52:51.547 回答
23

.zone() 已被弃用,您应该使用 utcOffset 代替:

// for a timezone that is +7 UTC hours
moment(1369266934311).utcOffset(420).format('YYYY-MM-DD HH:mm')
于 2015-08-19T23:45:11.927 回答
10

我对 Moment.js 也有同样的问题。我已经安装了时刻时区,但问题没有解决。然后,我做了这里暴露的事情,设置时区,它就像一个魅力:

moment(new Date({your_date})).zone("+08:00")

非常感谢!

于 2014-09-17T16:18:53.870 回答
6

刚刚来了这个,因为我有同样的问题,我只是发布我想出的结果

解析时,您可以更新偏移量(即我正在解析数据(1.1.2014),我只想要日期,2014 年 1 月 1 日。在 GMT+1 上,我会得到 31.12.2013。所以我首先偏移该值。

moment(moment.utc('1.1.2014').format());

好吧,对我支持跨时区很有用

于 2015-05-27T10:26:39.523 回答
-1

如果您将时间戳作为参数传递给moment()(例如,如果时区是 Asia/Hong_kong,即 +08:00),我要做的是:

const localDateTime = moment((item.createdAt.seconds + 8 * 3600) * 1000).format('YYYY-MM-DD HH:mm:ss');
于 2021-03-08T10:32:56.633 回答
-9

你可以试试这个,

在这里,您可以根据客户端时区(浏览器)获取日期。

moment(new Date().getTime()).zone(new Date().toString().match(/([-\+][0-9]+)\s/)[1]).format('YYYY-MM-DD HH:mm:ss')

正则表达式基本上可以为您提供偏移值。

干杯!!

于 2018-08-21T09:52:13.723 回答