这是我的一点JS代码,这是需要的:

var secDiff = Math.abs(Math.round((utc_date-this.premiere_date)/1000));
this.years = this.calculateUnit(secDiff,(86400*365));
this.days = this.calculateUnit(secDiff-(this.years*(86400*365)),86400);
this.hours = this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)),3600);
this.minutes = this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)-(this.hours*3600)),60);
this.seconds = this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)-(this.hours*3600)-(this.minutes*60)),1);

我想在“前”得到日期时间,但如果DST正在使用,那么日期是1小时。我不知道如何检查夏令时是否有效。

我怎样才能知道夏令时何时开始和结束?


当前回答

js库在它的time对象上提供了一个. isdst()方法。

moment#isDST检查当前时刻是否属于夏时制。

moment([2011, 2, 12]).isDST(); // false, March 12 2011 is not DST
moment([2011, 2, 14]).isDST(); // true, March 14 2011 is DST

其他回答

基于Matt Johanson对Sheldon Griffin提供的解决方案的评论,我创建了以下代码:

    Date.prototype.stdTimezoneOffset = function() {
        var fy=this.getFullYear();
        if (!Date.prototype.stdTimezoneOffset.cache.hasOwnProperty(fy)) {

            var maxOffset = new Date(fy, 0, 1).getTimezoneOffset();
            var monthsTestOrder=[6,7,5,8,4,9,3,10,2,11,1];

            for(var mi=0;mi<12;mi++) {
                var offset=new Date(fy, monthsTestOrder[mi], 1).getTimezoneOffset();
                if (offset!=maxOffset) { 
                    maxOffset=Math.max(maxOffset,offset);
                    break;
                }
            }
            Date.prototype.stdTimezoneOffset.cache[fy]=maxOffset;
        }
        return Date.prototype.stdTimezoneOffset.cache[fy];
    };

    Date.prototype.stdTimezoneOffset.cache={};

    Date.prototype.isDST = function() {
        return this.getTimezoneOffset() < this.stdTimezoneOffset(); 
    };

考虑到所有的评论和之前建议的答案,它试图得到所有世界的最好结果,特别是:

1)缓存每年stdTimezoneOffset的结果,这样当您在同一年测试多个日期时就不需要重新计算它。

2)它没有假设夏令时(如果它存在的话)一定是在7月, 即使在任何一个月的某个时间某个地点,它也会起作用。 但是性能方面,如果七月(或临近月份)确实是DST,它会工作得更快。

3)在更糟糕的情况下,它将比较每个月的第一个getTimezoneOffset。[并且每年测试一次]。

它所做的假设仍然是,如果有夏令时周期比一个月大。

如果有人想要消除这种假设,他可以把循环变成更像Aaron Cole提供的溶液中的东西-但我仍然会提前半年,当发现两个不同的偏移时跳出循环]

你很接近了,但是有点差。你永远不需要计算你自己的时间,因为它是你自己的时钟的结果。它可以检测您是否在您的位置使用日光节约时间,但不能检测由偏移量产生的远程位置:

newDateWithOffset = new Date(utc + (3600000*(offset)));

This will still be wrong and off an hour if they are in DST. You need for a remote time account if they are currently inside their DST or not and adjust accordingly. try calculating this and change your clock to - lets say 2/1/2015 and reset the clock back an hour as if outside DST. Then calculate for an offset for a place that should still be 2 hours behind. It will show an hour ahead of the two hour window. You would still need to account for the hour and adjust. I did it for NY and Denver and always go the incorrect (hour ahead) in Denver.

在浏览器中,JavaScript中的getTimezoneOffset()方法返回与00:00时区偏移的分钟数。例如,在夏令时(DST)中,America/New_York时区返回数字300。300分钟和0差5个小时。300分钟除以60分钟等于5小时。每个时区都与零时区、+00:00 / Etc/GMT /格林威治时间进行比较。

MDN Web文档

您必须知道的下一件事是,偏移量与实际时区的符号相反。

有关时区的信息由互联网编号分配机构(iana)维护。

Iana时区

joda.org提供了一个格式很好的时区表

时区

+00:00或Etc/GMT是格林威治时间

所有时区都偏移于+00:00 / "Etc/GMT" /格林威治时间

夏时制总是比夏天的“常规”时间早。你在秋天把时钟调慢了。(“后退”口号,记住该做什么)

因此,美国/纽约夏令时(冬季)比正常时间早一小时。举个例子,纽约市夏天的下午5点,现在是下午4点。美国/纽约夏令时。“America/New_York”时间名称是“Long Format”时区名称。美国东海岸通常称他们所在的时区为东部标准时间(EST)。

如果您想将今天的时区偏移量与其他日期的时区偏移量进行比较,您需要知道时区偏移量的数学符号(+/-“正/负”)与时区相反。

查看joda.org上的时区表,找到“America/New_York”的时区。在标准偏移前会有一个负号。

地球绕地轴逆时针旋转。在格林威治看日出的人比纽约市的人早5个小时看到日出。美国东海岸的人看到日出后,美国西海岸的人也会看到日出。

你知道这些是有原因的。这样您就可以从逻辑上确定某些JavaScript代码是否正确地获取了DST状态,而不需要在一年中的不同时间测试每个时区。

