在编写 Web 应用程序时,将(服务器端(数据库中的所有日期时间存储为 UTC 时间戳是有意义的。
当我注意到你在 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 时间,结果将有所不同。观察(我现在在格林威治标准时间 +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()
返回星期几。
以常规格式获取 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
或者,您可以使用 + 进行从日期到国际的类型转换
> +new Date
1641921156671
以秒为单位的 EPOC 时间戳。
> parseInt(Date.parse('2022-01-03T20:18:05.833Z') / 1000)
1641241085
> parseInt(new Date / 1000)
1643302523
你也可以使用 getTimezoneOffset 和 getTime 来做到这一点,
x = new Date()
var UTCseconds = (x.getTime() + x.getTimezoneOffset()*60*1000)/1000;
console.log("UTCseconds", UTCseconds)
我实际上认为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 对象使这变得相当微不足道。
不利的一面是,强制客户端的时区或区域设置的范围不大(我知道(,这对于特定于网站的设置来说可能很烦人,但我想这背后的原因是它是一个用户配置不应该被触及。
因此,简而言之,对时区操作没有太多本机支持的原因是因为您根本不想这样做。
您通常不需要在客户端执行太多的"时区操作"。通常,我尝试以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/20146:36:40 PM, 日期=8/26/2014, 时间=下午 6:36:40
想要一行,UTC Unix 时间戳可以在 JavaScript 中创建为:
var currentUnixTimestap = ~~(+new Date() / 1000);
这将考虑系统的时区。它基本上是自纪元以来以秒为单位经过的时间。
工作原理:
- 创建日期对象:
new Date()
。 - 通过在对象创建之前添加
unary +
将其转换为timestamp integer
来转换为时间戳。 :+new Date()
. - 将毫秒转换为秒:
+new Date() / 1000
- 使用双波形符将值舍入为整数。 :
~~(+new Date())
我认为这是一个更好的解决方案
// UTC milliseconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()
// UTC seconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()/1000|0
<</div>
div class="one_answers">由于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)
我使用以下方法:
Date.prototype.getUTCTime = function(){
return this.getTime()-(this.getTimezoneOffset()*60000);
};
定义此方法后,您可以执行以下操作:
var utcTime = new Date().getUTCTime();
明确指出,新的 Date((.getTime(( 确实返回了一个 UTC 值,因此这是一种非常有用的方法,可以存储和管理日期,与本地化时间无关。
换句话说,不要打扰所有的UTC javascript函数。相反,只需使用 Date.getTime((。
有关解释的更多信息,请点击此处:如果javascript"(new Date(((.getTime(("从2个不同的时区运行。
我认为这是您所期望的...
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
我对这个问题变得如此复杂感到惊讶。
它们都是相同的,它们的整数值都 === 纪元时间:D
console.log((new Date()).getTime() / 1000, new Date().valueOf() / 1000, (new Date() - new Date().getTimezoneOffset() * 60 * 1000) / 1000);
不信,结帐:http://www.epochconverter.com/
编辑:下面的代码不起作用。我总是假设新的 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);
}
请注意,它适用于"这个"这意味着我可以做:
var n = new Date(2008,10,10)
...
...
n.getUTCUnixTime();
并获取自 1970 年 1 月 1 日以来的 Unix 时间秒数。右?
对我来说,Javascript 将所有内容都存储在 UTC 时间中有点疯狂,但是为了获得该数字,我必须创建一个新的 Date 对象,传递各个 UTC getter,然后最终调用 getTime(( 为此......
默克。
一旦你这样做了
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 以来的毫秒数。(返回先前时间的负值。
这将返回 UTC 格式的时间戳:
var utc = new Date(new Date().toUTCString()).getTime();