如何在 JavaScript 中获取 UTC 时间戳?

How do I get a UTC Timestamp in JavaScript?

提问人:Merc 提问时间:3/18/2012 最后编辑:TylerHMerc 更新时间:7/11/2022 访问量:491664

问:

在编写 Web 应用程序时,将数据库中的所有日期时间(服务器端)存储为 UTC 时间戳是有意义的。

当我注意到你在 JavaScript 中的时区操作方面本身无法做太多事情时,我感到很惊讶。

我稍微扩展了 Date 对象。这个功能有意义吗?基本上,每次我向服务器发送任何内容时,它都会是用这个函数格式化的时间戳......

你能在这里看到什么重大问题吗?或者也许是从不同角度的解决方案?

Date.prototype.getUTCTime = function(){ 
  return new Date(
    this.getUTCFullYear(),
    this.getUTCMonth(),
    this.getUTCDate(),
    this.getUTCHours(),
    this.getUTCMinutes(), 
    this.getUTCSeconds()
  ).getTime(); 
}

这对我来说似乎有点令人费解。而且我对性能也不太确定。

JavaScript 时区 UTC

评论

0赞 trysis 1/14/2016
我知道这是一个老问题,但尽量不要像 Date 对象那样扩展本机对象。投了赞成票,因为我喜欢这个问题本身。
0赞 Sagi 1/18/2016
Date.parse(new Date().toUTCString())
66赞 Amadan 4/5/2017
这是今天在我的提要中出现的一个老问题,它充满了错误信息。时间戳始终采用 UTC 格式。 将显示当前时区时间表示,将显示UTC时间,但始终是UTC,因为Unix时间的定义如下:“Unix时间(也称为POSIX时间或纪元时间)是用于描述瞬间的时间系统,定义为自00:00:00协调世界时(UTC)以来经过的秒数, 1970 年 1 月 1 日,星期四,不包括闰秒。new Date().toString()new Date().toUTCString()new Date().getTime()

答:

206赞 DCoder 3/18/2012 #1
  1. 以这种方式构造的日期使用本地时区,使构造的日期不正确。设置某个日期对象的时区就是从包含该时区的日期字符串构造它。(我在较旧的 Android 浏览器中无法使用它。

  2. 请注意,返回的是毫秒,而不是普通的秒。getTime()

对于 UTC/Unix 时间戳,以下内容就足够了:

Math.floor((new Date()).getTime() / 1000)

它会将当前时区偏移量计入结果中。对于字符串表示,David Ellis 的答案是有效的。

澄清一下:

new Date(Y, M, D, h, m, s)

该输入被视为本地时间。如果传入 UTC 时间,结果会有所不同。观察(我现在在格林威治标准时间 +02:00,现在是 07:50):

> var d1 = new Date();
> d1.toUTCString();
"Sun, 18 Mar 2012 05:50:34 GMT" // two hours less than my local time
> Math.floor(d1.getTime()/ 1000)
1332049834 

> var d2 = new Date( d1.getUTCFullYear(), d1.getUTCMonth(), d1.getUTCDate(), d1.getUTCHours(), d1.getUTCMinutes(), d1.getUTCSeconds() );
> d2.toUTCString();
"Sun, 18 Mar 2012 03:50:34 GMT" // four hours less than my local time, and two hours less than the original time - because my GMT+2 input was interpreted as GMT+0!
> Math.floor(d2.getTime()/ 1000)
1332042634

另请注意,不能代替 .这是因为返回当月的某一天;然而,返回星期几getUTCDate()getUTCDay()getUTCDate()getUTCDay()

评论

1赞 Merc 3/18/2012
1) 我没有构建日期......我添加了一个原型函数来解决这个问题。2) 好点子,我应该做 Math.floor / 1000 - 但我仍然需要该函数才能拥有现有日期对象的 UTC 时间戳......右?
0赞 DCoder 3/18/2012
@Merc:1) 您正在调用 ,它从 UTC 输入创建一个新日期,但将其视为本地日期/时间。2) 是的,在这种情况下您应该使用。new Date()Math.floor(this.getTime() / 1000)
0赞 Merc 3/18/2012
在这里回答,因为我需要更新代码......这是为了在现有日期的 UTC 中具有 Unix 时间戳: function (){ return Math.floor( new Date( this.getUTCFullYear(), this.getUTCMonth(), this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds() ).getTime() / 1000); }这意味着我可以做: var n = new Date(2008,10,10) ... ...n.getUTCTime();(这将与 n.getUTCTime() 不同)
1赞 Manoj Patel 2/7/2019
谢谢兄弟 它的工作文件 Math.floor((new Date()).getTime() / 1000)
0赞 Timo 9/25/2022
我需要UTC小时和分钟,这对我有帮助。d1.getUTCHours(), d1.getUTCMinutes()
74赞 Shiplu Mokaddim 3/18/2012 #2

