简体   繁体   English

Javascript:将字符串解析为日期作为本地时区

[英]Javascript: parse a string to Date as LOCAL time zone

I have a string representing the current time: 2015-11-24T19:40:00 .我有一个表示当前时间的字符串: 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 ?如何在 Javascript 中解析此字符串以获取此字符串表示的日期作为LOCAL TIME Due to some restriction, I cannot use the library moment , but jquery is allowed.由于某些限制,我不能使用库moment ,但允许使用 jquery。 I know that someone has asked this question before, but the answer used moment我知道之前有人问过这个问题,但答案使用了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 UTC time ( 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 PACIFIC time ( 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");我尝试将 "Z" 添加到str ,就像这样var date = new Date(str+"Z"); , then both browsers give me UTC time. ,然后两个浏览器都给我 UTC 时间。 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"字母告诉所有浏览器(至少是 chrome、Firefox 和 Safari)将字符串解析为本地时区?

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),您可能会得到以下结果之一:

  1. Pre ES5 implementaitons may treat it as anything, even NaN (such as IE 8) ES5 之前的实现可以将其视为任何东西,甚至是 NaN(例如 IE 8)
  2. ES5 compliant implementations will treat it as UTC timezone符合 ES5 的实现会将其视为 UTC 时区
  3. ECMAScript 2015 compliant implementations will treat it as local (which is consistent with ISO 8601)符合 ECMAScript 2015 的实现会将其视为本地(与 ISO 8601 一致)

A Date object has a time value which is UTC, and an offset based on system settings. Date 对象有一个 UTC 时间值和一个基于系统设置的偏移量。 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 到输出时,你看到的通常是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, eg 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,它不接受任何其他时区指定(如果缺少,请注意上述行为)。

A variation on RobG's terrific answer. RobG 出色答案的变体。

Note that 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);
}

Note that this doesn't take into account if the date/time given is in any timezone.请注意,如果给定的日期/时间在任何时区,这不会考虑在内。 It will assume local time.它将假设当地时间。 You can change new Date for Date.UTC to assume UTC.您可以更改Date.UTC new Date以采用 UTC。

There are technical reasons for why you would write you code like this.为什么你会写这样的代码是有技术原因的。 For example, here we apply the correct number of arguments, with their corresponding expected type.例如,在这里我们应用正确数量的参数,以及它们对应的预期类型。 It's true that the Date constructor will turn strings into numbers but what could be happening is that there's a deoptimization taking place where the optimized code is expecting a number but sees a string and takes a slower path. Date 构造函数确实会将字符串转换为数字,但可能发生的情况是发生了去优化,其中优化的代码期望一个数字,但看到一个字符串并采用较慢的路径。 Not a big deal but I try to write my JavaScript to avoid such things.没什么大不了的,但我尝试编写我的 JavaScript 来避免这些事情。 We also won't be indexing outside the bounds of the array if less than 6 components can be found in the string which is also one of those things you can do in JavaScript but it has subtle deoptimization caveats.如果在字符串中可以找到少于 6 个组件,我们也不会在数组边界之外进行索引,这也是您可以在 JavaScript 中做的事情之一,但它有微妙的去优化警告。

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.这将适用于和/或没有 'T' 和 'Z' 字符串,并且仍然具有不错的性能。 I added the explicit Number conversion (faster and better than parseInt) so this also compiles in TypeScript.我添加了显式数字转换(比 parseInt 更快更好),因此这也可以在 TypeScript 中编译。 Number数字

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM