Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/466.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用一致的时区解释解析javascript日期?_Javascript_Date_Datetime - Fatal编程技术网

使用一致的时区解释解析javascript日期?

使用一致的时区解释解析javascript日期?,javascript,date,datetime,Javascript,Date,Datetime,假设我有两种不同类型的日期字符串——mysql日期戳和mysql日期+时间戳 "2015-12-25" "2015-12-25 00:00:00" 当我在JavaScript中解析这些时,我得到: new Date("2015-12-25"); Thu Dec 24 2015 19:00:00 GMT-0500 (Eastern Standard Time) new Date("2015-12-25 00:00:00"); Fri Dec 25 2015 00:00:00 GMT-0500 (

假设我有两种不同类型的日期字符串——mysql日期戳和mysql日期+时间戳

"2015-12-25"
"2015-12-25 00:00:00"
当我在JavaScript中解析这些时,我得到:

new Date("2015-12-25");
Thu Dec 24 2015 19:00:00 GMT-0500 (Eastern Standard Time)
new Date("2015-12-25 00:00:00");
Fri Dec 25 2015 00:00:00 GMT-0500 (Eastern Standard Time)
或者,在UTC中:

new Date("2015-12-25").toUTCString();
"Fri, 25 Dec 2015 00:00:00 GMT"
new Date("2015-12-25 00:00:00").toUTCString();
"Fri, 25 Dec 2015 05:00:00 GMT"
在末尾添加时间会使日期提前几个小时解析为我的时区。我想要的是某种函数,使它们作为同一个东西进行解析-GMT或no,我可以调整,只要结果是已知的一个或另一个,不管传入的日期字符串如何

我实现了一个涉及正则表达式和检测日期格式的解决方案,完成了一半,然后才发现可能有更好的方法来实现这一点

我发现了一些涉及
Date.prototype.getTimezoneOffset()
的解决方案,但是对于这两个日期,它们返回相同的内容,因为它们被解析为在同一时区

有什么想法吗?

ECMAScript ed 5.1(也称ES5)要求将ISO 8601日期字符串解析为UTC,但ISO要求将其解析为本地。现在,当前的ECMAScript标准(版本6)与ISO一致,并且要求将不带时区的符合ISO的字符串解析为本地字符串

ECMAScript 2016(第7版)再次更改,因此YYYY-MM-DD格式的日期字符串被解析为UTC,因此不再符合ISO 8601

因此,你是否会有一种行为取决于浏览器(如果你在IE8上尝试,你会得到NaN)。在ES5之前,所有字符串的解析依赖于实现

“2015-12-25”是一个有效的ISO 8601字符串,没有时区,因此根据ES5规则应视为UTC,根据ed 6规则应视为本地

“2015-12-25 00:00:00”不是有效的ISO字符串(日期和时间之间缺少“T”),因此浏览器可以随意解析它(解析非ISO字符串取决于所有版本的ECMAScript的实现)

底线是不要使用日期构造函数来解析字符串(或Date.parse)。自己解析它们

要解析类似ISO的字符串,请使用以下内容。它将不带偏移量的字符串视为UTC(根据ES5),但现在可能应该将其更改为本地:

/**
 * Parse an ISO string with or without an offset
 *   e.g. '2014-04-02T20:00:00-0600'
 *        '2014-04-02T20:00:00Z'
 *        '2014-02'
 *
 * Allows decimal seconds if supplied
 *   e.g. '2014-04-02T20:00:00.123-0600'
 *
 * If no offset is supplied (or it's Z), treat as UTC (per ECMA-262)
 *
 * If date only, e.g. '2014-04-02' or '2014-02', treat as UTC date (per ECMA-262)
 * All parts after year are optional
 * Don't allow two digit years to be converted to 20th century years
 * @param {string} s - ISO 860 date string
*/
function parseISOString(s) {
  var invalidDate = new Date(NaN);
  var t = s.split(/\D+/g);
  var hasOffset = /[-+]\d{4}$/.test(s);

  // Whether decimal seconds are present changes the offset field and ms value
  var hasDecimalSeconds = /[T ]\d{2}:\d{2}:\d{2}\.\d+/i.test(s);
  var offset = hasDecimalSeconds? t[7] : t[6];
  var offSign;
  var yr  = +t[0],
      mo  = t[1]? --t[1] : 0,
      da  = +t[2] || 1,
      hr  = +t[3] || 0,
      min = +t[4] || 0,
      sec = +t[5] || 0,
      ms  = hasDecimalSeconds? +t[6] : 0,
      offSign = hasOffset? /-\d{4}$/.test(s)? 1 : -1 : 0,
      offHr   = hasOffset? offset/100 | 0 : 0,
      offMin  = hasOffset? offset%100 : 0;

  // Ensure time values are in range, otherwise invalid date.
  // Values can't be -ve as splitting on non-digit character
  if (hr > 24 || min > 59 || sec > 59 || ms > 1000 || offHr > 24 || offMin > 59){
    return invalidDate;
  }

  // Create a date object from date parts, check for validity
  // Avoid two digit years being converted to 20th century
  var d = new Date();
  d.setUTCFullYear(yr, mo, da);

  // Check that date values are valid
  if (d.getUTCFullYear() != yr || d.getUTCDate() != da) {
    return invalidDate;
  }

  // If there's an offset, apply it to minutes to get a UTC time value
  min = hasOffset? +min + offSign * (offHr * 60 + offMin) : min;

  // Set UTC time values of d
  d.setUTCHours(hr, min, sec, ms);

  return d;
}

它可以减少到不到一半,但它的编写是为了便于阅读和维护。

您不能将“2015-12-25 00:00:00”中的最后一个字符删去,使其变成“2015-12-25”,如果输入只有两个大小写?它不仅仅有两个大小写-这只是一个例子。我想捕获任何时间信息,如果它存在的话。不过,我考虑过在字符串的末尾加上额外的00:00:00。问题在于确定可以将此额外位附加到的字符串-否则,它将返回无效日期:(将时间存储为整数或ISO格式8601@PaulS.-对于这个特殊的问题,请假设我无法控制存储中的日期格式。看起来我的半成品正则表达式解决方案比我想象的更接近。还有,见鬼,IE8?总是有更多,而且总是更糟。@Spirlypear IE 8于2009年发布,比ES5上市早两年标准。在ECMAScript ed 3下,字符串解析完全依赖于实现,大多数浏览器不支持ISO字符串。返回NaN只是他们当时和现在按照标准说“我无法解析该字符串”的方式。