简体   繁体   English

在Mozilla Firefox中使用moment.js时获取无效的日期

[英]Getting Invalid Day in Date when using moment.js in Mozilla Firefox

i'm currently using moment.js library to render dates in real time to my users, but after some tests today, i noticed something really weird, when listing all possible days to the user in Firefox, moment.js fails to add days in the date '2015-09-14'. 我目前正在使用moment.js库向用户实时呈现日期,但是在今天进行一些测试之后,我注意到了一件很奇怪的事情,当在Firefox中向用户列出所有可能的日期时,moment.js无法在日期“ 2015-09-14”。 After searching the developers documentation and the internet, i discovered that you have to pass a ISO8601 valid Date or construct by passing explicit information of the date, but the results continue to confuse me. 在搜索了开发人员文档和互联网之后,我发现您必须通过ISO8601有效日期或通过传递日期的显式信息进行构造,但是结果仍然使我感到困惑。

Here's some code for understanding: 以下是一些易于理解的代码:

Working case (creating a moment() instance from current time): 工作案例(从当前时间创建一个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>";

My Result: 我的结果:

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

Weird case #1 (creating a moment() using time with encoding 'YYYY-MM-DD'): 奇怪的情况#1(使用编码为'YYYY-MM-DD'的时间创建一个moment()):

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

My Result: 我的结果:

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

Weird case #2 (creating a moment() using explicit constructor like moment([2015, 8, 14])) return the same result: 奇怪的情况#2(使用像moment([2015,8,14])这样的显式构造函数创建moment()会返回相同的结果:

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

Firefox version: 40.0.3 Firefox版本:40.0.3

Thanks for all the Help! 感谢您提供的所有帮助!

You must be in Brazil! 你一定在巴西!

  • Brazil "springs-forward" for daylight saving time at midnight on October 18, 2015. That is, the clocks tick from 2015-10-17T23:59:59.999 to 2015-10-18T01:00:00.000 . 巴西将“ 夏令时向前”表示2015年10月18日午夜的夏时制 。也就是说,时钟从2015-10-17T23:59:59.9992015-10-18T01:00:00.000滴答2015-10-18T01:00:00.000 There is no midnight on this day in your time zone! 您所在时区的这一天没有午夜!

  • Moment still uses the Date object for certain operations internally. Moment仍在内部将Date对象用于某些操作。

  • The Date object is implemented differently on different browsers when it comes to DST transition edge cases, such as dealing with invalid or ambiguous values. 对于DST过渡边缘情况(例如,处理无效或模棱两可的值), Date对象在不同浏览器上的实现方式有所不同。

  • Firefox happens to shift backwards by an hour when you provide an invalid value. 当您提供无效值时,Firefox会向后移动一个小时。 Other browsers such as Chrome shift forwards (which is more sensible IMHO). Chrome之类的其他浏览器向前移动(这是更明智的恕我直言)。

Consider that with my time zone set for Brazil where DST occurs (Brasillia, Sao Paulo, etc.): 考虑将我的时区设置为发生DST的巴西(巴西利亚,圣保罗等):

In FireFox: 在FireFox中:

But in Chrome: 但是在Chrome中:

Notice that by shifting backwards instead of forwards, the dates for the middle two values are off by one. 请注意,通过向后而不是向前移动,中间两个值的日期偏移了一个。

To be clear, this is a browser issue - not a moment issue. 需要明确的是,这是浏览器问题-暂时不是问题。 Similar results can be obtained by just using the Date object. 仅使用Date对象就可以获得类似的结果。 Moment could detect this issue and compensate, but it currently does not. Moment 可以检测到此问题并进行补偿,但目前没有。

The workaround to get consistent behavior (with Date or with moment ) is to use noon when working with date-only values. 要获得一致的行为(使用Datemoment ),解决方法是在使用仅日期值时使用正午 DST transitions always occur at night, so noon is a safer value to use than midnight. DST转换总是在晚上进行,因此中午比午夜更安全。

Firefox: 火狐:

Chrome: 铬:

instead of 代替

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

just do 做就是了

printVar.add(1, 'days');

Example code: 示例代码:

 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM