javascript-如何使用moment.js(或替代库)解析日期以选择2月31日或6月31日e.t.c.无效?

时间:2015-08-29 12:30:53

标签: javascript datetime momentjs

如何使用moment.js(或替代库)解析日期以选择2月31日或6月31日e,t,c为无效?

我知道如果我做了

moment("20-02-2000");

它说

Moment {_isAMomentObject: true, _i: "20-02-2000", 
_isUTC: false, _locale: Locale, _d: Invalid Date}

因此,它可以检测到无效的日期,这很好

虽然我正在使用yyyy-mm-dd

我似乎无法解析日期

moment("2000-02-31");
Moment {_isAMomentObject: true, _i: "2000-02-31", 
_f: "YYYY-MM-DD", _isUTC: false, _pf: Object…}

^^没有关于那里的无效日期

moment("2000-02-40");
Moment {_isAMomentObject: true, _i: "2000-02-40", 
_f: "YYYY-MM-DD", _isUTC: false, _pf: Object…}

^^没有关于那里的无效日期

moment("2000-40-01");
Moment {_isAMomentObject: true, _i: "2000-40-01", 
_f: "YYYY-MM-DD", _isUTC: false, _pf: Object…}

^^没有关于那里的无效日期

加入

var v=moment("2000-02-31");

v.toDate()
Thu Mar 02 2000 00:00:00 GMT+0000 (GMT Standard Time)

^^我看到如果我给出一个无效的日期,比如31st feb,它会使它正常化,但我希望它只是说无效。

我正在寻找一个我给它的功能" 2000-31-02"它说无效日期。

我见过moment.js建议作为javascript的Date构造函数的替代品。我查看了moment.js,因为javascript的Date构造函数也解析了2月31日而没有说无效的javascript Date.parse assumes 31 days in February and all months?。所以我希望那一刻.js能够做到。如果可以,那怎么样?如果没有,那么有没有替代moment.js呢?

我正在寻找一个我可以导入的库,而不是重新发明轮子。

4 个答案:

答案 0 :(得分:2)

您可以先使用moment().isValid()检查时刻是否认为日期有效。

console.log(moment('2015-02-31').isValid());
//false

http://jsfiddle.net/nicholasduffy/uv8aqykm/

http://momentjs.com/docs/#/parsing/string-format/

答案 1 :(得分:2)

Moment.js提供isValid方法来检查解析后的字符串是否有效。

moment("2000-02-28").isValid(); //true

moment("2000-02-31").isValid(); //false

moment("2000-02-40").isValid(); //false

这是您正在寻找的行为吗?

您可以在此处了解有关此方法的更多信息http://momentjs.com/docs/#/parsing/is-valid/

答案 2 :(得分:1)

有isValid方法,但你也应该指定格式,只需要..

e.g。 moment("2000-02-31", "YYYY-MM-DD").isValid()

有趣的是,在输入时刻点时,javascript控制台没有显示isValid()。或者moment.prototype。

文档说

  

Moment原型通过moment.fn

曝光

isValid确实显示了moment.fn。

它是正确的,包括几个世纪的闰年规则,如果它可以被4和400整除,那么一个世纪是闰年。

moment("2000-02-31", "YYYY-MM-DD").isValid()
false

moment("2000-02-28", "YYYY-MM-DD").isValid()
true    

moment("2100-02-28", "YYYY-MM-DD").isValid()
true

moment("2100-02-29", "YYYY-MM-DD").isValid()
false

moment("2000-02-29", "YYYY-MM-DD").isValid()
true

必须是资本Ds

moment("2000-02-40","YYYY-MM-dd").isValid()
true

moment("2000-02-40","YYYY-MM-DD").isValid()
false

你可能想用正则表达式检查它是yyyy-mm-dd还是mm-dd-yyyy等因为它仍然接受2000.9或斜线/任何分隔符

moment("2000/02/20","YYYY-MM-DD").isValid()
true
moment("2000/52/20","YYYY-MM-DD").isValid()
false
moment("2000.9","YYYY-MM-DD").isValid()
true

答案 3 :(得分:1)

建议的格式(YYYY-DD-MM)必须重新格式化为YYYY-MM-DD或Javascript Date构造函数将返回无效的日期错误。

如上所述,Date构造函数仍将接受2000-02-31并将其转换为2001-03-02。所以你必须对它进行预处理。

如果您已预处理字符串并具有Date构造函数有效格式,则可以使用以下代码转换为日期。下面的代码还为您提供了检查日期字符串是否有效以及年份是否为闰年的机会。

var dso = {
    convert:function(d) {
        // Converts the date in d to a date-object. The input can be:
        //   a date object: returned without modification
        //  an array      : Interpreted as [year,month,day].
        //   a number     : Interpreted as number of milliseconds
        //                  since 1 Jan 1970 (a timestamp)
        //   a string     : Any format supported by the javascript engine, like
        //                  "YYYY/MM/DD", "MM/DD/YYYY", "Jan 31 2009" etc.
        //  an object     : Interpreted as an object with year, month and date
        //                  attributes.
        return (
            d.constructor === Date ? d :
            d.constructor === Array ? new Date(d[0],d[1]-1,d[2]) :
            d.constructor === Number ? new Date(d) :
            d.constructor === String ? new Date(d) :
            typeof d === "object" ? new Date(d.year,d.month-1,d.date) :
            NaN
        );
    },
    isvalid(d,f) {
      // optional formats possible, see switch statement
      var m = [0,31,28,31,30,31,30,31,31,30,31,30,31], t,a;
      if (d.constructor == String) {
        d = d.replace("/","-").replace(".","-").replace(", ","-").replace(",","-").replace(" ","");
        t = d.split("-"), t[0] = parseInt(t[0]), t[1] = parseInt(t[1]), t[2] = parseInt(t[2]);
        switch(f) {
          case "yyyy-dd-mm":
            a = (dso.leapyear(t[0])?1:0);
            if (t[2] > 12 || t[2] < 1) return false;
            if (t[1] < 1 || (t[1] + a) > m[parseInt(t[2])]) return false;
            break;
          case "dd-mm-yyyy":
            a = (dso.leapyear(t[2])?1:0);
            if (t[1] > 12 || t[1] < 1) return false;
            if (t[0] < 1 || (t[0] + a) > m[parseInt(t[1])]) return false;
            break;
          case "mm-dd-yyyy":
            a = (dso.leapyear(t[2])?1:0);
            if (t[0] > 12 || t[0] < 1) return false;
            if (t[1] < 1 || (t[1] + a) > m[parseInt(t[0])]) return false;
            break;
          case "mm-yyyy-dd":
            a = (dso.leapyear(t[1])?1:0);
            if (t[0] > 12 || t[0] < 1) return false;
            if (t[2] < 1 || (t[2] + a) > m[parseInt(t[0])]) return false;
            break;
          case "yyyy-mm-dd":
          default:
            a = (dso.leapyear(t[0])?1:0);
            if (t[1] > 12 || t[1] < 1) return false;
            if (t[2] < 1 || (t[2] + a) > m[parseInt(t[1])]) return false;
            break;
        }
        return true;
      }
    },
    leapyear: function(year) {
      if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0 || year == 4905 || year == 8228) return true;
      return false;
    }
}