在编写Web应用程序时,将数据库中的所有日期时间(服务器端)存储为UTC时间戳是有意义的。
当我注意到你无法在JavaScript中使用时区操作时,我感到非常惊讶。
我稍微扩展了Date对象。这个功能有意义吗?基本上,每次我向服务器发送任何内容时,它都将是使用此函数格式化的时间戳......
你能看到任何重大问题吗?或者从不同的角度来看解决方案?
Date.prototype.getUTCTime = function(){
return new Date(
this.getUTCFullYear(),
this.getUTCMonth(),
this.getUTCDate(),
this.getUTCHours(),
this.getUTCMinutes(),
this.getUTCSeconds()
).getTime();
}
这对我来说似乎有点费解。而且我对表现也不太了解。
答案 0 :(得分:129)
以这种方式构建的日期使用本地时区,使构造日期不正确。设置某个日期对象的时区是从包含时区的日期字符串构造它。 (我在使用较旧的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()
返回the day of the month;然而,getUTCDay()
会返回the day of the week。
答案 1 :(得分:48)
你也可以利用getTimezoneOffset和getTime,
来做到这一点
x = new Date()
var UTCseconds = (x.getTime() + x.getTimezoneOffset()*60*1000)/1000;
console.log("UTCseconds", UTCseconds)
答案 2 :(得分:40)
toUTCString
method。
var UTCstring = (new Date()).toUTCString();
console.log('UTCstring', UTCstring);
但是,请记住,您获得的日期值取决于客户端计算机的时钟,而不是您的服务器。如果您需要这些日期的精确值(例如,当相对于另一个用户的操作执行此操作或该操作时正确排序),您无法依赖客户端日期库,无论如何,您需要根据客户与您联系的时间来计算服务器端的日期。
请记住,基本上所有客户端代码都可以被客户端修改而且返回的是恶意值,您只能保证服务器端的代码 - 将客户端视为可能的攻击者。
答案 3 :(得分:14)
您通常不需要在客户端执行大量“时区操作”。作为一项规则,我尝试以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>");
返回以下内容(对于我的美国英语区域设置):
ticks = 1409103400661,DateTime = 8/26/2014 6:36:40 PM,Date = 8/26/2014, 时间= 6:36:40 PM
答案 4 :(得分:11)
我实际上认为js中的Date值远比C#DateTime对象好。 C#DateTime对象具有Kind属性,但没有严格的基础时区,如果要在两个非UTC和非本地时间之间进行转换,则难以跟踪时区转换。在js中,所有日期值都具有基础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对象使这一点变得相当简单。
在缺点方面,没有太多的空间来强制客户端(我知道)的时区或区域设置,这可能会令网站特定的设置烦恼,但我猜这背后的原因是这是一个不应该被触及的用户配置。
因此,简而言之,没有很多原生支持时区操作的原因是因为你根本不想这样做。
答案 5 :(得分:10)
以传统格式获取UTC时间的最简单方法如下:
new Date().toISOString()
"2016-06-03T23:15:33.008Z"
答案 6 :(得分:4)
如果您想要一行,可以在JavaScript中创建 UTC Unix时间戳:
var currentUnixTimestap = ~~(+new Date() / 1000);
这将考虑系统的时区。它基本上是自纪元以来在Seconds中流逝的时间。
new Date()
。unary +
来转换为时间戳,以将其转换为timestamp integer
。 :+new Date()
。+new Date() / 1000
~~(+new Date())
答案 7 :(得分:4)
我认为这是一个更好的解决方案
// UTC milliseconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()
// UTC seconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()/1000|0
答案 8 :(得分:4)
我使用以下内容:
Date.prototype.getUTCTime = function(){
return this.getTime()-(this.getTimezoneOffset()*60000);
};
一旦定义了这个方法,你可以这样做:
var utcTime = new Date().getUTCTime();
答案 9 :(得分:2)
由于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)
答案 10 :(得分:1)
我想说明新的Date()。getTime()实际上确实返回了一个UTC值,因此以一种与本地化时间无关的方式存储和管理日期是一种非常有用的方法。
换句话说,不要担心所有UTC javascript函数。相反,只需使用Date.getTime()。
有关解释的更多信息,请点击此处: If javascript "(new Date()).getTime()" is run from 2 different Timezones.
答案 11 :(得分:1)
我很惊讶这个问题变得多么复杂。
这些都是相同的,它们的整数值都是=== EPOCH时间:D
console.log((new Date()).getTime() / 1000, new Date().valueOf() / 1000, (new Date() - new Date().getTimezoneOffset() * 60 * 1000) / 1000);
不要相信我,结帐: http://www.epochconverter.com/
答案 12 :(得分:1)
编辑:以下代码不起作用。我总是假设新的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();
获取自Unix时间1970年1月1日以来的秒数。 正确?
对我来说,有点疯狂,Javascript以UTC时间存储所有内容,但是为了获得该数字,我必须创建一个新的Date对象,传递单个UTC getter,然后最终为此调用getTime()。 ..
Merc的。
答案 13 :(得分:0)
我认为这是你所期待的......
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
答案 14 :(得分:0)
这将以UTC格式返回时间戳:
var utc = new Date(new Date().toUTCString()).getTime();
答案 15 :(得分:0)
一旦您这样做
new Date(dateString).getTime() / 1000
已经是UTC时间戳
const getUnixTimeUtc = (dateString = new Date()) => Math.round(new Date(dateString).getTime() / 1000)
答案 16 :(得分:0)
使用day.js
在浏览器中:
dayjs.extend(dayjs_plugin_utc)
console.log(dayjs.utc().unix())
<script src="https://cdn.jsdelivr.net/npm/dayjs@latest/dayjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dayjs@latest/plugin/utc.js"></script>
在node.js中:
import dayjs from 'dayjs'
dayjs.extend(require('dayjs/plugin/utc'))
console.log(dayjs.utc().unix())
您获得的UTC Unix时间戳不带毫秒。