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

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

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

这里有什么主要问题吗?或者换个角度解决?

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

我只是觉得有点费解。我对表现也不是很确定。


以这种方式构造的日期使用本地时区,使得构造的日期不正确。要设置某个日期对象的时区,就要从包含该时区的日期字符串构造它。(我在旧版Android浏览器上运行时遇到了问题。) 注意,getTime()返回毫秒,而不是普通的秒。

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

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

它将把当前时区偏移量考虑到结果中。对于字符串表示,David Ellis的答案是可行的。

澄清:

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

该输入被视为本地时间。如果传入UTC时间,结果将有所不同。观察(我现在在GMT +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()返回星期几。


你也可以使用getTimezoneOffset和getTime,

x =新日期() var utccos = (x.getTime() + x. gettimezone胶印()*60*1000)/1000; 游戏机。log (UTCseconds”、“UTCseconds)


I actually think Date values in js are far better than say the C# DateTime objects. The C# DateTime objects have a Kind property, but no strict underlying time zone as such, and time zone conversions are difficult to track if you are converting between two non UTC and non local times. In js, all Date values have an underlying UTC value which is passed around and known regardless of the offest or time zone conversions that you do. My biggest complaint about the Date object is the amount of undefined behaviour that browser implementers have chosen to include, which can confuse people who attack dates in js with trial and error than reading the spec. Using something like iso8601.js solves this varying behaviour by defining a single implementation of the Date object.

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

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

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

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

someDate.toISOString();

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

someDate.getTime();

ISO 8601 is a standard. You can't be confused about what a date string means if you include the date offset. What this means for you as a developer is that you never have to deal with local time conversions yourself. The local time values exist purely for the benefit of the user, and date values by default display in their local time. All the local time manipulations allow you to display something sensible to the user and to convert strings from user input. It's good practice to convert to UTC as soon as you can, and the js Date object makes this fairly trivial.

缺点是,没有太多的范围可以强制客户端的时区或地区(据我所知),这对于特定于网站的设置来说是很烦人的,但我猜这背后的原因是,这是一个不应该被触及的用户配置。

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


编辑:下面的代码不工作。我总是假设new Date(). gettime()返回自1970年1月1日在当前时区的秒数。事实并非如此:getTime()返回UTC的秒数。因此,下面的代码会过度调整。谢谢大家!]

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

如果我有一个date对象

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()…

芝加哥商业交易所。


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

这些都是相同的,它们的整数值都=== EPOCH time:D

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

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


您通常不需要在客户端做太多的“时区操作”。作为一项规则,我尝试以刻度或“自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,日期=8/26/2014, 时间= 6:36:40点


我想说明的是,new Date(). gettime()实际上返回一个UTC值,因此它是一种非常有用的存储和管理日期的方式,不受本地化时间的影响。

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

更多关于解释的信息在这里: 如果javascript "(new Date()). gettime()"从2个不同的时区运行。


如果你想要一行,UTC Unix时间戳可以在JavaScript中创建:

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

这将考虑到系统的时区。它基本上是以秒为单位的从epoch开始的时间。

工作原理:

创建日期对象:new date()。 通过在对象创建之前添加一元+将其转换为时间戳整数来转换为时间戳。: +new Date()。 将毫秒转换为秒:+new Date() / 1000 使用双波浪号将值舍入为整数。: ~~(+new Date())


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

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

如果需要EPOC时间戳,则将日期传递给date。解析方法

> 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

我使用以下方法:

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

一旦定义了这个方法,你可以这样做:

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

我认为这是一个更好的解决办法

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

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

我想这就是你所期待的……

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

Now,

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

这将返回UTC时间戳:

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


因为new Date().toUTCString()返回一个像“Wed, 11 Oct 2017 09:24:41 GMT”这样的字符串,你可以将最后3个字符切片并将切片后的字符串传递给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)

一旦你这样做了

new Date(dateString).getTime() / 1000

它已经是UTC时间戳了

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

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


只做:

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

MDN指出:

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