您也可以使用 getTimezoneOffset 和 getTime 来做到这一点,

x = new Date()
var UTCseconds = (x.getTime() + x.getTimezoneOffset()*60*1000)/1000;

console.log("UTCseconds", UTCseconds)

评论

7赞 Theofanis Pantelides 4/2/2015
谢谢,这在互联网上无处可寻!
0赞 zangw 9/1/2015
我测试以下代码: .这似乎是正确的.var tt = new Date('Thu Jan 01 1970 08:00:00 GMT+0800 (China Standard Time)'); (tt.getTime() - tt.getTimezoneOffset()*60*1000)/1000tt.getTime() - tt.getTimezoneOffset()GMT+0800
2赞 StefansArya 6/27/2017
这样更好var UTCseconds = (Math.floor(x.getTime()/1000) + x.getTimezoneOffset()*60)
0赞 claudekennilol 11/27/2018
看起来这不像写的那样工作..看起来您必须将时间字符串传递到包含时区。.这有点违背了尝试在 JS 中执行此操作的目的。new Date()
2赞 RobG 4/7/2020
这是完全错误的,分配给 UTCseconds 的值不是 UTC 秒。Date 的时间值 UTC,通过任何方法更改它,这意味着它表示不同的时间点。
17赞 Matt Esch 3/18/2012 #3

我实际上认为 js 中的 Date 值比 C# DateTime 对象要好得多。C# DateTime 对象具有 Kind 属性,但本身没有严格的基础时区,如果在两个非 UTC 时间和非本地时间之间进行转换,则很难跟踪时区转换。在 js 中,所有 Date 值都有一个基础 UTC 值,无论您进行何种偏离或时区转换,该值都会被传递和已知。我对 Date 对象最大的抱怨是浏览器实现者选择包含的大量未定义行为,这可能会使那些在 js 中攻击日期的人感到困惑,而不是阅读规范。使用类似 iso8601.js 的东西通过定义 Date 对象的单个实现来解决这种不同的行为。

默认情况下,规范说您可以使用扩展的 ISO 8601 日期格式创建日期,例如

var someDate = new Date('2010-12-12T12:00Z');

因此,您可以通过这种方式推断出确切的 UTC 时间。

当您要将 Date 值传递回服务器时,您将调用

someDate.toISOString();

或者,如果您更愿意使用毫秒时间戳(从 1970 年 1 月 1 日 UTC 开始的毫秒数)

someDate.getTime();

ISO 8601 是一项标准。如果包含日期偏移量,则不会对日期字符串的含义感到困惑。对于开发人员来说,这意味着您永远不必自己处理本地时间转换。本地时间值的存在纯粹是为了用户的利益,默认情况下,日期值以本地时间显示。所有本地时间操作都允许您向用户显示一些有意义的内容,并从用户输入转换字符串。尽快转换为 UTC 是一种很好的做法,而 js Date 对象使这变得相当微不足道。

不利的一面是,强制客户端的时区或区域设置的范围不大(我知道),这对于特定于网站的设置来说可能很烦人,但我想这背后的原因是它是一个用户配置不应该被触及。

因此,简而言之,对时区操作的原生支持不多的原因是你根本不想这样做。

1赞 Merc 3/18/2012 #4

编辑:下面的代码不起作用。我一直假设 new Date().getTime() 返回自 1970 年 1 月 1 日以来当前时区的秒数。事实并非如此:getTime() 返回 UTC 中的秒数。因此,下面的代码确实进行了严重的过度调整。谢谢大家!

