简体   繁体   English

Javascript日期:处理夏令时的最佳方法是什么?

[英]Javascript dates: what is the best way to deal with Daylight Savings Time?

In a previous question I wrote about a javascript date function that was mysteriously stopping on 11/07/101. 在之前的一个问题中,我写了一篇关于javascript日期函数的信息,这个函数在11/07/101神秘地停止了。 Thanks to the stackoverflow users I was told my problem is Daylight Savings Time. 感谢stackoverflow用户,我被告知我的问题是夏令时。 Javascript date, is this my error or did I find a bug? Javascript日期,这是我的错误还是我发现了一个错误?

So my last question on this is what is the recommended approach in Javascript to deal with Daylight Savings Time? 所以我对此的最后一个问题是Javascript中推荐的处理夏令时的方法是什么?

Is http://code.google.com/p/datejs/ the best approach to solve this? http://code.google.com/p/datejs/是解决此问题的最佳方法吗?

The best way is not to deal with DST. 最好的方法是不要处理夏令时。 Use the UTC methods and you won't have to worry about crossing a DST boundary, or any other timezone discontinuity (locale timezone rules can change for more reasons than just DST). 使用UTC方法,您不必担心跨越DST边界或任何其他时区不连续(区域设置时区规则可能因为更多原因而不仅仅是DST而更改)。

var timestamp= Date.UTC(2010, 10-1, 31, 0, 0, 0); // zero-based month: 9->october
var nextday= new Date(timestamp+86400000); // add one day
var ymd= [
    nextday.getUTCFullYear(),
    nextday.getUTCMonth()+1, // zero-based month
    nextday.getUTCDate()
].join('-');
alert(ymd); // 2010-11-1

If the above had been done with new Date(2010, ...) and getDate() etc, it'd return 2010-10-31 , the day add failing due to the DST change (in my region, anyway). 如果上面已经完成了new Date(2010, ...)getDate()等,它将返回2010-10-31 ,由于DST更改(在我所在的地区,无论如何),添加失败的那一天。

It is a pity that the 'default' most-obvious methods in Date are about local time, especially since JavaScript provides so very little context to scripts on what 'local time' actually is. 遗憾的是, Date中“默认”最明显的方法是关于本地时间的,特别是因为JavaScript在“本地时间”实际上为脚本提供了非常少的上下文。 UTC is a more stable proposition. UTC是一个更稳定的主张。

Use Date.setHours(hour,min,sec,millisec) to set the hour default to noon: Date.setHours(11); 使用Date.setHours(hour,min,sec,millisec)将小时默认设置为中午: Date.setHours(11); ( view reference ) 查看参考

