格式化特定时区的日期

问题描述 投票:0回答:9

我正在使用 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 格式显示日期。

javascript timezone momentjs
9个回答
338
投票

正如 Manto 的回答中所指出的,从 Moment 2.9.0 开始,

.utcOffset()
是首选方法。此函数使用相对于 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 时间落后分钟的数字(例如,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')

107
投票

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

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”

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


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

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


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


73
投票

使用时刻时区

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

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

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

24
投票

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

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

12
投票

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

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

非常感谢!


6
投票

刚刚来到这里,因为我遇到了同样的问题,所以我只是发布我得出的结果

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

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

嗯,跨时区支持对我来说很方便

B


-1
投票

如果你有一个除以“T”的时间戳,那么你必须首先使用utc方法。 以下是我将时间戳从 UTC 转换为 EST/EST 的方法:

let createdDate = moment.utc("2023-06-11T00:45:48.42") 
moment(createdDate, "MM/DD/yy").tz("America/New_York").format("MM/DD/yy")}

结果是:06/10/2023

参考:https://momentjs.com/timezone/docs/#/using-timezones/


-4
投票

如果您将时间戳作为参数传递给

moment()
(例如,如果时区是 Asia/Hong_kong,即 +08:00),我要做的是:

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

-14
投票

你可以试试这个,

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

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

正则表达式基本上可以获取偏移值。

干杯!!

© www.soinside.com 2019 - 2024. All rights reserved.