Javascript:将字符串解析为日期作为本地时区
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33908299/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript: parse a string to Date as LOCAL time zone
提问by Simo
I have a string representing the current time: 2015-11-24T19:40:00
. How do I parse this string in Javascript to get a Date represented by this string as the LOCAL TIME? Due to some restriction, I cannot use the library moment
, but jquery is allowed. I know that someone has asked this question before, but the answer used moment
我有一个表示当前时间的字符串:2015-11-24T19:40:00
. 如何在 Javascript 中解析此字符串以获取此字符串表示的日期作为LOCAL TIME? 由于某些限制,我不能使用库moment
,但允许使用jquery。我知道之前有人问过这个问题,但答案使用moment
For example, if I run the script in California, then this string would represent 7PM pacific time, but if I run the script in NY then this string would represent Eastern Time?
例如,如果我在加利福尼亚运行脚本,那么这个字符串将代表太平洋时间晚上 7 点,但如果我在纽约运行脚本,那么这个字符串将代表东部时间?
I tried the following but Chrome and Firefox give me different results:
我尝试了以下方法,但 Chrome 和 Firefox 给了我不同的结果:
var str = "2015-11-24T19:40:00";
var date = new Date(str);
Chrome consumes it as UTCtime (Tue Nov 24 2015 11:40:00 GMT-0800 (Pacific Standard Time)
),
Chrome 将其用作UTC时间 ( Tue Nov 24 2015 11:40:00 GMT-0800 (Pacific Standard Time)
),
but Firefox consumes it as my local PACIFICtime (Tue Nov 24 2015 19:40:00 GMT-0800 (Pacific Standard Time)
)
但 Firefox 将其用作我当地的太平洋时间 ( Tue Nov 24 2015 19:40:00 GMT-0800 (Pacific Standard Time)
)
I tried adding "Z" to str
, like this var date = new Date(str+"Z");
, then both browsers give me UTC time. Is there any similar letter to "Z"
which tells all browsers (at least chrome, Firefox and Safari) to parse the string as local time zone?
我尝试将“Z”添加到str
,像这样var date = new Date(str+"Z");
,然后两个浏览器都给我 UTC 时间。是否有任何类似的字母"Z"
告诉所有浏览器(至少是 chrome、Firefox 和 Safari)将字符串解析为本地时区?
回答by RobG
Parsing of date strings using the Date constructor or Date.parse (which are essentially the same thing) is strongly recommended against.
强烈建议不要使用 Date 构造函数或 Date.parse(本质上是相同的)解析日期字符串。
If Date is called as a function and passed an ISO 8601 format date string without a timezone (such as 2015-11-24T19:40:00), you may get one of the following results:
如果将 Date 作为函数调用并传递不带时区的 ISO 8601 格式日期字符串(例如 2015-11-24T19:40:00),您可能会得到以下结果之一:
- Pre ES5 implementaitons may treat it as anything, even NaN (such as IE 8)
- ES5 compliant implementations will treat it as UTC timezone
- ECMAScript 2015 compliant implementations will treat it as local (which is consistent with ISO 8601)
- ES5 之前的实现可以将其视为任何东西,甚至是 NaN(例如 IE 8)
- 符合 ES5 的实现会将其视为 UTC 时区
- 符合 ECMAScript 2015 的实现会将其视为本地(与 ISO 8601 一致)
A Date object has a time value which is UTC, and an offset based on system settings. When you send a Date to output, what you see is usually the result of Date.prototype.toString, which is an implementation dependent, human readable string representing the date and time, usually in a timezone based on system settings.
Date 对象有一个 UTC 时间值和一个基于系统设置的偏移量。当你发送一个 Date 到输出时,你看到的通常是Date.prototype.toString的结果,它是一个依赖于实现的、人类可读的表示日期和时间的字符串,通常在基于系统设置的时区中。
The best way to parse date strings is to do it manually. If you are assured that the format is consistent and valid, then parsing an ISO format string as a local date is as simple as:
解析日期字符串的最佳方法是手动进行。如果您确定格式一致且有效,那么将 ISO 格式字符串解析为本地日期就非常简单:
/* @param {string} s - an ISO 8001 format date and time string
** with all components, e.g. 2015-11-24T19:40:00
** @returns {Date} - Date instance from parsing the string. May be NaN.
*/
function parseISOLocal(s) {
var b = s.split(/\D/);
return new Date(b[0], b[1]-1, b[2], b[3], b[4], b[5]);
}
document.write(parseISOLocal('2015-11-24T19:40:00'));
Note that parsing of ISO strings using Date.parse only accepts UTC, it does not accept any other timezone designation (noting the above behaviour if it's missing).
请注意,使用 Date.parse 解析 ISO 字符串仅接受 UTC,它不接受任何其他时区指定(如果缺少,请注意上述行为)。
回答by John Leidegren
A variation on RobG's terrific answer.
RobG 出色答案的变体。
Notethat this will require that you run bleeding edge JavaScript as it relies on the arrow notation and spread operator.
请注意,这将要求您运行前沿的 JavaScript,因为它依赖于箭头符号和展开运算符。
function parseDateISOString(s) {
let ds = s.split(/\D+/).map(s => parseInt(s));
ds[1] = ds[1] - 1; // adjust month
return new Date(...ds);
}
The benefit of this approach is that it automatically applies the correct number of arguments passed. If this is what you want.
这种方法的好处是它会自动应用传递的正确数量的参数。如果这是你想要的。
回答by Huupke
Where Date is called as a constructor with more than one argument, the specified arguments represent local time.
当 Date 作为具有多个参数的构造函数被调用时,指定的参数表示本地时间。
I also have a much faster way than using the string.split() because we already know where the numbers are:
我还有一个比使用 string.split() 更快的方法,因为我们已经知道数字在哪里:
return new Date(Number(date.substring(0, 4)), Number(date.substring(5, 7))-1,
Number(date.substring(8, 10)), Number(date.substring(11, 13)),
Number(date.substring(14, 16)), Number(date.substring(17, 19)));
This will work with and/or without the 'T' and 'Z' strings and still has decent performance. I added the explicit Number conversion (faster and better than parseInt) so this also compiles in TypeScript. Number
这将适用于和/或没有 'T' 和 'Z' 字符串,并且仍然具有不错的性能。我添加了显式数字转换(比 parseInt 更快更好),因此这也可以在 TypeScript 中编译。数字