设置特定时区中日期的格式

2022-08-30 00:50:47

我正在使用 Moment.js 在我的 Web 应用中解析日期并设置其格式。作为 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 格式显示日期。


答案 1

正如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')

较旧的 .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 时区并改用:.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')

答案 2

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

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"

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

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

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


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

在这种情况下,它们的行为是平等的。


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