首先,感谢您的精彩见解。 我想我的问题标题错了......它应该是“获取现有日期的 UTC Unix 时间戳”。

所以,如果我有一个日期对象:

var d = new Date(2009,01,31)

我正在寻找一个会告诉我“UTC Unix 时间戳”的函数。

这个功能似乎是真正的诀窍:

Date.prototype.getUTCUnixTime =  function (){
  return Math.floor( new Date(
    this.getUTCFullYear(),
    this.getUTCMonth(),
    this.getUTCDate(),
    this.getUTCHours(),
    this.getUTCMinutes(), 
    this.getUTCSeconds()
  ).getTime() / 1000); 
}

请注意,它适用于“this”这意味着我可以做:

var n = new Date(2008,10,10)
...
...

n.getUTCUnixTime();

并获取自 1970 年 1 月 1 日以来的 Unix 时间秒数。 右?

对我来说,Javascript 以 UTC 时间存储所有内容有点疯狂,但为了获得该数字,我必须创建一个新的 Date 对象来传递各个 UTC getter,然后最后为此调用 getTime()......

默克。

评论

1赞 Anurag 3/19/2012
你看到@DCoder对他的答案的更新了吗?你的方法得到了错误的时间,而 JavaScript 确实提供了一种从对象获取 unix 时间戳的简单方法——使用该方法。查看所有其他答案。getUTCUnixTimeDategetTime
1赞 Merc 3/19/2012
呃,你是对的,刚刚看到了他们。(用头撞墙)
2赞 fliptopbox 5/31/2014 #5

我对这个问题变得如此复杂感到惊讶。

它们都是相同的,它们的整数值都是 === EPOCH 时间:D

console.log((new Date()).getTime() / 1000, new Date().valueOf() / 1000, (new Date() - new Date().getTimezoneOffset() * 60 * 1000) / 1000);

不相信我,结帐:http://www.epochconverter.com/

13赞 ahmd0 8/27/2014 #6

通常不需要在客户端执行太多的“时区操作”。通常,我尝试以“自 1970 年 1 月 1 日午夜以来的毫秒数”的形式存储和处理 UTC 日期。这确实简化了存储、排序、偏移量的计算,最重要的是,让您摆脱了“夏令时”调整的麻烦。这是我使用的一些 JavaScript 代码。ticks

要获取当前 UTC 时间,请执行以下操作:

function getCurrentTimeUTC()
{
    //RETURN:
    //      = number of milliseconds between current UTC time and midnight of January 1, 1970
    var tmLoc = new Date();
    //The offset is in minutes -- convert it to ms
    return tmLoc.getTime() + tmLoc.getTimezoneOffset() * 60000;
}

然后,您通常需要的是将最终用户的日期/时间格式设置为其本地时区和格式。以下内容负责处理客户端计算机上日期和时间格式的所有复杂性:

function formatDateTimeFromTicks(nTicks)
{
    //'nTicks' = number of milliseconds since midnight of January 1, 1970
    //RETURN:
    //      = Formatted date/time
    return new Date(nTicks).toLocaleString();
}

function formatDateFromTicks(nTicks)
{
    //'nTicks' = number of milliseconds since midnight of January 1, 1970
    //RETURN:
    //      = Formatted date
    return new Date(nTicks).toLocaleDateString();
}

function formatTimeFromTicks(nTicks)
{
    //'nTicks' = number of milliseconds since midnight of January 1, 1970
    //RETURN:
    //      = Formatted time
    return new Date(nTicks).toLocaleTimeString();
}

所以下面的例子:

var ticks = getCurrentTimeUTC();  //Or get it from the server

var __s = "ticks=" + ticks + 
    ", DateTime=" + formatDateTimeFromTicks(ticks) +
    ", Date=" + formatDateFromTicks(ticks) +
    ", Time=" + formatTimeFromTicks(ticks);

document.write("<span>" + __s + "</span>");

返回以下内容(适用于我的美国英语区域设置):

