Moment.js:在特定时区中格式化日期

qui*_*int 158 javascript timezone momentjs

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

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

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

// problem solved, always "03/11 17:00"
moment('3/11/2012 13:00 -0400').utc().format("MM/DD HH:mm")
Run Code Online (Sandbox Code Playgroud)

但是如何在特定时区格式化日期?无论浏览器的当前时间如何,我都希望得到一致的结果,但我不希望以UTC显示日期.

qui*_*int 221

正如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')
Run Code Online (Sandbox Code Playgroud)

.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')
Run Code Online (Sandbox Code Playgroud)

要使用命名时区而不是数字偏移,请包含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')
Run Code Online (Sandbox Code Playgroud)

  • @ebi它默认使用浏览器的时区.要*访问浏览器的时区偏移量,请使用`.zone()`作为getter,从UTC返回分钟(例如,在标准时间内返回纽约300). (4认同)
  • @haemse `utcOffset()` 与 DST 或时区规则*无关*。它只是查看您已经构建的时刻并获取/设置 UTC 分钟数。如果您想处理已知时区的 DST 和其他规则,请使用带有命名时区(“America/Phoenix”)的 Moment Timezone 库。 (2认同)

Phi*_*nyy 50

使用时刻时区

moment(date).tz('Europe/Berlin').format(format)
Run Code Online (Sandbox Code Playgroud)

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

moment.tz.add('Europe/Berlin|CET CEST CEMT|-10 -20 -30')
Run Code Online (Sandbox Code Playgroud)


Nic*_*tti 29

几个答案已经提到,时刻时区是指定时区的方式.我只是想澄清一下这个库让我很困惑.这两个陈述有所不同:

moment.tz(date, format, timezone)

moment(date, format).tz(timezone)
Run Code Online (Sandbox Code Playgroud)

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

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

例:

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"
Run Code Online (Sandbox Code Playgroud)

我的时区是从utc +5.所以在第一种情况下,它不会改变,它设置了具有utc时区的日期和时间.

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

注意:格式参数非常重要.如果省略,则可能会回退到可能无法预测的行为的Date类


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

在这种情况下,他们都表现得一样


即使现在我理解为什么它以这种方式工作,我认为这是一个非常令人困惑的功能,值得解释.

  • moment(...).tz 不是函数 (4认同)
  • 您安装了moment-timezone吗? (2认同)

Man*_*nto 17

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

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


fac*_*ias 6

我在Moment.js中遇到了同样的问题。我已经安装了moment-timezone,但是问题没有解决。然后,我只做了这里公开的内容,设置了时区,它就像一个符咒一样工作:

moment(new Date({your_date})).zone("+08:00")
Run Code Online (Sandbox Code Playgroud)

非常感谢!

  • 您不应该使用`new Date()`构造函数。Moment提供了解析日期所需的一切。请参阅[解析](http://momentjs.com/docs/#/parsing/)文档。 (15认同)
  • 该警告表示Moment在内部完全恢复了您正在执行的操作(内部使用了`new Date()`),但这在[各浏览器之间不一致](http://dygraphs.com/date-formats.html)。相反,您应该使用提供期望的格式作为第二个参数。例如:`moment(“ 12-25-1995”,“ MM-DD-YYYY”)`。 (6认同)

Bar*_*zer 6

刚刚出现这个问题,因为我遇到了同样的问题,所以我只是发布了我想出的结果

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

moment(moment.utc('1.1.2014').format());
Run Code Online (Sandbox Code Playgroud)

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