如何将日期转换为 GMT?

IT技术 javascript
2021-03-11 04:49:15

如何将不同时区的日期转换为 GMT 0?假设我有这样的约会

Fri Jan 20 2012 11:51:36 GMT-0500
Fri Jan 20 2012 11:51:36 GMT-0300
Fri Jan 20 2012 11:51:36 GMT+0500

Fri Jan 20 2012 06:51:36 GMT
Fri Jan 20 2012 08:51:36 GMT
Fri Jan 20 2012 16:51:36 GMT

这些是我new Date().toString()在不同时区获得的日期是否有任何 js 方法来检测时区并进行相应的转换?

编辑:后三个日期不是前三个的 GMT 转换时间。例如,Fri Jan 20 2012 11:51:36 GMT-0500在 GMT 中Fri Jan 20 2012 16:51:36 GMT不是Fri Jan 20 2012 06:51:36 GMT. GMT-0500 在 GMT 之后,而不是在 GMT 之前,因此您必须添加偏移量才能获得 GMT,而不是减去它。

6个回答

Matt Johnson-Pint回答比这个好得多。

console.log(new Date("Fri Jan 20 2012 11:51:36 GMT-0500").toUTCString())

我不知道为什么有人会想要那个,但是我知道如果您将分钟值视为秒值,那么您的公式将无法工作。当然,复制粘贴你的代码会导致史诗般的失败,所以我想最好把它返回到有意义的地方。
2021-04-20 04:49:15
UTC 和 GMT 不一样!
2021-04-22 04:49:15
@Morg 最后一条评论解释说它需要 3.6M 秒......我忘了为什么。如果您检查编辑,我最初放置了 60K 秒。在我回复之前你能确认这是正确的吗?
2021-04-30 04:49:15
不正确。getTimezoneOffset 以分钟为单位,您使用 3.6M 秒。它应该是 60K 秒。提示,永远不要使用大数字,新日期(date3.getTime() + (date3.getTimezoneOffset() * 60 * 1000)); 更喜欢有意义的乘法(即使它们是开销),或者更好的变量,如 var seconds=1000;var minutes=60*seconds;
2021-05-13 04:49:15
对不起,但这个答案是错误的。 getTimezoneOffset根据调用它的日期和运行代码的计算机的时区返回一个偏移量。它并没有提供从构建一个字符串的日期时的偏移通过。此外 - 如此处所示,将偏移量添加到日期时间戳只会改变您正在使用的时间。仍然会根据本地计算机的时区返回字符串结果 - 使用该时区的夏令时规则。
2021-05-15 04:49:15

您可以简单地使用日期对象toUTCString (或toISOString) 方法。

例子:

new Date("Fri Jan 20 2012 11:51:36 GMT-0500").toUTCString()

// Output:  "Fri, 20 Jan 2012 16:51:36 GMT"

如果您更喜欢更好地控制输出格式,请考虑使用诸如date- fnsmoment.js 之类的库

另外,在您的问题中,您实际上错误地转换了时间。当时间戳字符串中显示偏移量时,这意味着字符串中的日期和时间值已经从 UTC 调整了该值。要转换回 UTC,请在应用偏移量之前反转符号。

11:51:36 -0300  ==  14:51:36Z
我同意,但我也发现该解决方案很棒,但后来发现很难将其用于进一步计算
2021-04-22 04:49:15
@BlackMamba - 这是一个与问题中提出的问题不同的问题。此外,由于这些函数有 UTC 版本,因此很容易寻址。
2021-04-26 04:49:15
这绝对是比我更好的答案。
2021-05-01 04:49:15
但是这个解决方案的问题是,如果我需要对日期进行一些操作,它将无法工作,例如 getMonth 和 getDate
2021-05-07 04:49:15
这也让我可以比较日期,很好。
2021-05-11 04:49:15

尽管看起来合乎逻辑,但接受的答案是不正确的,因为 JavaScript 日期不是这样工作的。

