Mer*_*erc 146 javascript timezone utc
在编写Web应用程序时,将(服务器端)所有日期时间存储在数据库中作为UTC时间戳是有意义的.
当我发现你无法在JavaScript中进行时区操作时,我感到非常惊讶.
我稍微扩展了Date对象.这个功能有意义吗?基本上,每次我向服务器发送任何内容时,它都将是使用此功能格式化的时间戳...
你能看到这里有什么重大问题吗?或者从不同角度解决问题?
Date.prototype.getUTCTime = function(){
return new Date(
this.getUTCFullYear(),
this.getUTCMonth(),
this.getUTCDate(),
this.getUTCHours(),
this.getUTCMinutes(),
this.getUTCSeconds()
).getTime();
}
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎有点令人费解.而且我对表现也不太确定.
DCo*_*der 141
以这种方式构造的日期使用本地时区,使构造日期不正确.设置某个日期对象的时区是从包含时区的日期字符串构造它.(我在使用较旧的Android浏览器时遇到了问题.)
请注意,getTime()
返回毫秒,而不是普通秒.
对于UTC/Unix时间戳,以下内容应该足够:
Math.floor((new Date()).getTime() / 1000)
Run Code Online (Sandbox Code Playgroud)
它会将当前时区偏移量计入结果.对于字符串表示,David Ellis的回答是有效的.
澄清:
new Date(Y, M, D, h, m, s)
Run Code Online (Sandbox Code Playgroud)
该输入被视为当地时间.如果传入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
Run Code Online (Sandbox Code Playgroud)
另请注意,getUTCDate()
不能替代getUTCDay()
.这是因为getUTCDate()
返回该月的某一天 ; 然而,getUTCDay()
返回星期几.
Shi*_*dim 47
你也可以利用getTimezoneOffset和getTime来做到这一点,
x = new Date()
var UTCseconds = (x.getTime() + x.getTimezoneOffset()*60*1000)/1000;
console.log("UTCseconds", UTCseconds)
Run Code Online (Sandbox Code Playgroud)
Tah*_*koz 19
以传统格式获取UTC时间的最简单方法如下:
new Date().toISOString()
"2016-06-03T23:15:33.008Z"
Run Code Online (Sandbox Code Playgroud)
ahm*_*md0 13
您通常不需要在客户端执行大量"时区操作".作为一项规则,我尝试以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;
}
Run Code Online (Sandbox Code Playgroud)
那么您通常需要的是为最终用户设置其本地时区和格式的日期/时间.以下内容将处理客户端计算机上日期和时间格式的所有复杂性:
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();
}
Run Code Online (Sandbox Code Playgroud)
所以下面的例子:
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>");
Run Code Online (Sandbox Code Playgroud)
返回以下内容(对于我的美国英语区域设置):
ticks = 1409103400661,DateTime = 8/26/2014 6:36:40 PM,Date = 8/26/2014,Time = 6:36:40 PM
Mat*_*sch 12
我实际上认为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');
Run Code Online (Sandbox Code Playgroud)
因此,您可以通过这种方式推断出确切的UTC时间.
如果要将Date值传递回要调用的服务器
someDate.toISOString();
Run Code Online (Sandbox Code Playgroud)
或者你是否愿意使用毫秒时间戳(从1970年1月1日UTC开始的毫秒数)
someDate.getTime();
Run Code Online (Sandbox Code Playgroud)
ISO 8601是标准.如果包含日期偏移量,则不能混淆日期字符串的含义.作为开发人员,这对您来说意味着您永远不必自己处理本地时间转换.本地时间值纯粹为了用户的利益而存在,默认情况下日期值显示在其本地时间.所有本地时间操作都允许您显示对用户有意义的内容并从用户输入转换字符串.尽快转换为UTC是一种很好的做法,而js Date对象使这一点变得相当简单.
在缺点方面,没有太多的空间强制客户端(我知道)的时区或区域设置,这可能会令网站特定的设置烦恼,但我猜这背后的原因是它是一个用户不应该触及的配置.
因此,简而言之,没有很多原生支持时区操作的原因是因为你根本就不想这样做.
如果你想要一个单行,UTC Unix 时间戳可以在 JavaScript 中创建为:
var currentUnixTimestap = ~~(+new Date() / 1000);
Run Code Online (Sandbox Code Playgroud)
这将考虑系统的时区。它基本上是自纪元以来经过的秒数。
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
Run Code Online (Sandbox Code Playgroud)
由于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)
Run Code Online (Sandbox Code Playgroud)
我使用以下内容:
Date.prototype.getUTCTime = function(){
return this.getTime()-(this.getTimezoneOffset()*60000);
};
Run Code Online (Sandbox Code Playgroud)
定义此方法后,您可以执行以下操作:
var utcTime = new Date().getUTCTime();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
235509 次 |
最近记录: |