24 hours after noon on a day is guaranteed to be the next day, though on daylight savings time days it will be one hour off (which doesn't change the result in your script at all). 一天中午24小时后保证是第二天,但在夏令时,它将减少一小时(这根本不会改变你的剧本中的结果)。

I was in a situation where I needed the date in the local time zone, i was doing a lot of adding and subtracting days via time stamps, some time later DST gave me issues, I made a function to add days to a time stamp and check if the time zone changed cause of DST 我在当地时区需要约会的情况下,我通过时间戳做了很多添加和减去日期,一段时间后DST给了我问题,我做了一个函数来添加时间戳和检查时区是否改变了夏令时的原因
Heres is my scratchpad test: 继承人是我的暂存测试:

function timeToHuman(stamp) {
    var monthNames = ["January", "February", "March", "April", "May", "June",
            "July", "August", "September", "October", "November", "December"],
        date = new Date(stamp*1000),
        month = monthNames[date.getMonth()],
        day = date.getDate(),
        year = date.getFullYear(),
        hour = date.getHours(),
        min = date.getMinutes(),
        amp;
    if(hour>11){
        hour -= 12;
        amp = "PM";
    }
    else
        amp="AM";
    hour = hour==0?12:hour;
    min = min<10?"0"+min:min;
    return month + " " + day + ", " + year + " @ " +  hour + ":" + min + " " + amp +// Month/Day /Year
        " || "+year+"/"+(date.getMonth()+1)+"/"+day+ " @ " +  date.getHours() + ":" + min;// Year/Month/Day
}
function addDays(stamp,days){//stamp = new Date().getTime()/1000
    var sec=days*86400,
        B4=new Date(stamp*1000).getTimezoneOffset(),
        A=new Date((stamp+sec)*1000).getTimezoneOffset();
    if(B4!=A){// DST correction
        A=(A-B4)*60;
        console.log('DST adjust by:',A,'seconds');
        sec+=A;
    }
    return stamp+sec;
}
var sample=[
         Math.floor(new Date('Sun Mar 10 2018 11:38:59 GMT-0500 (EDT)').getTime()/1000),// day before DST change
         Math.floor(new Date('Sun Mar 11 2018 11:38:59 GMT-0400 (EDT)').getTime()/1000),// day after DST change
         Math.floor(new Date('Sun Nov 3 2018 11:38:59 GMT-0400 (EDT)').getTime()/1000),// day before DST change
         Math.floor(new Date('Sun Nov 4 2018 11:38:59 GMT-0500 (EDT)').getTime()/1000)// day after DST change
      ]
    date=[];
for(i in sample){
    i=parseInt(i,10);
  date.push('Without DST Detection, Part '+(i+1));
  date.push('\t'+timeToHuman(sample[i]+2*86400));
  date.push('\t'+timeToHuman(sample[i]+1*86400));
  date.push('\t'+timeToHuman(sample[i]));
  date.push('\t'+timeToHuman(sample[i]+-1*86400));
  date.push('\t'+timeToHuman(sample[i]+-2*86400));
  date.push('\t'+timeToHuman(sample[i]+-3*86400));
  date.push('With DST Detection, Part '+(i+1));
  date.push('\t'+timeToHuman(addDays(sample[i],2)));
  date.push('\t'+timeToHuman(addDays(sample[i],1)));
  date.push('\t'+timeToHuman(sample[i]));
  date.push('\t'+timeToHuman(addDays(sample[i],-1)));
  date.push('\t'+timeToHuman(addDays(sample[i],-2)));
  date.push('\t'+timeToHuman(addDays(sample[i],-3)));
}
date.join('\n');

/*
Without DST Detection, Part 1
    March 12, 2018 @ 12:38 PM || 2018/3/12 @ 12:38
    March 11, 2018 @ 12:38 PM || 2018/3/11 @ 12:38
    March 10, 2018 @ 11:38 AM || 2018/3/10 @ 11:38
    March 9, 2018 @ 11:38 AM || 2018/3/9 @ 11:38
    March 8, 2018 @ 11:38 AM || 2018/3/8 @ 11:38
    March 7, 2018 @ 11:38 AM || 2018/3/7 @ 11:38
With DST Detection, Part 1
    March 12, 2018 @ 11:38 AM || 2018/3/12 @ 11:38
    March 11, 2018 @ 11:38 AM || 2018/3/11 @ 11:38
    March 10, 2018 @ 11:38 AM || 2018/3/10 @ 11:38
    March 9, 2018 @ 11:38 AM || 2018/3/9 @ 11:38
    March 8, 2018 @ 11:38 AM || 2018/3/8 @ 11:38
    March 7, 2018 @ 11:38 AM || 2018/3/7 @ 11:38
Without DST Detection, Part 2
    March 13, 2018 @ 11:38 AM || 2018/3/13 @ 11:38
    March 12, 2018 @ 11:38 AM || 2018/3/12 @ 11:38
    March 11, 2018 @ 11:38 AM || 2018/3/11 @ 11:38
    March 10, 2018 @ 10:38 AM || 2018/3/10 @ 10:38
    March 9, 2018 @ 10:38 AM || 2018/3/9 @ 10:38
    March 8, 2018 @ 10:38 AM || 2018/3/8 @ 10:38
With DST Detection, Part 2
    March 13, 2018 @ 11:38 AM || 2018/3/13 @ 11:38
    March 12, 2018 @ 11:38 AM || 2018/3/12 @ 11:38
    March 11, 2018 @ 11:38 AM || 2018/3/11 @ 11:38
    March 10, 2018 @ 11:38 AM || 2018/3/10 @ 11:38
    March 9, 2018 @ 11:38 AM || 2018/3/9 @ 11:38
    March 8, 2018 @ 11:38 AM || 2018/3/8 @ 11:38
Without DST Detection, Part 3
    November 5, 2018 @ 10:38 AM || 2018/11/5 @ 10:38
    November 4, 2018 @ 10:38 AM || 2018/11/4 @ 10:38
    November 3, 2018 @ 11:38 AM || 2018/11/3 @ 11:38
    November 2, 2018 @ 11:38 AM || 2018/11/2 @ 11:38
    November 1, 2018 @ 11:38 AM || 2018/11/1 @ 11:38
    October 31, 2018 @ 11:38 AM || 2018/10/31 @ 11:38
With DST Detection, Part 3
    November 5, 2018 @ 11:38 AM || 2018/11/5 @ 11:38
    November 4, 2018 @ 11:38 AM || 2018/11/4 @ 11:38
    November 3, 2018 @ 11:38 AM || 2018/11/3 @ 11:38
    November 2, 2018 @ 11:38 AM || 2018/11/2 @ 11:38
    November 1, 2018 @ 11:38 AM || 2018/11/1 @ 11:38
    October 31, 2018 @ 11:38 AM || 2018/10/31 @ 11:38
Without DST Detection, Part 4
    November 6, 2018 @ 11:38 AM || 2018/11/6 @ 11:38
    November 5, 2018 @ 11:38 AM || 2018/11/5 @ 11:38
    November 4, 2018 @ 11:38 AM || 2018/11/4 @ 11:38
    November 3, 2018 @ 12:38 PM || 2018/11/3 @ 12:38
    November 2, 2018 @ 12:38 PM || 2018/11/2 @ 12:38
    November 1, 2018 @ 12:38 PM || 2018/11/1 @ 12:38
With DST Detection, Part 4
    November 6, 2018 @ 11:38 AM || 2018/11/6 @ 11:38
    November 5, 2018 @ 11:38 AM || 2018/11/5 @ 11:38
    November 4, 2018 @ 11:38 AM || 2018/11/4 @ 11:38
    November 3, 2018 @ 11:38 AM || 2018/11/3 @ 11:38
    November 2, 2018 @ 11:38 AM || 2018/11/2 @ 11:38
    November 1, 2018 @ 11:38 AM || 2018/11/1 @ 11:38
*/

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

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