ticks=1409103400661,DateTime=8/26/2014 6:36:40 PM,Date=8/26/2014, 时间=下午 6:36:40

评论

1赞 Matt Johnson-Pint 3/22/2015
通过在函数中添加值,您实际上返回了不同的时间点。的结果已经在 UTC 中。getTimezoneOffsetgetCurrentTimeUTCgetTime
1赞 ahmd0 3/25/2015
@MattJohnson:这是不正确的。的结果是与本地时间的偏移量。这很容易检查您是否有权访问运行 JavaScript 的任何内容。tmLoc.getTime()
2赞 Matt Johnson-Pint 3/25/2015
对不起,但事实并非如此。请参阅 MDN 参考。§15.9.3.3 描述了 getTime,它指向 §15.9.5 中定义的“时间值”,即 §15.9.3.3明确设置为 UTC 的 。PrimitiveValue
2赞 Matt Johnson-Pint 3/25/2015
好吧,既然你通过 获得,那么这是一回事。时区将影响和类似项的字符串输出,但不会影响自 UTC 中 1970-01-01 午夜以来的毫秒数。tmLocnew Date()tmLoc.toString()tmLoc.getTime()
1赞 ahmd0 6/28/2017
@StefansArya://The offset is in minutes -- convert it to ms
4赞 Stan Lin 3/21/2015 #7

我想澄清一下,new Date().getTime() 实际上确实返回了一个 UTC 值,因此它是一种非常有用的方式,可以以与本地化时间无关的方式存储和管理日期。

换句话说,不要为所有的UTC javascript函数而烦恼。相反,只需使用 Date.getTime()。

有关解释的更多信息,请参见此处:如果 javascript “(new Date()).getTime()” 从 2 个不同的时区运行。

13赞 Kushal Likhi 3/27/2015 #8

如果你想要一个衬垫UTC Unix 时间戳可以在 JavaScript 中创建为:

var currentUnixTimestap = ~~(+new Date() / 1000);

这将考虑系统的时区。它基本上是自纪元以来经过的时间(以秒为单位)。

工作原理:

  • 创建日期对象 : .new Date()
  • 通过在对象创建之前添加来转换为时间戳,以将其转换为 .: .unary +timestamp integer+new Date()
  • 将毫秒转换为秒:+new Date() / 1000
  • 使用双波浪号将值四舍五入为整数。:~~(+new Date())

评论

13赞 Sharky 11/17/2016
请勿使用此。在当前的 ecma 规范中,按位运算(如波浪号 - 按位 not)处理 32 位的有符号整数值。这意味着在 2038 年 1 月 19 日之后,当时间戳值将超过 32 位有符号整数的最大值时,这种波浪符魔术将不起作用jsfiddle.net/phb20ymb
2赞 jeffbRTC 4/10/2021
@Sharky我使用它是因为它还不是 2038 年!
1赞 Mikko Ohtamaa 12/2/2022
我保证在2038年1月20日对这个答案投反对票。
0赞 1/20/2023
来自 2023 年的问候,Echo Anybody
125赞 Tahsin Turkoz 6/4/2016 #9

以传统格式获取 UTC 时间的最简单方法如下:

> new Date().toISOString()
"2016-06-03T23:15:33.008Z"

如果需要 EPOC 时间戳,请将日期传递给 Date.parse 方法

> Date.parse(new Date)
1641241000000
> Date.parse('2022-01-03T20:18:05.833Z')
1641241085833

或者,您可以使用 + 进行从 Date 到 Int 的类型转换

> +new Date 
1641921156671

EPOC 时间戳(以秒为单位)。

> parseInt(Date.parse('2022-01-03T20:18:05.833Z') / 1000)
1641241085
> parseInt(new Date / 1000)
1643302523

评论

19赞 speciesUnknown 8/28/2019
这是正确答案。许多其他答案给出了“通用时间字符串”,但没有给出当前的“通用协调时间”。我不明白为什么这里的一切都如此复杂。
1赞 Tahsin Turkoz 8/28/2019
谢谢@gburton。欣赏你看到通往真理的简单方法。:)
1赞 Sean O 9/5/2019
我使用它和“.split('T')[0]”来轻松进行 YYYY-MM-DD 基于日期的比较。
7赞 Jordi Nebot 9/19/2019
这提供了一个 UTC 时间字符串,但 OP 要求提供 UTC 时间戳(纪元)
4赞 GavinBelson 8/27/2020
这是误导性的,它不提供UTC时间戳
6赞 jlbofh 11/24/2016 #10

