假设您网站的用户输入了一个日期范围。
2009-1-1 to 2009-1-3
您需要将此日期发送到服务器进行某些处理,但服务器要求所有日期和时间均为UTC。
现在假设用户在阿拉斯加。由于它们所处的时区与UTC完全不同,因此需要将日期范围转换为如下所示:
2009-1-1T8:00:00 to 2009-1-4T7:59:59
使用JavaScriptDate对象,如何将第一个“本地化”日期范围转换为服务器能够理解的内容?
假设您网站的用户输入了一个日期范围。
2009-1-1 to 2009-1-3
您需要将此日期发送到服务器进行某些处理,但服务器要求所有日期和时间均为UTC。
现在假设用户在阿拉斯加。由于它们所处的时区与UTC完全不同,因此需要将日期范围转换为如下所示:
2009-1-1T8:00:00 to 2009-1-4T7:59:59
使用JavaScriptDate对象,如何将第一个“本地化”日期范围转换为服务器能够理解的内容?
当前回答
这是我的方法:
var now = new Date();
var utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000);
生成的utc对象实际上不是utc日期,而是转换为与utc时间匹配的本地日期(请参见注释)。然而,在实践中,它确实起到了作用。
更新:当调用UTC.toString()、UTC.toLocaleString()等时,这个答案是获取UTC日期的一种快速而肮脏的方法。不过,有更好的解决方案,尤其是现在使用现代浏览器的情况下,我应该改进一下答案。基本上,.toISOString()(IE 9+)是您想要使用的。
其他回答
所以这是我必须要做的,因为我仍然希望JavaScript日期对象作为日期进行操作,而不幸的是,这些答案中的很多都需要您转到字符串。
//First i had a string called stringDateVar that i needed to convert to Date
var newDate = new Date(stringDateVar)
//output: 2019-01-07T04:00:00.000Z
//I needed it 2019-01-07T00:00:00.000Z because i had other logic that was dependent on that
var correctDate = new Date(newDate.setUTCHours(0))
//This will output 2019-01-07T00:00:00.000Z on everything which allows scalability
这个功能对我来说非常有用。
function ParseDateForSave(dateValue) {
// create a new date object
var newDate = new Date(parseInt(dateValue.substr(6)));
// return the UTC version of the date
return newDate.toISOString();
}
另一种转换为UTC并将其保留为日期对象的解决方案:(它的工作方式是从格式化字符串的末尾删除“GMT”部分,然后将其放回Date构造函数中)
var now=新日期();var now_utc=新日期(now.toUTCString().slice(0,-4));控制台日志(now_utc)
我需要这样做来与日期时间选择器库交互。但总的来说,这样处理约会是个坏主意。
用户通常希望使用本地时间的日期时间,因此您可以更新服务器端代码以正确解析带有偏移量的日期时间字符串,然后转换为UTC(最佳选项),或者在发送到服务器之前转换为UTC字符串(如Will Stern的回答)
浏览器可能会有所不同,你也应该记住不要相信客户端生成的任何信息,也就是说,下面的声明适用于我(Mac OS X 10.8.2上的Google Chrome v24)
var utcDate=新日期(new Date().getTime());
edit:“这和new Date()有什么不同?”请参见此处:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
如果未提供任何参数,则构造函数将根据系统设置为当前日期和时间创建JavaScript Date对象。注意:当Date作为具有多个参数的构造函数调用时,指定的参数表示本地时间。如果需要UTC,请使用具有相同参数的新日期(Date.UTC(…))。(注意:Date.UTC()返回自1970-01-01 00:00:00 UTC以来的毫秒数)
如前面的答案所述,添加60000*Date.getTimezoneOffset()是不正确的。首先,您必须将所有日期/时间视为UTC,并使用时区修饰符进行显示。
同样,浏览器可能有所不同,然而,Date.getTime()返回自1970-01-01 UTC/GMT以来的毫秒数。如果您像我上面所做的那样使用这个数字创建一个新的日期,它将是UTC/GMT。但是,如果通过调用.toString()来显示它,它将显示在本地时区中,因为.toString()使用的是本地时区,而不是调用它的Date对象的时区。
我还发现,如果您在日期上调用.getTimezoneOffset(),它将返回您的本地时区,而不是您调用它的日期对象的时区(但我无法验证这是否是标准的)。
在我的浏览器中,添加60000*Date.getTimezoneOffset()将创建一个不是UTC的DateTime。然而,当在我的浏览器中显示(例如:.toString())时,它会在我的本地时区中显示一个DateTime,如果忽略时区信息,该DateTime将是正确的UTC时间。
toISOString()方法返回简化扩展ISO格式的字符串格式(ISO 8601),总是24或27个字符长(YYYY-MM-DDTH:MM:ss.sssZ或±YYYY-MM-dDTH:MM:ss.sssZ,分别)。时区始终为零UTC偏移,如后缀“Z”。
来源:MDN网络文档
您需要的格式是用.toISOString()方法创建的。对于本机不支持此方法的旧浏览器(ie8及以下版本),可以在此处找到垫片:
这将使您能够执行所需的操作:
var isoDateString=新日期().toISOString();console.log(isoDateString);
对于时区工作,moment.js和moment.jstimezone是非常宝贵的工具。。。特别是用于在客户端和服务器javascript之间导航时区。