Javascript 如何检查 DST(夏令时)是否生效以及偏移量是多少?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11887934/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 07:33:45  来源:igfitidea点击:

How to check if the DST (Daylight Saving Time) is in effect and if it is what's the offset?

javascriptdst

提问by Jo Smo

This is a bit of my JS code for which this is needed:

这是我需要的一些 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);

I want to get the datetime in ago, but if the DST is in use then the dates are off by 1 hour. I don't know how to check if the DST is in use or not.

我想获取之前的日期时间,但是如果 DST 正在使用中,那么日期会延迟 1 小时。我不知道如何检查 DST 是否在使用中。

How can I know when the daylight saving starts and ends?

我如何知道夏令时的开始和结束时间?

回答by Sheldon Griffin

This code uses the fact that getTimezoneOffsetreturns a greatervalue during Standard Time versus Daylight Saving Time (DST). Thus it determines the expected output during Standard Time, and it compares whether the output of the given date the same (Standard) or less (DST).

此代码使用在标准时间与夏令时 (DST) 期间getTimezoneOffset返回更大值的事实。因此,它确定标准时间期间的预期输出,并比较给定日期的输出是否相同(标准)或更少(DST)。

Note that getTimezoneOffsetreturns positivenumbers of minutes for zones westof UTC, which are usually stated as negativehours (since they're "behind" UTC). For example, Los Angeles is UTC–8hStandard, UTC-7hDST. getTimezoneOffsetreturns 480(positive 480 minutes) in December (winter, Standard Time), rather than -480. It returns negativenumbers for the Eastern Hemisphere (such -600for Sydney in winter, despite this being "ahead" (UTC+10h).

请注意,getTimezoneOffset返回UTC以西区域的分钟数,通常表示为小时数(因为它们“落后于”UTC)。例如,洛杉矶是UTC-8h标准,UTC-7hDST。在 12 月(冬季,标准时间)返回(正 480 分钟),而不是. 它返回东半球的负数(例如冬季的悉尼,尽管这是“超前”(UTC+10h)。getTimezoneOffset480-480-600

Date.prototype.stdTimezoneOffset = function () {
    var jan = new Date(this.getFullYear(), 0, 1);
    var jul = new Date(this.getFullYear(), 6, 1);
    return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
}

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

var today = new Date();
if (today.isDstObserved()) { 
    alert ("Daylight saving time!");
}

回答by Jon Nylander

Create two dates: one in June, one in January. Compare their getTimezoneOffset() values.

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

  • if January offset > June offset, client is in northern hemisphere
  • if January offset < June offset, client is in southern hemisphere
  • if no difference, client timezone does not observe DST
  • 如果 1 月抵消 > 6 月抵消,则客户在北半球
  • 如果 1 月偏移 < 6 月偏移,则客户位于南半球
  • 如果没有区别,客户端时区不遵守夏令时

Now check getTimezoneOffset() of the current date.

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

  • if equal to June, northern hemisphere, then current timezone is DST (+1 hour)
  • if equal to January, southern hemisphere, then current timezone is DST (+1 hour)
  • 如果等于六月,北半球,则当前时区为 DST(+1 小时)
  • 如果等于一月,南半球,则当前时区为 DST(+1 小时)

回答by Toastrackenigma

This answer is quite similar to the accepted answer, but doesn't override the Dateprototype, and only uses one function call to check if Daylight Savings Time is in effect, rather than two.

这个答案与接受的答案非常相似,但没有覆盖Date原型,并且只使用一个函数调用来检查夏令时是否有效,而不是两个。



The idea is that, since no country observes DST that lasts for 7 months[1], in an area that observes DST the offset from UTC time in January will be different to the one in July.

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

While Daylight Savings Time moves clocks forwards, JavaScript always returns a greatervalue during Standard Time. Therefore, getting the minimum offset between January and July will get the timezone offset during DST.

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

We then check if the dates timezone is equal to that minimum value. If it is, then we are in DST; otherwise we are not.

然后我们检查日期时区是否等于该最小值。如果是,那么我们处于夏令时;否则我们不是。

The following function uses this algorithm. It takes a date object, d, and returns trueif daylight savings time is in effect for that date, and falseif it is not:

以下函数使用此算法。它接受一个日期对象,dtrue如果夏令时对该日期有效,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(); 
}

回答by Aaron Cole

I was faced with this same problem today but since our daylight saving starts and stops at differing times from the USA (at least from my understanding), I used a slightly different route..

我今天遇到了同样的问题,但由于我们的夏令时开始和停止的时间与美国不同(至少根据我的理解),我使用了略有不同的路线。

var arr = [];
for (var i = 0; i < 365; i++) {
 var d = new Date();
 d.setDate(i);
 newoffset = d.getTimezoneOffset();
 arr.push(newoffset);
}
DST = Math.min.apply(null, arr);
nonDST = Math.max.apply(null, arr);

Then you simply compare the current timezone offset with DST and nonDST to see which one matches.

然后您只需将当前时区偏移量与 DST 和非 DST 进行比较,看看哪一个匹配。

回答by epeleg

Based on Matt Johanson's comment on the solution provided by Sheldon Griffin I created the following code:

基于 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(); 
    };