我使用以下内容:

Date.prototype.getUTCTime = function(){ 
  return this.getTime()-(this.getTimezoneOffset()*60000); 
};

定义此方法后,您可以执行以下操作:

var utcTime = new Date().getUTCTime();

评论

0赞 avalanche1 11/29/2016
最干净的解决方案。感谢!
0赞 jlbofh 7/11/2018
但这并不是发送日期的干净解决方案,因为时间戳始终是 UTC。对我来说,发送日期时最好的解决方案是使用字符串表示形式,例如“dd/MM/yyyy HH:mm:ss”,然后在服务器端使用服务器的默认时区对其进行解析,以获取 UTC 时间戳或其他内容。看到这个答案
2赞 avalanche1 7/14/2018
解析字符串 - 你说它干净吗?呵呵
0赞 jlbofh 7/15/2018
可以肯定的是,有一些方法可以根据 ISO 规范以字符串格式生成日期。方法是 toISOString()。你可以在 Java 中使用如下方法干净地解析它:DateTime dt = new DateTime ("2018-07-15T02:36:00+02:00");
1赞 RobG 4/7/2020
另一个错误的答案是返回 UTC 偏移量,减去本地时区偏移量使其成为本地偏移量,而不是 UTC,因此 getUTCTime 返回本地偏移量,而不是 UTC。this.getTime()
7赞 koalex 12/7/2016 #11

我认为这是一个更好的解决方案

// UTC milliseconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()

// UTC seconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()/1000|0

评论

2赞 RobG 4/7/2020
另一个错误的答案是,getTime 返回一个 UTC 偏移量,添加本地时区偏移量完全搞砸了。ECMAScript 偏移量是 +ve 表示 west,-ve 表示 east,因此应该从 UTC 中减去它们以获得局部值。但是,由于时间值开始时是 UTC,因此添加它实质上会将其从 UTC 移到与局部偏移量相反的方向。
3赞 Kapilrc 12/28/2016 #12

我认为这是你所期待的......

var currTimestamp = Date.now(), //1482905176396
    utcDateString = (new Date(currTimestamp)).toUTCString(); //"Wed, 28 Dec 2016 06:06:50 GMT"

现在

new Date(utcDateString).getTime(); //This will give you UTC Timestamp in JavaScript

评论

0赞 taseenb 8/20/2021
你有什么理由不这样做吗?new Date().toUTCString()
-3赞 Yash Pandya 1/27/2017 #13

这将返回 UTC 格式的时间戳:

var utc = new Date(new Date().toUTCString()).getTime();

评论

2赞 Bas van Dijk 10/4/2017
这不会以 UTC 格式返回时间:给出 Wed Oct 04 2017 07:20:14 GMT+0200 (GMT+02:00)new Date(new Date().toUTCString())
7赞 Maurice Wipf 10/11/2017 #14

由于返回一个字符串,例如您可以对最后 3 个字符进行切片并将切片后的字符串传递给:new Date().toUTCString()"Wed, 11 Oct 2017 09:24:41 GMT"new Date()

new Date()
// Wed Oct 11 2017 11:34:33 GMT+0200 (CEST)

new Date(new Date().toUTCString().slice(0, -3))
// Wed Oct 11 2017 09:34:33 GMT+0200 (CEST)
0赞 fiddlest 4/9/2020 #15

一旦你这样做了

new Date(dateString).getTime() / 1000

它已经是UTC时间戳

   const getUnixTimeUtc = (dateString = new Date()) => Math.round(new Date(dateString).getTime() / 1000)

我在 https://www.unixtimestamp.com/index.php 上进行了测试

0赞 Gnopor 7/11/2022 #16

只需做:

const time = new Date().getTime();

MDN 指出:

Date.prototype.getTime() 返回指定日期的数值,作为自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数。(返回前一次的负值。