有没有任何解决方法破v8dateparsing器?

V8dateparsing器已损坏:

> new Date('asd qw 101') Sat Jan 01 101 00:00:00 GMT+0100 (CET) 

我可以像这样使用脆弱的正则expression式:

 \d{1,2} (jan|feb|mar|may|jun|jul|aug|sep|oct|nov|dec) \d{1,4} 

但它太脆弱了。 我不能依靠new Date (V8发行) ,也不能帮助我,因为时刻正在摆脱date检测(github问题线程) 。

有没有任何解决方法破v8dateparsing器?

要清楚。 我们有Gecko和V8,都有Date V8已经打破date,壁虎有工作之一。 我需要Gecko(Firefox)中的Date

更新:这绝对是破解器https://code.google.com/p/v8/issues/detail?id=2602
Status: WorkingAsIntendedStatus: WorkingAsIntended

Date对象基于时间值,该值是自1970年1月1日以来的毫秒数,具有以下构造函数

 new Date(); new Date(value); new Date(dateString); new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]); 

从文档中 ,

new Date(dateString)中的new Date(dateString)是表示date的string值。 该string应该采用Date.parse()方法( IETF兼容的RFC 2822时间戳以及ISO8601的一个版本 识别的格式。

现在看一下date.js中的v8源代码 :

 function DateConstructor(year, month, date, hours, minutes, seconds, ms) { if (!%_IsConstructCall()) { // ECMA 262 - 15.9.2 return (new $Date()).toString(); } // ECMA 262 - 15.9.3 var argc = %_ArgumentsLength(); var value; if (argc == 0) { value = %DateCurrentTime(); SET_UTC_DATE_VALUE(this, value); } else if (argc == 1) { if (IS_NUMBER(year)) { value = year; } else if (IS_STRING(year)) { // Probe the Date cache. If we already have a time value for the // given time, we re-use that instead of parsing the string again. var cache = Date_cache; if (cache.string === year) { value = cache.time; } else { value = DateParse(year); <- DOES NOT RETURN NaN if (!NUMBER_IS_NAN(value)) { cache.time = value; cache.string = year; } } } ... 

它看起来像DateParse()不返回一个string,如'asd qw 101' DateParse() 'asd qw 101' NaN,因此错误。 您可以在Chrome(v8) [返回-58979943000000 ]和Gecko(Firefox) [返回NaN]中与Date.parse('asd qw 101')进行交叉检查。 Sat Jan 01 101 00:00:00当您种子new Date()与时间戳-58979943000000(在这两个浏览器)

有没有任何解决方法破v8dateparsing器?

我不会说V8dateparsing器坏了。 它只是试图以最好的方式满足RFC 2822标准的一个string,但是壁虎也是如此,在某些情况下两个中断 都会给出不同的结果

在Chrome(V8)和Firefox(Gecko)中 尝试 new Date('Sun Ma 10 2015') )来处理另一个exception情况。 这里铬不能决定天气“马”代表“三月”或“五月”,并给出了一个无效的date,而Firefox不。

解决方法:

你可以在Date()创build你自己的包装来过滤那些V8自己的parsing器不能的string。 但是,对ECMA-5中的内置子进行子类化并不可行。 在ECMA-6中,可以对内置的构造函数(Array,Date和Error)进行子类化 – 引用

但是,您可以使用更强大的正则expression式来validation对RFC 2822 / ISO 8601的string

 ^(?:(?:31(\/|-|\. |\s)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:29|30)(\/|-|\.|\s)(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.|\s)(?:0?2|(?:Feb))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.|\s)(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$ 

图片正则表达式 从debuggex生成的图像

所以,似乎v8没有坏,它只是工作不同。

希望能帮助到你!

您似乎正在寻求一种方法来parsing可能以任何特定格式的string,并确定要表示哪些数据。 总的来说,这是一个糟糕的主意,有很多原因。

你说moment.js是“摆脱date检测”,但实际上它从来没有这个function摆在首位。 人们只是假设它可以做到这一点,在某些情况下它是有效的,而且在许多情况下它没有。

这里是一个例子来说明这个问题。

  var s = "01.02.03"; 

那是约会吗 也许。 也许不会。 这可能是一个文档中的标题。 即使我们说这是一个约会,约会是几号? 它可以被解释为以下任何一种:

  • 2003年1月2日
  • 0003年1月2日
  • 二○○三年二月一日
  • 0003年2月1日
  • 2001年2月3日
  • 0001年2月3日

消除歧义的唯一方法是了解当前的文化date设置。 Javascript的Date对象就是这样做的 – 这意味着你将得到一个不同的值,这取决于代码运行的机器的设置。 但是,moment.js是关于所有环境的稳定性。 文化背景是通过当下自己的语言环境function而明确的。 依靠浏览器的文化设置导致解释错误。

最好的办法是明确你正在使用的格式。 不要允许随机垃圾input。 期待你的input格式,并使用正则expression式提前validation格式,而不是试图构build一个Date ,看看事实之后是否有效。

如果你不能这样做,你将不得不寻找额外的上下文来帮助决定。 例如,如果您从后端进程中获取networking中的一些随机位,并且想要从文本中提取date,则必须具有关于每个特定网页的语言和语言环境的一些知识。 你可以猜到,但你可能会错过相当长的时间。

另见: 垃圾进入,垃​​圾出来

ES5 15.9.4.2 Date.parse: /…/如果string不符合该格式,该函数可能会回退到任何特定于实现的启发式或实现特定的date格式。 无法识别string或date包含格式string中的非法元素值应导致Date.parse返回NaN。

所以没关系,根据以上引用v8dateparsing器的结果:

  1. new Date('asd qw 101') :星期六01 01 101 00:00:00 GMT + 0100(CET)
  2. new Date('asd qw') :无效date