It tries to get the best of all worlds taking into account all the comments and previously suggested answers and specifically it:

考虑到所有评论和先前建议的答案,它试图充分利用所有世界,特别是它:

1) Caches the result for per year stdTimezoneOffset so that you don't need to recalculate it when testing multiple dates in the same year.

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

2) It does not assume that DST (if it exists at all) is necessarily in July, and will work even if it will at some point and some place be any month. However Performance-wise it will work faster if indeed July (or near by months) are indeed DST.

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

3) Worse case it will compare the getTimezoneOffset of the first of each month. [and do that Once per tested year].

3) 更坏的情况是它会比较每个月第一天的 getTimezoneOffset。[并在每个测试年执行一次]。

The assumption it does still makes is that the if there is DST period is larger then a single month.

它仍然做出的假设是,如果有 DST 期间大于一个月。

If someone wants to remove that assumption he can change loop into something more like whats in the solutin provided by Aaron Cole - but I would still jump half a year ahead and break out of the loop when two different offsets are found]

如果有人想消除这个假设,他可以将循环更改为更像 Aaron Cole 提供的解决方案中的内容 - 但我仍然会提前半年跳出循环,当找到两个不同的偏移量时]

回答by Daniel F

The moment.jslibrary provides an .isDst()method on its time objects.

所述moment.js库提供一个.isDst()在其时间的对象的方法。

moment#isDST checks if the current moment is in daylight saving time.

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

回答by Alan Wells

The getTimezoneOffset()method in JavaScript, in a browser, returns the number of minutes offset from the 00:00 time zone. For example, America/New_York time zone in Daylight Savings (DST) returns the number 300. 300 minutes is 5 hours difference from zero. 300 minutes divided by 60 minutes is 5 hours. Every time zone is compared to the zero time zone, +00:00 / Etc/GMT / Greenwich time.

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

MDN Web Docs

MDN 网络文档

The next thing that you must know, is that the offset has the opposite sign of the actual time zone.

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

Information about time zones is maintained by the Internet Assigned Numbers Authority (iana)

有关时区的信息由 Internet Assigned Numbers Authority (iana) 维护

iana time zones

伊安娜时区

A nicely formatted table of Time Zones is supplied by joda.org

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

joda-time Time Zones

joda-time 时区

+00:00 or Etc/GMT is Greenwich time

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

All time zones are offset from +00:00 / "Etc/GMT" / Greenwich time

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

Daylight Savings Time is always an earlier time than the "regular" time in the summer. You set your clocks back in the fall season. ("Fall Back" slogan to remember what to do)

夏令时总是比夏季的“常规”时间早。您在秋季将时钟调回。(“Fall Back”口号记住该做什么)

So, America/New_York time in Daylight Savings (winter) is one hour before the regular time. So, for example, what was normally 5 p.m. in the afternoon in New York city in the summer, is now 4 p.m. America/New_York time in Daylight Savings. The name "America/New_York" time is a "Long Format" time zone name. The east coast of the U.S typically calls their time zone Eastern Standard Time (EST)