想象一下,现在是纽约的11月,时钟拨慢了一个小时。在纽约市的夏天,这段时间是240分钟或4个小时。

您可以通过创建一个7月的日期,然后获取偏移量来测试这一点。

var July_Date = new Date(2017, 6, 1);
var july_Timezone_OffSet = July_Date.getTimezoneOffset();

console.log('july_Timezone_OffSet: ' + july_Timezone_OffSet)

什么将打印到浏览器的开发人员工具控制台日志?

答案是:240

因此,现在您可以在1月份创建一个日期,并查看浏览器返回的冬季时区偏移值。

var Jan_Date = new Date(2017, 0, 1);//Month is zero indexed - Jan is zero
var jan_Timezone_OffSet = Jan_Date.getTimezoneOffset();

console.log('jan_Timezone_OffSet: ' + jan_Timezone_OffSet)

答案是:300

显然300比240大。那么,这意味着什么呢?是否应该编写测试冬季偏移量大于夏季偏移量的代码?还是夏季抵消量小于冬季抵消量?如果夏季和冬季时区偏移量存在差异,则可以假设该时区使用DST。但这并没有告诉您今天浏览器时区是否使用夏令时。所以,你需要得到今天的时区偏移。

var today = new Date();
var todaysTimeZone = today.getTimezoneOffset();

console.log('todaysTimeZone : ' + todaysTimeZone)

答案是:?-取决于一年中的时间

如果今天的时区偏移量和夏季时区偏移量是相同的,而夏季和冬季时区偏移量是不同的,那么根据逻辑推断,今天一定不是夏时制。

你能忽略比较夏季和冬季时区偏移量吗(要知道这个时区是否使用DST),只比较今天的时区偏移量和夏季TZ偏移量,并且总是得到正确的答案吗?

today's TZ Offset !== Summer TZ Offset

今天是冬天还是夏天?如果你知道这一点,那么你可以应用下面的逻辑:

if ( it_is_winter && ( todays_TZ_Offset !== summer_TZ_Offset) {
  var are_We_In_DST = true;
}

但问题是,你不知道今天是冬天还是夏天。每个时区都有自己的夏令时开始和停止的规则。您需要跟踪世界上每个时区的每个时区的规则。所以,如果有更好更简单的方法,你也可以用更好更简单的方法来做。

剩下的是,您需要知道这个时区是否使用夏令时,然后将今天的时区偏移量与夏季时区偏移量进行比较。这总能给你一个可靠的答案。

最后的逻辑是:

if ( DST_Is_Used_In_This_Time_Zone && ( todays_TZ_Offset !== summer_TZ_Offset) {
  var are_We_In_DST = true;
}

函数确定浏览器中的时区是否使用夏令时:

function is_DST_Used_In_This_TimeZone() {
  var Jan_Date, jan_Timezone_OffSet, July_Date, july_Timezone_OffSet 
      offsetsNotEqual, thisYear, today;

  today = new Date();//Create a date object that is now
  thisYear = today.getFullYear();//Get the year as a number

  Jan_Date = new Date(thisYear, 0, 1);//Month is zero indexed - Jan is zero
  jan_Timezone_OffSet = Jan_Date.getTimezoneOffset();

  console.log('jan_Timezone_OffSet: ' + jan_Timezone_OffSet)

  July_Date = new Date(thisYear, 6, 1);
  july_Timezone_OffSet = July_Date.getTimezoneOffset();

  console.log('july_Timezone_OffSet: ' + july_Timezone_OffSet)

  offsetsNotEqual = july_Timezone_OffSet !== jan_Timezone_OffSet;//True if not equal

  console.log('offsetsNotEqual: ' + offsetsNotEqual);

  return offsetsNotEqual;//If the offsets are not equal for summer and
       //winter then the only possible reason is that DST is used for
       //this time zone
}

这个答案与公认的答案非常相似,但没有覆盖Date原型,并且只使用一个函数调用来检查日光节约时间是否有效,而不是两个。


这个想法是,由于没有国家遵守持续7个月的夏时制[1],在遵守夏时制的地区,1月份与UTC时间的偏移量将与7月份的偏移量不同。

虽然夏令时将时钟向前移动,但JavaScript总是在标准时间期间返回更大的值。因此,在1月和7月之间获取最小偏移量将获得夏令时期间的时区偏移量。

然后检查dates timezone是否等于该最小值。如果是,那么我们就是在夏令时;否则我们就不是了。

下面的函数使用这个算法。它接受一个日期对象d,如果夏令时在该日期有效,则返回true,如果不是则返回false:

function isDST(d) {
    let jan = new Date(d.getFullYear(), 0, 1).getTimezoneOffset();
    let jul = new Date(d.getFullYear(), 6, 1).getTimezoneOffset();
    return Math.max(jan, jul) !== d.getTimezoneOffset();    
}

创建两个日期:一个在六月,一个在一月。比较它们的getTimezoneOffset()值。

如果一月抵消>六月抵消,客户端在北半球 如果1月偏移量< 6月偏移量,则客户在南半球 如果没有差异,则客户端时区不遵守夏令时

现在检查当前日期的getTimezoneOffset()。

如果等于北半球的6月,则当前时区为夏时制(+1小时) 如果等于南半球的1月,则当前时区为夏时制(+1小时)