【问题标题】:Using Moment to Validate Default Javascript Date Format使用 Moment 验证默认 Javascript 日期格式
【发布时间】:2018-05-12 14:00:36
【问题描述】:

我想使用 moment(或任何其他方法)根据默认 javascript 日期格式将特定字符串验证为有效日期值。

我有以下代码:

var date = new Date(); // Tue Nov 28 2017 17:54:41 GMT-0600 (CST)

我想获取该字符串输出并使用 moment 将其验证为有效的日期字符串。我知道我可以做到:

moment(date, moment.ISO_8601).isValid();

但是有一个问题。以下是相同日期值的结果:

moment(new Date(), moment.ISO_8601).isValid(); //True
moment("Tue Nov 28 2017 17:54:41 GMT-0600 (CST)", moment.ISO_8601).isValid() //False

这不是我想要的,因为它们都应该是真的。我不能这样做new Date(...),因为这是该方法的结果:

moment(new Date("Tue Nov 28 2017 17:54:41 GMT-0600 (CST)"), moment.ISO_8601).isValid(); //True
moment(new Date("3"), moment.ISO_8601).isValid(); //True

这也不是我想要的,因为第二行应该是假的。

如果字符串严格遵循Tue Nov 28 2017 17:54:41 GMT-0600 (CST) 格式,我如何才能正确地将其验证为有效日期?

我到处研究以了解Tue Nov 28 2017 17:54:41 GMT-0600 (CST) 是什么格式,但我找不到任何东西。它既不是 ISO 8601,也不是 RFC 2822。

【问题讨论】:

  • 是什么让你认为new Date() 产生了一个字符串?
  • @Sag1v 我并不是真的这么说,我只是说我有一个这种格式的字符串
  • 没有“默认的javascript日期格式”。 Date.prototype.toString 的输出依赖于实现,并且因浏览器和主机而异。但是,需要一个实现来正确解析由它自己的 toString 产生的输出(而不是其他的)。如果解析字符串的结果是无效日期,则需要toString方法返回字符串“无效日期”。

标签: javascript validation date momentjs


【解决方案1】:

如果您想使用 Moment.js 严格验证时间戳,请在解析时使用 strict 标志:

var s = 'Tue Nov 28 2017 17:54:41 GMT-0600';
s = s.replace('GMT','');
console.log('Modified string: ' + s);

var mStrict = moment(s, 'ddd MMM D YYYY HH:mm:ss ZZ', true);
console.log('Strict parse: ' + mStrict.format());

var mLoose  = moment(s, 'ddd MMM D YYYY HH:mm:ss ZZ');
console.log('Loose parse : ' + mLoose.format());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.2/moment.min.js"></script>

但是,对我来说,严格和宽松都会产生“无效日期”,这是不正确的(应该是“无效日期”)。问题似乎是时区值或令牌。

【讨论】:

    【解决方案2】:

    正如 RobG 在 cmets 中所说的那样 没有“默认的 javascript 日期格式”。 Date.prototype.toString 的输出依赖于实现

    由于您的输入既不是 ISO 8601 也不是 RFC 2822 日期时间格式,您必须使用 moment(String, String) 使用 'ddd MMM D YYYY HH:mm:ss [GMT]Z' 作为格式参数。如果您希望您的字符串与您的格式严格匹配,您可以使用strict mode (moment(String, String, Boolean))。

    请注意,moment 不提供解析时区缩写的令牌(例如CST),因此在严格模式下将无法识别您的输入。这是一个使用严格模式和宽恕模式进行解析的示例; myIsValid 函数是从输入中删除时区缩写的示例。

    var s = 'Tue Nov 28 2017 17:54:41 GMT-0600 (CST)';
    var fmt = 'ddd MMM D YYYY HH:mm:ss [GMT]Z';
    
    console.log(moment(s, fmt).isValid());
    console.log(moment(s, fmt, true).isValid());
    
    function myIsValid(input){
      // Check if input contains ()
      var idxl = input.indexOf('(');
      var idxr = input.indexOf(')');
      if( idxl>0 && idxr>0 ){
        // Remove timezone abbreviation
        input = input.substr(0, idxl-1);
      }
      var fmt = 'ddd MMM D YYYY HH:mm:ss [GMT]Z';
      return moment(input, fmt, true).isValid();
    }
    
    console.log(myIsValid(s));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

    moment 的最新版本 (2.19.2),即使在宽恕模式下也会给出无效日期。使用parsingFlags() 你会看到weekdayMismatchtrue,我认为这是moment 2.19+ 版本的问题 这与moment #4227 问题有关。

    var s = 'Tue Nov 28 2017 17:54:41 GMT-0600 (CST)';
    var fmt = 'ddd MMM D YYYY HH:mm:ss [GMT]Z';
    var m1 = moment(s, fmt);
    var m2 = moment(s, fmt, true);
    console.log(m1.isValid());
    console.log(m1.parsingFlags());
    console.log(m2.isValid());
    console.log(m2.parsingFlags());
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.2/moment.min.js"></script>

    【讨论】:

      猜你喜欢
      • 2019-10-29
      • 1970-01-01
      • 1970-01-01
      • 2018-11-25
      • 2021-02-06
      • 1970-01-01
      • 2018-02-12
      • 2015-07-22
      • 1970-01-01
      相关资源
      最近更新 更多