Unix 格式的 GMT/UTC(非本地)时间

Posted

技术标签:

【中文标题】Unix 格式的 GMT/UTC(非本地)时间【英文标题】:GMT/UTC (not local) time in Unix format 【发布时间】:2012-02-22 16:27:54 【问题描述】:

我正在使用 javascript 并尝试以 Unix 格式获取 GMT+0/UTC+0 时间(也称为 Zulu 时间)。

我已经设法以 Unix 格式获取本地时间,如下所示:

var datetime = new Date()
var unixtime = Math.floor(Number(datetime/1000));

但是当我尝试对 UTC 时间做同样的事情时......

var datetime = new Date()
var year = datetime.getUTCFullYear()
var month = datetime.getUTCMonth()
var day = datetime.getUTCDate()
var hours = datetime.getUTCHours()
var minutes = datetime.getUTCMinutes()
var seconds = datetime.getUTCSeconds()
var unixtime = (Date.UTC(year,month,day,hours,minutes,seconds,00)/1000);

它失败了。我只是以 Unix 格式获取本地时间。

您可以在此处实时运行它:http://jsfiddle.net/wC8XH/1/ (也在pastebin上:http://pastebin.com/uDD5zUah)

这是一个输出示例:

2012-01-30 23:15:19 = 1327958119
2012-01-30 21:15:19 = 1327958119

在做:

date -d "2012-01-30 21:15:19" +%s

在 Linux 上给我 1327950919,而不是 1327958119。差异是 7200 秒,即 2 小时,这是我的时区 (+0200)。

因此,如果我只是想要人类可读的格式,我可以获得 UTC+0 时间,但是当我请求 Date.UTC 将其转换为 Unix 格式时,它会选择转换我的本地时间。

我错过了什么吗?

【问题讨论】:

【参考方案1】:

是的,你的问题倒过来了。

Javascript总是以“Unix 格式”告诉您 UTC 或 GMT 的秒数。因为 Unix 总是在 UTC 或 GMT 内部工作。没有 UTC 就谈论“Unix 时间”是没有意义的。

因此,您的两个 Javascript 代码片段以简单的方式和非常冗长的复杂方式找到了相同的正确答案(当前的“unix 时间”是多少?),这就是它们给出相同结果的原因。

... 并且 date 命令对区域设置敏感。在您的语言环境中,您有 2 小时的偏移量,因此它假定您的日期字符串有 2 小时的偏移量。您可以使用 -u 标志告诉它不要那样做,这意味着您保证您的字符串采用 UTC 时间。

以下是一些示例,通过设置 TZ 环境变量,所提供字符串的明显时区会发生变化(显示的 TZ 值适用于常见的 Unix 时区文件,特定系统上可用的名称可能会有所不同)。

$ TZ="America/New_York" date -d "2012-01-30 21:15:19" +%s
1327976119
$ TZ="Europe/Paris" date -d "2012-01-30 21:15:19" +%s
1327954519
$ date -u -d "2012-01-30 21:15:19" +%s
1327958119

【讨论】:

【参考方案2】:

首先,正如 @tialaramex 已经说过的,两个 JavaScript 代码 sn-ps 都是正确的,所以你应该选择更短的那个。

问题在于 Linux date 命令。当您传递一个日期时,它会以您当前的时区而不是 UTC 来解释它!看:

$ date -d "2012-01-30 21:15:19" +%s
1327954519
$ scala
scala> new java.util.Date(1327954519 * 1000L)
res0: java.util.Date = Mon Jan 30 21:15:19 CET 2012

我住在 CET,请注意 date 的输出与您的不同。

更新:遵循以下 cmets 中 @derobert 的伟大建议,您可以在调用 date 时明确指定时区:

$ date -d "2012-01-30 21:15:19+0000" +%s
1327958119
$ scala
scala> new java.util.Date(1327958119 * 1000L)
res0: java.util.Date = Mon Jan 30 22:15:19 CET 2012

UTC 时间 21:15 是欧洲中部时间 22:15,一切正常。

【讨论】:

好吧,您只需将时区指定为date,例如date -d "2012-01-30 21:15:19 +0000" +%sdate -d "2012-01-30 21:15:19 UTC" +%sdate -u -d "2012-01-30 21:15:19 Z" 都可以。请感到欢迎(不,鼓励)将此添加到您的答案中。 @derobert:我怀疑一定有办法将时区指定为date,谢谢!我更新了我的答案。 那么,让我直说吧。当我告诉 JavaScript 解释器将字符串 '2012-01-30 23:15:19 +0200' 转换为 Unix 时间时,它首先看到它应该是 '2012-01-30 21:15:19 +0000' 并且然后转换成1327958119吧?

以上是关于Unix 格式的 GMT/UTC(非本地)时间的主要内容,如果未能解决你的问题,请参考以下文章

强制 Java 时区为 GMT/UTC

在 PHP 中获取 UTC 时间

关于时间的梳理

如何在 Android 设备中使用 GMT 获取时区格式?

如何获取 ISO-8601 GMT/UTC 年周数

NSDate dateWithTimeIntervalSince1970 不返回 GMT/UTC 时间