因此,夏令时(冬季)中的 America/New_York 时间比常规时间早一小时。因此,例如,夏季纽约市通常下午 5 点,现在是夏令时美国/纽约时间下午 4 点。名称“America/New_York”时间是“长格式”时区名称。美国东海岸通常称他们的时区为东部标准时间 (EST)

If you want to compare today's time zone offset to the time zone offset of some other date, you need to know that mathematical sign (+/- "Positive / Negative") of the time zone offset is the opposite of the time zone.

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

Look at the time zone table at joda.org and find the time zone for "America/New_York" It will have a negative sign in front of the Standard Offset.

查看 joda.org 上的时区表,找到“America/New_York”的时区,它会在 Standard Offset 前面有一个负号。

The earth rotates counter-clockwise on it's axis. A person watch the sunrise in Greenwich sees the sunrise 5 hours before someone in New York City will see the sunrise. And someone on the West Coast of the U.S. will see the sunrise after someone on the East Coast of the U.S. sees the sunrise.

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

There's a reason why you need to know all of this. So that you'll be able to logically determine whether some JavaScript code is getting the DST status correctly or not, without needing to test every time zone at different times of the year.

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

Imagine that it's November in New York City, and the clocks have been set back an hour. In the summer in New York City, the offset is 240 minutes or 4 hours.

想象一下,现在是纽约市的 11 月,时钟已经倒退了一个小时。在纽约市的夏季,偏移量为 240 分钟或 4 小时。

You can test this by creating a date that is in July and then getting the offset.

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

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

console.log('july_Timezone_OffSet: ' + july_Timezone_OffSet)

What will print to the browser's developer tools console log?

什么会打印到浏览器的开发者工具控制台日志?

Answer is: 240

答案是:240

So, now you can create a date in January and see what your browser returns for a time zone offset for the winter season.

因此,现在您可以在 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)

Answer is: 300

答案是:300

Obviously 300 is bigger than 240. So, what does this mean? Should you write code that tests for the winter offset being bigger than the summer offset? Or the summer offset less than the winter offset? If there is a difference between the summer and winter time zone offsets, then you can assume that DST is being used for this time zone. But that doesn't tell you if todayis using DST for the browsers time zone. So, you'll need to get the time zone offset for today.

显然 300 比 240 大。那么,这是什么意思呢?您是否应该编写测试冬季偏移量大于夏季偏移量的代码?或者夏季偏移量小于冬季偏移量?如果夏季和冬季时区偏移量之间存在差异,则您可以假设该时区使用的是 DST。但这并不能告诉您今天是否对浏览器时区使用 DST。因此,您需要获取今天的时区偏移量。

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

console.log('todaysTimeZone : ' + todaysTimeZone)

Answer is: ? - Depends on the time of year

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

If today's time zone offset and the summer time zone offset is the same, ANDthe summer and winter time zone offsets are different, then by logical deduction, today must be NOT be in DST.

如果今天的时区偏移量和夏令时区偏移量是相同的,夏季和冬季的时区偏移量是不同的,然后通过逻辑推演,今天必须不能在DST。

Can you omit comparing the summer and winter time zone offsets, (To know if DST is used for this time zone) and just compare today's time zone offset to the summer TZ offset, and always get the correct answer?

您是否可以省略比较夏季和冬季时区偏移量(要知道该时区是否使用 DST)而仅将今天的时区偏移量与夏季 TZ 偏移量进行比较,并始终得到正确的答案?

today's TZ Offset !== Summer TZ Offset

Well, is today in the winter or summer? If you knew that then you could apply the following logic:

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

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

But the problem is, that you don't know if today's date is in winter or summer. Every time zone can have it's own rules for when DST starts and stops. You'd need to keep track of every time zone's rules for every time zone in the world. So, if there is a better and easier way then you might as well do it the better and easier way.

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

What we are left with, is that you need to know if this time zone uses DST, and then compare today's time zone offset with the summer time zone offset. That will always give you a reliable answer.

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

The final logic is:

最后的逻辑是:

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

Function to determine if the time zone in the browser uses DST:

判断浏览器时区是否使用夏令时的函数:

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
}

回答by Santhosh S

