格式化特定时区的日期

我使用Moment.js来解析和格式化我的web应用程序中的日期。作为JSON对象的一部分,我的后端服务器以UTC epoch (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>

But how do I format a date in a specifc timezone?

I want consistent results regardless of the browser's current time, but I don't want to display dates in UTC.

577692 次浏览

正如黑披巾的回答中所指出的,.utcOffset()是第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')

旧的.zone()作为setter是Moment.js 2.9.0中的弃用。它接受一个包含时区标识符的字符串(例如,“-0400”或“-04:00”表示-4小时)或表示分钟后面 UTC的数字(例如,夏令时期间的纽约为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')

要使用命名时区而不是数值偏移量,请包含时刻时区并使用.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')

我在使用Moment.js时也遇到了同样的问题。我已经安装了moment-timezone,但是这个问题没有解决。然后,我做了这里曝光的事情,设置时区,它就像一个魅力:

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

非常感谢!

使用moment-timezone

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

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

moment.tz.add('Europe/Berlin|CET CEST CEMT|-10 -20 -30')

只是偶然发现了这个,因为我也有同样的问题,我只是发布了我想到的结果

在解析时,你可以更新偏移量(即我正在解析一个数据(1.1.2014),我只想要日期,2014年1月1日。在格林尼治标准时间+1上,我会得到31.12.2013。所以我先偏移这个值。

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

对我来说跨越时区的支持很方便

B

.zone()已经弃用,你应该使用utcOffset:

// for a timezone that is +7 UTC hours
moment(1369266934311).utcOffset(420).format('YYYY-MM-DD HH:mm')

一些答案已经提到了moment-timezone是使用named timezone的方法。我只是想澄清一些让我很困惑的关于这个库的事情。这两种说法有区别:

moment.tz(date, format, timezone)


moment(date, format).tz(timezone)

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

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

例子:

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”

注意:format参数非常重要。如果省略了moment,可能会退回到Date类,从而导致不可预测的行为


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

在这种情况下,它们的行为是一样的


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

你可以试试这个,

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

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

正则表达式基本上会得到偏移值。

干杯! !

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

const localDateTime = moment((item.createdAt.seconds + 8 * 3600) * 1000).format('YYYY-MM-DD HH:mm:ss');