目前,我有一个函数可以将字符串转换为Date对象,如果没有将小时和分钟设置为0,则该字符串可能包含或不包含时间信息:
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对象为我这样做,它是否会更有表现力,或者更可靠:
// Replace '-' with '/' for Safari.
const stringToDate = string => new Date(string.replace(/-/g, '/'))
console.log(stringToDate("2017-07-09"))
我知道日期方法根据浏览器的不同行为(例如Safari不能读取'-'),我也关注夏时制可能出现的错误。两条路都安全吗?
发布于 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日期和至少一个闰年)。
如果返回的日期可能是错误的,则循环将以错误结束,下面是我的测试:
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)
}
}
通过新日期()
// 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)
}
}
希望它能帮到别人!
发布于 2019-11-15 09:16:07
您的regex意味着您使用的是non-standard date time formats,这在Safari中是失败的。即使您更正了格式,仍然会出现这样的问题:Safari实现不带时区的解析时间是错误的(也就是说,不符合规范)。
new Date('2019-11-15 10:06'); // DO NOT USE: fails in Safari
因此,最好坚持使用stringToDate
函数来创建date对象。
发布于 2019-11-15 12:51:48
你已经回答了你的问题:
,我想知道如果我仅仅依靠内置的解析器为我做…,它是否会更有表现力,或者更可靠?
我知道根据浏览器…,数据解析器的行为不同。
因此,您已经知道使用内置解析器是不可靠的。
ECMA-262只支持两种格式,而当前至少有一种浏览器无法解析其中的一种,而旧的浏览器也会失败。所以你的选择是:
的大量其他现有和未来实现。
不是一个很难的选择。
https://stackoverflow.com/questions/58870954
复制相似问题