【问题标题】:Getting Invalid Day in Date when using moment.js in Mozilla Firefox在 Mozilla Firefox 中使用 moment.js 时获取无效日期
【发布时间】:2015-09-14 21:06:08
【问题描述】:

我目前正在使用 moment.js 库向我的用户实时呈现日期,但今天经过一些测试后,我注意到一些非常奇怪的事情,当在 Firefox 中向用户列出所有可能的日期时,moment.js 无法在日期“2015-09-14”中添加天数。 在搜索开发人员文档和互联网后,我发现您必须传递 ISO8601 有效日期或通过传递日期的显式信息来构造,但结果仍然让我感到困惑。

这里有一些代码供大家理解:

工作案例(从当前时间创建一个 moment() 实例):

var printVar = moment();
var divInfo  = document.getElementById('calendars');
divInfo.innerHTML += "<ul>";

for(var i=0; i<40; i++){
    divInfo.innerHTML += "<li> " + printVar.format('DD/MM/YYYY') + " </li>";            
    printVar = moment(printVar).add(1, 'days');
}

divInfo.innerHTML += "</ul>";

我的结果:

  • 15/10/2015
  • 16/10/2015
  • 17/10/2015
  • 18/10/2015
  • 19/10/2015
  • 20/10/2015

奇怪的案例 #1(使用编码“YYYY-MM-DD”的时间创建一个时刻()):

var printVar = moment('2015-09-14');

var divInfo  = document.getElementById('calendars');
divInfo.innerHTML += "<ul>";

for(var i=0; i<40; i++){
    divInfo.innerHTML += "<li> " + printVar.format('DD/MM/YYYY') + " </li>";            
    printVar = moment(printVar).add(1, 'days');
}

divInfo.innerHTML += "</ul>";

我的结果:

  • 15/10/2015
  • 16/10/2015
  • 17/10/2015
  • 17/10/2015
  • 18/10/2015
  • 19/10/2015

奇怪的情况 #2(使用像 moment([2015, 8, 14]) 这样的显式构造函数创建一个 moment())返回相同的结果:

  • 15/10/2015
  • 16/10/2015
  • 17/10/2015
  • 17/10/2015
  • 18/10/2015
  • 19/10/2015

火狐版本:40.0.3

感谢大家的帮助!

【问题讨论】:

  • 有趣的bug,但你绝对应该在github上创建一个Issue..看起来真的很奇怪

标签: javascript momentjs


【解决方案1】:

你一定在巴西!

  • 2015 年 10 月 18 日午夜,daylight saving time 的巴西“快速前进”。也就是说,时钟从 2015-10-17T23:59:59.999 跳到 2015-10-18T01:00:00.000您所在时区的这一天没有午夜!

  • Moment 在内部仍然使用Date 对象进行某些操作。

  • Date 对象在涉及 DST 过渡边缘情况时在不同浏览器上的实现方式不同,例如处理无效或不明确的值。

  • 当您提供无效值时,Firefox 恰好将 向后 移动一个小时。其他浏览器,例如 Chrome shift forwards(恕我直言,这更明智)。

考虑一下我的时区设置为发生夏令时的巴西(巴西利亚、圣保罗等):

在火狐中:

但在 Chrome 中:

请注意,通过向后移动而不是向前移动,中间两个值的日期相差 1。

需要明确的是,这是一个浏览器问题,而不是一时的问题。仅使用Date 对象可以获得类似的结果。 Moment 可以检测到这个问题并进行补偿,但目前还没有。

获得一致行为的解决方法(使用Datemoment)是在使用仅日期值时使用noon。 DST 转换总是发生在晚上,因此使用中午比午夜更安全。

火狐:

铬:

【讨论】:

    【解决方案2】:

    而不是

    printVar = moment(printVar.format()).add(1, 'days');

    只是做

    printVar.add(1, 'days');

    示例代码:

    var printVar, divInfo, i;
    
    printVar = moment();
    divInfo  = document.getElementById('example-1');
    
    divInfo.innerHTML += "<ul>";
    for(i=0; i<10; i++){
        divInfo.innerHTML += "<li> " + printVar.format('DD/MM/YYYY') + " </li>";            
        printVar.add(1, 'days');
    }
    divInfo.innerHTML += "</ul>";
    
    
    printVar = moment('2015-9-10');
    divInfo  = document.getElementById('example-2');
    divInfo.innerHTML += "<ul>";
    for(i=0; i<10; i++){
        divInfo.innerHTML += "<li> " + printVar.format('DD/MM/YYYY') + " </li>";            
        printVar.add(1, 'days');
    }
    
    divInfo.innerHTML += "</ul>";
    
    
    printVar = moment([2015, 8, 14]);
    divInfo  = document.getElementById('example-3');
    divInfo.innerHTML += "<ul>";
    
    for(i=0; i<10; i++){
        divInfo.innerHTML += "<li> " + printVar.format('DD/MM/YYYY') + " </li>";            
        printVar.add(1, 'days');
    }
    
    divInfo.innerHTML += "</ul>";
    div {
      margin-top: 20px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/locale/af.js"></script>
    <div id="example-1"></div>
    <div id="example-2"></div>
    <div id="example-3"></div>

    【讨论】:

    • 已经做到了:/ 将格式传递给变量时,我得到一个更奇怪的结果,如下所示:15/10/2015、16/10/2015、17/10/2015、17 /10/2015, 17/10/2015, 17/10/2015.
    猜你喜欢
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 2015-02-04
    • 2017-04-04
    • 2017-01-22
    • 1970-01-01
    相关资源
    最近更新 更多