是否有任何破解v8日期解析器的解决方法? [英] is there any workaround for broken v8 date parser?

查看:142
本文介绍了是否有任何破解v8日期解析器的解决方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

V8日期解析器已损坏:

 >新日期('asd qw 101')
星期六01 01 101 00:00:00 GMT + 0100(CET)

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

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

但它太脆弱了。我不能依赖新日期



所以,好像v8打破了,它的工作方式不同。



希望有所帮助!


V8 Date parser is broken:

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

I can use fragile regular expression like this:

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

but it is too fragile. I cannot rely on new Date (issue in V8) and also moment cant help me because moment is getting rid off date detection (github issue-thread).

is there any workaround for broken v8 date parser?

To be clear. We have Gecko and V8, both have Date. V8 has broken Date, Gecko has working one. I need the Date from in Gecko (Firefox).

Update: It’s definitely broken parser https://code.google.com/p/v8/issues/detail?id=2602
nope, Status: WorkingAsIntended

解决方案

Date objects are based on a time value that is the number of milliseconds since 1 January, 1970 UTC and have the following constructors

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

From the docs,

dateString in new Date(dateString) is a string value representing a date. The string should be in a format recognized by the Date.parse() method (IETF-compliant RFC 2822 timestamps and also a version of ISO8601).

Now looking at the v8 sourcecode in date.js:

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;
        }
      }

    }
...

it looks like DateParse() does not return a NaN for for a string like 'asd qw 101' and hence the error. You can cross-check the same with Date.parse('asd qw 101') in both Chrome(v8) [which returns -58979943000000] and Gecko (Firefox) [which returns a NaN]. Sat Jan 01 101 00:00:00 comes when you seed new Date() with a timestamp of -58979943000000(in both browsers)

is there any workaround for broken v8 date parser?

I wouldnt say V8 date parser is broken. It just tries to satisfy a string against RFC 2822 standard in the best possible way but so does gecko and both break gives different results in certain cases.

Try new Date('Sun Ma 10 2015') in both Chrome(V8) and Firefox(Gecko) for another such anomaly. Here chrome cannot decide weather 'Ma' stands for 'March' or 'May' and gives an Invalid Date while Firefox doesnt.

Workaround:

You can create your own wrapper around Date() to filter those strings that V8's own parser cannot. However, subclassing built-ins in ECMA-5 is not feasible. In ECMA-6, it will be possible to subclass built-in constructors (Array, Date, and Error) - reference

However you can use a more robust regular expression to validate strings against RFC 2822/ISO 8601

^(?:(?: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})$

Image generated from debuggex

So, seems like v8 aint broken, it just works differently.

Hope it helps!

这篇关于是否有任何破解v8日期解析器的解决方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