在这里需要特别注意的是,JavaScript 中日期(即new Date()-0Date.now()的数值始终以自纪元以来的毫秒为单位来衡量,这是一个基于宇宙历史中精确时刻的无时区量您无需对返回的数值进行任何加减运算即可将数值Date()转换为时区,因为该数值没有 timezone如果它确实有时区,则 JavaScript 日期中的其他所有内容都将不起作用。

时区、闰年、闰秒以及对我们本地时间和日期的所有其他无休止的复杂调整,都是基于这个一致且明确的数值,而不是相反。

以下是日期的数值(提供给日期构造函数)如何独立于时区的示例:

中部标准时间:

new Date(0);
// Wed Dec 31 1969 18:00:00 GMT-0600 (CST)

在阿拉斯加安克雷奇:

new Date(0);
// Wed Dec 31 1969 15:00:00 GMT-0900 (AHST)

在法国巴黎:

new Date(0);
// Thu Jan 01 1970 01:00:00 GMT+0100 (CET)

重要的是要观察到,在所有情况下,基于零毫秒的无时区纪元偏移,结果时间是相同的。法国巴黎的凌晨 1 点与阿拉斯加安克雷奇的前一天下午 3 点完全相同,这与伊利诺伊州芝加哥的下午 6 点完全相同。

因此,此页面上接受的答案是不正确的。观察:

// Create a date.
   date = new Date();
// Fri Jan 27 2017 18:16:35 GMT-0600 (CST)


// Observe the numerical value of the date.
   date.valueOf();
// 1485562595732
// n.b. this value has no timezone and does not need one!!


// Observe the incorrectly "corrected" numerical date value.
   date.valueOf() + date.getTimezoneOffset() * 60000;
// 1485584195732


// Try out the incorrectly "converted" date string.
   new Date(date.valueOf() + date.getTimezoneOffset() * 60000);
// Sat Jan 28 2017 00:16:35 GMT-0600 (CST)

/* Not the correct result even within the same script!!!! */

如果你在另一个时区有一个日期字符串,通过创建的结果对象中没有转换new Date("date string")需要为什么?无论时区如何,该日期的 JavaScript 数值都将相同。无论原始时区是什么,JavaScript 都会自动通过极其复杂的过程来提取自纪元以来的原始毫秒数。

最重要的是,将文本日期字符串x插入new Date(x)构造函数将自动从原始时区(无论可能是什么)转换为无时区的纪元毫秒表示时间,无论任何时区都是相同的。在您的实际应用程序中,您可以选择在您想要的任何时区中显示日期,但不要为此添加/减去日期的数值。在创建日期对象的那一刻,所有的转换都已经发生了。时区甚至不再存在,因为日期对象是使用精确定义且不受时区限制的时间感来实例化的。

当您的应用程序的用户被考虑时,时区才会重新开始存在。用户确实有一个时区,因此您只需向用户显示该时区。但这也会自动发生

让我们考虑一下原始问题中的几个日期:

   date1 = new Date("Fri Jan 20 2012 11:51:36 GMT-0300");
// Fri Jan 20 2012 08:51:36 GMT-0600 (CST)


   date2 = new Date("Fri Jan 20 2012 11:51:36 GMT-0300")
// Fri Jan 20 2012 08:51:36 GMT-0600 (CST)

控制台已经知道我的时区,因此它会自动向我显示这些时间对我的意义。

如果您想知道 GMT/UTC 表示的时间,也不需要转换!你根本不改变时间。您只需显示时间的 UTC 字符串:

    date1.toUTCString();
// "Fri, 20 Jan 2012 14:51:36 GMT"

编写用于使用 JavaScript 日期的数值以数字方式转换时区的代码几乎肯定会失败。时区太复杂了,这就是为什么 JavaScript 被设计成你不需要这样做的原因。

例如: +(new Date("9/9/19")) != +(new Date("9/9/19 GMT-000"))
2021-04-20 04:49:15
是的,我认为这是有效的,因为您在构造函数中提供了一个时区GMT-0500当没有给定时区时,它似乎不起作用。
2021-04-26 04:49:15
@阿兹米索夫。你甚至尝试过吗?正如我所提到的,即使没有时区,也会假设用户的时区,但转换仍然是绝对正确的。如果未指定时区,您是否期待有所不同?例如,如果我的电脑是 CDT,那么:x = new Date('9/20/2017'); Wed Sep 20 2017 00:00:00 GMT-0500 (CDT) x.toUTCString() “Wed, 20 Sep 2017 05:00:00 GMT”一切正常。底线:程序员“不需要”用神奇的数学来去除时区偏移。系统会为您完成。你应该尝试做你自己。
2021-05-06 04:49:15
@Azmisov '您需要删除时区偏移,如已接受的答案中所述' - 如果您使用我建议的方法,那么即使在您提到的情况下也不需要这样做。我建议的解决方案就足够了。在 JavaScript 控制台中尝试以下操作:x = new Date('Fri Jan 20 2012 11:51:36 GMT-0500'); x.toUTCString()您将"Fri, 20 Jan 2012 16:51:36 GMT"得到原始海报所期望的结果。此外,即使没有时区,也会假定用户的时区(正如您所说),但转换仍由toUTCString().
2021-05-09 04:49:15
虽然您是对的,但请注意,如果未给出,则 Date 构造函数将假定时区。如果我这样做new Date("9/9/19"),它将使用客户端的时区。因此,如果您想将日期解释为在 GMT 中给出,则需要删除时区偏移量,如已接受的答案中所述。
2021-05-13 04:49:15

只需使用Date.getUTC*()系列方法。在我的电脑上(欧洲中部时间,UTC+01:00):

new Date().toString()
//Fri Jan 20 2012 18:05:16 GMT+0100 (CET)

new Date().getHours()
//18

new Date().getUTCHours()
//17

请注意,getUTCHours()在 UTC返回正确的小时。

也可以看看:

我只是在研究这个,我可能有点晚了,但我做了一个解决方法。以下是步骤: - 从应用程序被触发的任何时区获取当前时间。- - 从 gmt 0 获取该区域的时区偏移量。然后添加您的时区值(以毫秒为单位)。您将获得您所在时区的日期。我添加了一些额外的代码以在实际时间之后删除任何内容。

getCurrentDate() {
    var date = new Date();
    var newDate = new Date(8 * 60 * 60000 + date.valueOf() + 
                           (date.getTimezoneOffset() * 60000));
    var ampm = newDate.getHours() < 12 ? ' AM' : ' PM';
    var strDate = newDate + '';
    return (strDate).substring(0, strDate.indexOf(' GMT')) + ampm
}
这是唯一对我的情况有效的方法。非常感谢 :)
2021-04-27 04:49:15