cmx*_*mxl 9 javascript google-chrome date
我在Chrome浏览器中发现了一些奇怪的Date行为(版本74.0.3729.131(官方内部版本)(64位))。在Chrome开发者控制台中执行了以下javascript:
new Date('1894-01-01T00:00:00+01:00')
// result: Mon Jan 01 1894 00:00:00 GMT+0100 (Central European Standard Time)
new Date('1893-01-01T00:00:00+01:00')
// result: Sat Dec 31 1892 23:53:28 GMT+0053 (Central European Standard Time)
Run Code Online (Sandbox Code Playgroud)
尽管已经提供了有效的ISO8601值,但我已经在不同的浏览器中通过Date ctor阅读了有关非标准日期解析的信息。但这不仅仅是奇怪的o_o
在Firefox(Quantum 66.0.3(64位))中,相同的调用会导致预期的Date对象:
new Date('1894-01-01T00:00:00+01:00')
// result: > Date 1892-12-31T23:00:00.000Z
new Date('1893-01-01T00:00:00+01:00')
// result: > Date 1893-12-31T23:00:00.000Z
Run Code Online (Sandbox Code Playgroud)
好吧,似乎这种行为无法避免,所以你应该手动解析日期。但解析它的方法非常简单。
如果我们解析 ISO 8601 格式的日期,则日期字符串的掩码如下所示:
<yyyy>-<mm>-<dd>T<hh>:<mm>:<ss>(.<ms>)?(Z|(+|-)<hh>:<mm>)?
Run Code Online (Sandbox Code Playgroud)
inT字符串将日期与时间分开。所以,我们可以将 ISO 字符串分割为T
var isoString = `2019-05-09T13:26:10.979Z`
var [dateString, timeString] = isoString.split("T")
Run Code Online (Sandbox Code Playgroud)
所以,我们有dateString == "2019-05-09". 现在单独获取这些参数非常简单
var [year, month, date] = dateString.split("-").map(Number)
Run Code Online (Sandbox Code Playgroud)
由于时间字符串的可变性,我们应该做出更复杂的动作。
我们timeString == "13:26:10Z"
也有可能timeString == "13:26:10"并且timeString == "13:26:10+01:00
var clearTimeString = timeString.split(/[Z+-]/)[0]
var [hours, minutes, seconds] = clearTimeString.split(":").map(Number)
var offset = 0 // we will store offset in minutes, but in negation of native JS Date getTimezoneOffset
if (timeString.includes("Z")) {
// then clearTimeString references the UTC time
offset = new Date().getTimezoneOffset() * -1
} else {
var clearOffset = timeString.split(/[+-]/)[1]
if (clearOffset) {
// then we have offset tail
var negation = timeString.includes("+") ? 1 : -1 // detecting is offset positive or negative
var [offsetHours, offsetMinutes] = clearOffset.split(":").map(Number)
offset = (offsetMinutes + offsetHours * 60) * negation
} // otherwise we do nothing because there is no offset marker
}
Run Code Online (Sandbox Code Playgroud)
此时,我们有了数字格式的数据表示形式:
year、month、date、hours、minutes和seconds以offset分钟为单位。
是的,我们无法避免它,因为它太酷了。JSDate自动匹配所有负值和过大值的日期。因此,我们可以以原始格式传递所有参数,JSDate构造函数将自动为我们创建正确的日期!
new Date(year, month - 1, date, hours, minutes + offset, seconds)
Run Code Online (Sandbox Code Playgroud)
瞧!这是完整的工作示例。
<yyyy>-<mm>-<dd>T<hh>:<mm>:<ss>(.<ms>)?(Z|(+|-)<hh>:<mm>)?
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们得到的Date实例的所有值(如.getHours())都被标准化,包括时区偏移。仍然会testDate1.toISOString返回奇怪的结果。但如果您使用此日期,它可能 100% 符合您的需求。
希望有帮助:)
| 归档时间: |
|
| 查看次数: |
156 次 |
| 最近记录: |