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

IT技术 javascript timezone utc
2021-01-15 05:53:55

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

当我注意到在 JavaScript 中不能在时区操作方面做很多事情时,我感到很惊讶。

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

你能看出这里有什么主要问题吗?或者也许是从不同角度的解决方案?

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

这对我来说似乎有点复杂。而且我对性能也不太确定。

6个回答
  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()返回星期几

@Merc:1)您正在调用new Date(),它会根据您的 UTC 输入创建一个新日期,但将其视为本地日期/时间。2)是的,你应该Math.floor(this.getTime() / 1000)在这种情况下使用
2021-03-16 05:53:55
1)我没有构造日期......我添加了一个原型函数来处理这个2)好点,我应该做 Math.floor / 1000 - 但我仍然需要该函数才能获得现有日期对象的UTC时间戳......对吗?
2021-03-21 05:53:55
在这里回答,因为我需要更新代码......这是在 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() 不同)
2021-03-29 05:53:55
谢谢兄弟 它的工作文件 Math.floor((new Date()).getTime() / 1000)
2021-04-07 05:53:55

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

new Date().toISOString()
"2016-06-03T23:15:33.008Z"
谢谢@gburton。感谢您看到了通往真理的简单方法。:)
2021-04-03 05:53:55
这是正确答案。许多其他答案给出了“通用时间字符串”,但没有给出当前的“通用协调时间”。我不明白为什么这里的一切都如此复杂。
2021-04-04 05:53:55
这是误导性的,它不提供 UTC 时间戳
2021-04-06 05:53:55
我将它与“.split('T')[0]”一起用于简单的 YYYY-MM-DD 基于日期的比较。
2021-04-09 05:53:55
这提供了 UTC 时间字符串,但 OP 要求提供 UTC时间戳(纪元)
2021-04-09 05:53:55

你也可以使用 getTimezoneOffset 和 getTime,

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

console.log("UTCseconds", UTCseconds)

我测试以下代码:var tt = new Date('Thu Jan 01 1970 08:00:00 GMT+0800 (China Standard Time)'); (tt.getTime() - tt.getTimezoneOffset()*60*1000)/1000. 似乎tt.getTime() - tt.getTimezoneOffset()是正确的GMT+0800
2021-03-14 05:53:55
谢谢,这在互联网上是找不到的!
2021-03-17 05:53:55
看起来这不像写的那样工作..看起来你必须将时间字符串传入new Date()包含时区的..这有点违背了在js中尝试这样做的目的..
2021-03-24 05:53:55
这个更好 var UTCseconds = (Math.floor(x.getTime()/1000) + x.getTimezoneOffset()*60)
2021-04-04 05:53:55
这是完全错误的,分配给UTCseconds 的值不是UTC 秒。日期的时间值UTC,通过任何方法更改它意味着它代表不同的时刻。
2021-04-04 05:53:55

我实际上认为 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();

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

someDate.getTime();

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

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

因此,简而言之,对时区操作没有很多本机支持的原因是因为您根本不想这样做。

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

要获取当前的 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>");

返回以下内容(对于我的美国英语语言环境):

滴答=1409103400661,日期时间=8/26/2014 6:36:40 PM,日期=8/26/2014,时间=6:36:40 PM

通过getTimezoneOffsetgetCurrentTimeUTC函数中添加值,实际上返回的是不同的时间点。结果getTime已经在UTC。
2021-03-14 05:53:55
@MattJohnson:那是不正确的。的结果tmLoc.getTime()是对本地时间的偏移。这很容易检查您是否有权访问运行 JavaScript 的任何内容。
2021-03-15 05:53:55
好吧,既然你获得了tmLocvia new Date(),那么它也是一样的。时区将影响tmLoc.toString()和类似项目的字符串输出,但不会影响tmLoc.getTime() 自 UTC 时间 1970-01-01 午夜以来的毫秒数。
2021-04-04 05:53:55
对不起,但事实并非如此。请参阅MDN 参考您也可以在 ECMAScript 规范中看到这一点。§15.9.3.3 描述getTime,它指向您在§15.9.5 中定义的“时间值” ,即PrimitiveValue,如§15.9.3.3 中明确设置为 UTC。
2021-04-09 05:53:55
@StefansArya: //The offset is in minutes -- convert it to ms
2021-04-11 05:53:55