首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >解析字符串以转换为Date还是让JavaScript进行转换更好?

解析字符串以转换为Date还是让JavaScript进行转换更好?
EN

Stack Overflow用户
提问于 2019-11-15 05:40:23
回答 3查看 164关注 0票数 2

目前,我有一个函数可以将字符串转换为Date对象,如果没有将小时和分钟设置为0,则该字符串可能包含或不包含时间信息:

代码语言:javascript
运行
复制
const stringToDate = string => {
  const [, y, m, d, h = 0, min = 0] = string.match(/(\d{4})-(\d{2})-(\d{2})(?: (\d{2}):(\d{2}))?/)
  return new Date(y, parseInt(m) - 1, d, h, min)
}

console.log(stringToDate("2017-07-09"))

,我想知道,如果我只依靠Date对象为我这样做,它是否会更有表现力,或者更可靠:

代码语言:javascript
运行
复制
// Replace '-' with '/' for Safari.
const stringToDate = string => new Date(string.replace(/-/g, '/')) 

console.log(stringToDate("2017-07-09"))

我知道日期方法根据浏览器的不同行为(例如Safari不能读取'-'),我也关注夏时制可能出现的错误。两条路都安全吗?

Converting a string to a date in JavaScript中找不到答案

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-11-16 03:58:59

TL;博士

使用新日期()的更快,这两种方法都在Chrome、Firefox、Safari.上进行了可靠的测试。

我在5年内为这两个函数编写了测试用例。然后,我在Chrome、Safari和Firefox上运行了基准测试来比较它们,下面是结果:

https://jsperf.com/string-to-date-regexp-vs-new-date/1

在jsbench.me上的相同结果:

我们可以看到,在所有情况下,使用regexp都要慢一些( Safari比其他浏览器更慢)。

我还在这两种情况下添加了一个检查,以验证stringToDate函数的计算日期在5年内总是正确的(这显然超过了10个DLS日期和至少一个闰年)。

如果返回的日期可能是错误的,则循环将以错误结束,下面是我的测试:

  1. 通过regexp

代码语言:javascript
运行
复制
const stringToDate = string => {
  const [, y, m, d, h = 0, min = 0] = string.match(/(\d{4})-(\d{2})-(\d{2})(?: (\d{2}):(\d{2}))?/)
  return new Date(y, parseInt(m) - 1, d, h, min)
}

let tmpDate = new Date()
for (let i = 0; i <= 365 * 5; i++) {
  let y = tmpDate.getFullYear()
  let m = tmpDate.getMonth()
  let d = tmpDate.getDate()

  tmpDate = new Date(y, m, d + 1, 0, 0)
  y = tmpDate.getFullYear()
  m = tmpDate.getMonth() + 1
  d = tmpDate.getDate()

  const tmpDateFormatted = `${y}-${m < 10 ? '0' : ''}${m}-${d < 10 ? '0' : ''}${d}`
  const calculatedDate = stringToDate(tmpDateFormatted)
  // console.log(calculatedDate)
  
  if (calculatedDate.getTime() !== tmpDate.getTime()) {
    console.error('Wrong date.', calculatedDate, 'should be', tmpDate)
  }
}

通过新日期()

代码语言:javascript
运行
复制
// Replace '-' with '/' for Safari.
const stringToDate = string => new Date(string.replace(/-/g, '/')) 

let tmpDate = new Date()
for (let i = 0; i <= 365 * 5; i++) {
  let y = tmpDate.getFullYear()
  let m = tmpDate.getMonth()
  let d = tmpDate.getDate()

  tmpDate = new Date(y, m, d + 1, 0, 0)
  y = tmpDate.getFullYear()
  m = tmpDate.getMonth() + 1
  d = tmpDate.getDate()

  const tmpDateFormatted = `${y}-${m < 10 ? '0' : ''}${m}-${d < 10 ? '0' : ''}${d}`
  const calculatedDate = stringToDate(tmpDateFormatted)
  // console.log(calculatedDate)
  
  if (calculatedDate.getTime() !== tmpDate.getTime()) {
    console.error('Wrong date.', calculatedDate, 'should be', tmpDate)
  }
}

希望它能帮到别人!

票数 0
EN

Stack Overflow用户

发布于 2019-11-15 09:16:07

您的regex意味着您使用的是non-standard date time formats,这在Safari中是失败的。即使您更正了格式,仍然会出现这样的问题:Safari实现不带时区的解析时间是错误的(也就是说,不符合规范)。

代码语言:javascript
运行
复制
new Date('2019-11-15 10:06'); // DO NOT USE: fails in Safari

因此,最好坚持使用stringToDate函数来创建date对象。

票数 0
EN

Stack Overflow用户

发布于 2019-11-15 12:51:48

你已经回答了你的问题:

,我想知道如果我仅仅依靠内置的解析器为我做…,它是否会更有表现力,或者更可靠?

我知道根据浏览器…,数据解析器的行为不同。

因此,您已经知道使用内置解析器是不可靠的。

ECMA-262只支持两种格式,而当前至少有一种浏览器无法解析其中的一种,而旧的浏览器也会失败。所以你的选择是:

  1. 使用一个简单的函数来解析特定的格式字符串,在其中您可以确定结果
  2. 使用库和解析器提供要解析的格式,并再次确定结果
  3. 希望,无论运行什么实现,代码的正确解析都是基于您尝试过的两个浏览器所做的,而忽略了可能运行您的代码

的大量其他现有和未来实现。

不是一个很难的选择。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58870954

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档