Use Moment.js (https://momentjs.com/)

使用 Moment.js ( https://momentjs.com/)

moment().isDST();will give you if Day light savings is observed.

moment().isDST();如果观察到夏令时,会给你。

Also it has helper function to calculate relative time for you. You don't need to do manual calculations e.g moment("20200105", "YYYYMMDD").fromNow();

它还具有辅助功能来为您计算相对时间。您不需要进行手动计算,例如moment("20200105", "YYYYMMDD").fromNow();

回答by Hyman Giffin

Future-Proof Solution That Works In All Time Zones

适用于所有时区的面向未来的解决方案

  1. Let xbe the expected number of milliseconds into the year of interest without factoring in daylight savings.
  2. Let ybe the number of milliseconds since the Epochfrom the start of the year of the date of interest.
  3. Let zbe the number of milliseconds since the Epochof the full date and time of interest
  4. Let tbe the subtraction of both xand yfrom z: z - y - x. This yields the offset due to DST.
  5. If tis zero, then DST is not in effect. If tis not zero, then DST is in effect.
  1. x成为感兴趣年份的预期毫秒数,而不考虑夏令时。
  2. y是从感兴趣日期的年份开始的纪元以来的毫秒数。
  3. z是自感兴趣的完整日期和时间的纪元以来的毫秒数
  4. t是两者的减法xyfrom z: z - y - x。由于 DST,这会产生偏移。
  5. 如果t为零,则 DST 无效。如果t不为零,则 DST 有效。

(function(){"use strict";
function dstOffsetAtDate(dateInput) {
    var fullYear = dateInput.getFullYear()|0;
 // "Leap Years are any year that can be exactly divided by 4 (2012, 2016, etc)
  //   except if it can be exactly divided by 100, then it isn't (2100,2200,etc)
  //   except if it can be exactly divided by 400, then it is (2000, 2400)"
 // (https://www.mathsisfun.com/leap-years.html).
    var isLeapYear = ((fullYear & 3) | (fullYear/100 & 3)) === 0 ? 1 : 0;
 // (fullYear & 3) = (fullYear % 4), but faster
    //Alternative:var isLeapYear=(new Date(currentYear,1,29,12)).getDate()===29?1:0
    var fullMonth = dateInput.getMonth()|0;
    return (
        // 1. We know what the time since the Epoch really is
        (+dateInput) // same as the dateInput.getTime() method
        // 2. We know what the time since the Epoch at the start of the year is
        - (+new Date(fullYear, 0, 0)) // day defaults to 1 if not explicitly zeroed
        // 3. Now, subtract what we would expect the time to be if daylight savings
        //      did not exist. This yields the time-offset due to daylight savings.
        - ((
            ((
                // Calculate the day of the year in the Gregorian calendar
                // The code below works based upon the facts of signed right shifts
                //    ? (x) >> n: shifts n and fills in the n highest bits with 0s 
                //    ? (-x) >> n: shifts n and fills in the n highest bits with 1s
                // (This assumes that x is a positive integer)
                (31 & ((-fullMonth) >> 4)) + // January // (-11)>>4 = -1
                ((28 + isLeapYear) & ((1-fullMonth) >> 4)) + // February
                (31 & ((2-fullMonth) >> 4)) + // March
                (30 & ((3-fullMonth) >> 4)) + // April
                (31 & ((4-fullMonth) >> 4)) + // May
                (30 & ((5-fullMonth) >> 4)) + // June
                (31 & ((6-fullMonth) >> 4)) + // July
                (31 & ((7-fullMonth) >> 4)) + // August
                (30 & ((8-fullMonth) >> 4)) + // September
                (31 & ((9-fullMonth) >> 4)) + // October
                (30 & ((10-fullMonth) >> 4)) + // November
                // There are no months past December: the year rolls into the next.
                // Thus, fullMonth is 0-based, so it will never be 12 in Javascript
                
                (dateInput.getDate()|0) // get day of the month
    
            )&0xffff) * 24 * 60 // 24 hours in a day, 60 minutes in an hour
            + (dateInput.getHours()&0xff) * 60 // 60 minutes in an hour
            + (dateInput.getMinutes()&0xff)
        )|0) * 60 * 1000 // 60 seconds in a minute * 1000 milliseconds in a second
        - (dateInput.getSeconds()&0xff) * 1000 // 1000 milliseconds in a second
        - dateInput.getMilliseconds()
    );
}

// Demonstration:
var date = new Date(2100, 0, 1)
for (var i=0; i<12; i=i+1|0, date.setMonth(date.getMonth()+1|0))
    console.log(date.getMonth()+":\t"+dstOffsetAtDate(date)/60/60/1000+"h\t"+date);
date = new Date(1900, 0, 1);
for (var i=0; i<12; i=i+1|0, date.setMonth(date.getMonth()+1|0))
    console.log(date.getMonth()+":\t"+dstOffsetAtDate(date)/60/60/1000+"h\t"+date);

// Performance Benchmark:
console.time("Speed of processing 16384 dates");
for (var i=0,month=date.getMonth()|0; i<16384; i=i+1|0)
    date.setMonth(month=month+1+(dstOffsetAtDate(date)|0)|0);
console.timeEnd("Speed of processing 16384 dates");
})();

I believe that the above code snippet is superior to all other answers posted here for many reasons.

我相信上面的代码片段优于此处发布的所有其他答案,原因有很多。

  • This answer works in all time zones, even Antarctica/Casey.
  • Daylight savings is very much subject to change. It might be that 20 years from now, some country might have 3 DST periods instead of the normal 2. This code handles that case by returning the DST offset in milliseconds, not just whether DST is in effect or not in effect.
  • The size of the months of the year and the way that Leap Years work fits perfectly into keeping our time on track with the sun. Heck, it works so perfectly that all we ever do is just adjust mere seconds here and there. Our current system of leap years has been in effect since February 24th, 1582, and will likely stay in effect for the foreseeable future.
  • This code works in timezones that do not use DST.
  • This code works in historic times before when DST was implemented (such as the 1900s).
  • This code is maximally integer-optimized and should give you no problem if called in a tight loop. After running the code snippet above, scroll down to the bottom of the output to see the performance benchmark. My computer is able to process 16384 dates in ~97ms on Chrome.
  • 这个答案适用于所有时区,甚至南极洲/凯西
  • 夏令时很可能会发生变化。可能是 20 年后,某些国家/地区可能有 3 个 DST 周期而不是正常的 2 个。此代码通过以毫秒为单位返回 DST 偏移量来处理这种情况,而不仅仅是 DST 是否有效。
  • 一年中月份的大小和闰年的工作方式非常适合让我们的时间与太阳保持同步。哎呀,它工作得如此完美,以至于我们所做的只是在这里和那里调整几秒钟。我们当前的闰年系统自15822 月 24 日起生效,并且在可预见的未来可能会继续有效。
  • 此代码适用于不使用 DST 的时区。
  • 此代码适用于实施 DST 之前的历史时期(例如 1900 年代)。
  • 此代码最大程度地进行了整数优化,如果在紧密循环中调用,应该不会有问题。运行上面的代码片段后,向下滚动到输出的底部以查看性能基准。我的电脑在 Chrome 上可以在大约 97 毫秒内处理 16384 个日期。

However, if you are not preparing for over 2 DST periods, then the below code can be used to determine whether DST is in effect as a boolean.

但是,如果您没有准备超过 2 个 DST 周期,则可以使用以下代码来确定 DST 是否作为布尔值有效。

function isDaylightSavingsInEffect(dateInput) {
    // To satisfy the original question
    return dstOffsetAtDate(dateInput) !== 0;
}

回答by Nico Westerdale

I've found that using the Moment.jslibrary with some of the concepts described here (comparing Jan to June) works very well.

我发现使用Moment.js库和这里描述的一些概念(比较 Jan 到 June)效果很好。

This simple function will return whether the timezone that the user is in observes Daylight Saving Time:

这个简单的函数将返回用户所在的时区是否遵守夏令时:

function HasDST() {
    return moment([2017, 1, 1]).isDST() != moment([2017, 6, 1]).isDST();
}

A simple way to check that this works (on Windows) is to change your timezone to a non DST zone, for example Arizona will return false, whereas EST or PST will return true.

检查这是否有效(在 Windows 上)的一种简单方法是将您的时区更改为非 DST 区域,例如 Arizona 将返回 false,而 EST 或 PST 将返回 true。

enter image description here

在此处输入图片说明