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

这是我需要这个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); 

我想在之前得到date时间,但如果DST正在使用,那么date是closures的1个小时。 我不知道如何检查DST是否在使用中。

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

过时链接给出的代码将告诉你夏令时是否生效。 它使用getTimezoneOffset在DST和标准时间期间返回不同值的事实,并比较两者之间的差异。 (例如纽约在DST期间正常返回-5和-4)

请注意,我不知道国际时区的错综复杂情况,只testing过它会为我的时区返回正确的结果。但代码似乎很稳固。

 var today = new Date(); if (today.dst()) { alert ("Daylight savings time!"); } 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.dst = function() { return this.getTimezoneOffset() < this.stdTimezoneOffset(); } 

创build两个date:一个在六月,一个在一月。 比较它们的getTimezoneOffset()值。

  • 如果1月份抵消> 6月份抵消,客户位于北半球
  • 如果一月份抵消<六月抵消,客户位于南半球
  • 如果没有区别,客户端时区不会观察到DST

现在检查当前date的getTimezoneOffset()。

  • 如果等于六月,北半球,那么当前的时区是DST(+1小时)
  • 如果等于1月份南半球,那么当前的时区是DST(+1小时)

今天我也遇到了同样的问题,但是由于我们的夏令时在美国的不同时间开始和停止(至less从我的理解),我用了一个稍微不同的路线。

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

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

根据Matt Johanson对Sheldon Griffin提供的解决scheme的评论,我创build了以下代码:

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

它试图通过考虑所有的评论和先前build议的答案来获得最好的结果,特别是:

1)每年stdTimezoneOffsetcaching结果,以便在同一年testing多个date时不需要重新计算结果。

2)不假定DST(如果它存在的话)必然是在7月份,即使在某个时间点,某个地方是任何月份,也将工作。 然而,从性能angular度来看,如果确实是7月(或接近几个月)确实是夏令时,那么速度会更快。

3)更糟的情况是它会比较每个月的第一个getTimezoneOffset。 [每个testing年度都要做一次]。

这个假设仍然存在,那就是如果DST时期大于一个月的话。

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

已经解决了,但只是认为我应该添加我做的方式(以防人们感兴趣)。

  function isDST(t) { //t is the date object to check, returns true if daylight saving time is in effect. var jan = new Date(t.getFullYear(),0,1); var jul = new Date(t.getFullYear(),6,1); return Math.min(jan.getTimezoneOffset(),jul.getTimezoneOffset()) == t.getTimezoneOffset(); } 

与例外答案(janurary和july时区偏移)一样工作,然后返回条件。

你好,但有一点closures。 你永远不需要计算自己的时间,因为这是你自己的时钟的结果。 它可以检测您是否在您的位置使用夏令时,但不能检测由偏移产生的远程位置:

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

如果他们在夏令时,这将仍然是错误的,并且closures一个小时。 您需要一个远程时间帐户,如果他们目前在他们的DST内,并相应地进行调整。 尝试计算这个,并改变你的时钟 – 让说2015年2月1日,并重置时钟回到一个小时,如果外面的DST。 然后计算一个应该还有2个小时的地方的偏移量。 它将在两小时之前显示一小时。 你仍然需要考虑小时和调整。 我是为了纽约和丹佛而做的,而且总是在丹佛进行不正确的(小时前的)。

我最近需要创build一个UTC和DST的datestring,根据谢尔登的回答,我把它放在一起:

 Date.prototype.getTimezone = function(showDST) { var jan = new Date(this.getFullYear(), 0, 1); var jul = new Date(this.getFullYear(), 6, 1); var utcOffset = new Date().getTimezoneOffset() / 60 * -1; var dstOffset = (jan.getTimezoneOffset() - jul.getTimezoneOffset()) / 60; var utc = "UTC" + utcOffset.getSign() + (utcOffset * 100).preFixed(1000); var dst = "DST" + dstOffset.getSign() + (dstOffset * 100).preFixed(1000); if (showDST) { return utc + " (" + dst + ")"; } return utc; } Number.prototype.preFixed = function (preCeiling) { var num = parseInt(this, 10); if (preCeiling && num < preCeiling) { num = Math.abs(num); var numLength = num.toString().length; var preCeilingLength = preCeiling.toString().length; var preOffset = preCeilingLength - numLength; for (var i = 0; i < preOffset; i++) { num = "0" + num; } } return num; } Number.prototype.getSign = function () { var num = parseInt(this, 10); var sign = "+"; if (num < 0) { sign = "-"; } return sign; } document.body.innerHTML += new Date().getTimezone() + "<br>"; document.body.innerHTML += new Date().getTimezone(true); 
 <p>Output for Turkey (UTC+0200) and currently in DST: &nbsp; UTC+0300 (DST+0100)</p> <hr> 

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

时刻#isDST检查当前时刻是否在夏令时。

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

我发现使用Moment.js库和这里描述的一些概念(比较1月到6月)是非常好的。

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

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

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

在这里输入图像描述

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

MDN网页文件

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

有关时区的信息由互联网号码分配机构(iana)

iana时区

时区的格式很好的表由joda.org提供

约达时间时区

+00:00或者其他格林尼治时间

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

夏令时总是比夏天的“正常”时间早。 你在秋季设置你的时钟。 (“回头”的口号要记住要做什么)

所以,夏令时(冬季)的America / New_York时间比正常时间早一个小时。 那么,例如,夏天下午五点在纽约市下午通常是现在的下午四点在美国/纽约时间夏令时。 名称“America / New_York”时间是“长格式”时区名称。 美国东海岸典型地称他们的时区东部标准时间(东部标准时间)

如果要比较今天的时区偏移和其他date的时区偏移,则需要知道时区偏移的math符号(+/-“正/负”)与时区相反。

查看joda.org上的时区表,find“America / New_York”的时区,它将在标准偏移量前面出现负号。

地球在它的轴上逆时针旋转。 一个人在格林威治观看日出,在纽约市有人看到日出前5个小时就能看到日出。 在美国东海岸的人看到日出之后,美国西海岸的人们将会看到日出。

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

想象一下,这是十一月在纽约市,时钟已经被设置了一个小时。 在纽约市的夏天,抵消是240分钟或4小时。

你可以通过创build一个7月份的date然后得到偏移量来testing。

 var July_Date = new Date(2017, 6, 1); var july_Timezone_OffSet = July_Date.getTimezoneOffset(); console.log('july_Timezone_OffSet: ' + july_Timezone_OffSet) 

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

答案是:240

因此,现在您可以在一月份创build一个date,并查看您的浏览器在冬季的时区偏移量。

 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.那么,这是什么意思? 您是否应该编写testing冬季偏移量大于夏季偏移量的代码? 还是夏天的偏移小于冬天的偏移? 如果夏季和冬季的时差存在差异,则可以假设夏时制正用于此时区。 但是,这并不能告诉你今天是否使用浏览器时区的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; } 

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

我们剩下的就是你需要知道这个时区是否使用DST,然后比较今天的时区偏移量和夏令时偏移量。 这将永远给你一个可靠的答案。

最终的逻辑是:

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

确定浏览器中的时区是否使用DST的function:

 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 }