186

这是我需要的一些 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 小时。我不知道如何检查 DST 是否生效。

我怎么知道夏令时开始和结束的时间?

4

15 回答 15

362

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

请注意,对于 UTC以西getTimezoneOffset的区域,返回数分钟数,通常表示为负数(因为它们“落后于”UTC)。例如,洛杉矶是UTC-8h Standard,UTC-7h DST。在 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!");
}
于 2012-08-09T17:04:50.903 回答
35

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


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

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

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

以下函数使用此算法。如果夏令时对该日期有效,则它需要一个日期对象,如果不是,则d返回:truefalse

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();    
}
于 2015-05-16T20:50:42.133 回答
28

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

  • 如果 1 月偏移量 > 6 月偏移量,则客户端位于北半球
  • 如果 1 月偏移量 < 6 月偏移量,则客户端在南半球
  • 如果没有差异,则客户端时区不遵守 DST

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

  • 如果等于北半球六月,则当前时区为 DST(+1 小时)
  • 如果等于 1 月,南半球,则当前时区为 DST(+1 小时)
于 2012-08-09T17:49:19.170 回答
14

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

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 进行比较,看看哪个匹配。

于 2012-11-13T17:33:19.180 回答
9

基于 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)它并不假设 DST(如果它存在的话)一定是在 7 月,即使它会在某个时间点和某个地方是任何月份,它也会起作用。但是,如果确实 7 月(或接近几个月)确实是 DST,那么在性能方面它会运行得更快。

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

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

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

于 2014-11-06T11:30:28.250 回答
9

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

MDN 网络文档

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

有关时区的信息由 Internet 号码分配机构 (iana) 维护

伊安娜时区

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

joda-time 时区

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

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

夏令时总是比夏季的“常规”时间更早。你把你的时钟拨回了秋季。(“后退”口号记住该做什么)

因此,夏令时(冬季)中的 America/New_York 时间比常规时间早一小时。因此,例如,夏季纽约市通常下午 5 点,现在是夏令时美国/纽约时间下午 4 点。名称“America/New_York”时间是“长格式”时区名称。美国东海岸通常将其时区称为东部标准时间 (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。但这并不能告诉您今天是否使用 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;
}

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

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
}
于 2017-11-07T23:29:10.523 回答
4

moment.js库为其时间对象提供了一个方法.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
于 2017-10-03T14:49:58.443 回答
4

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

  1. 让我们x在不考虑夏令时的情况下进入感兴趣的年份的预期毫秒数。
  2. 让我们成为从感兴趣日期开始的纪元y以来的毫秒数。
  3. 让我们成为自感兴趣的完整日期和时间的纪元z以来的毫秒数
  4. t是 和xy减法z: z - y - x。这会产生由于 DST 引起的偏移量。
  5. 如果t为零,则 DST 无效。如果t不为零,则 DST 有效。

"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)) // 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)
                -1 + // first day in the year is day 1
                (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");

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

  • 这个答案适用于所有时区,甚至是Antarctica/Cas​​ey
  • 夏令时非常容易发生变化。可能是从现在开始的 20 年后,某些国家/地区可能有 3 个 DST 周期,而不是正常的 2 个。此代码通过以毫秒为单位返回 DST 偏移量来处理这种情况,而不仅仅是 DST 是否有效。
  • 一年中月份的大小和闰年的工作方式非常适合让我们的时间与太阳保持同步。哎呀,它工作得如此完美,以至于我们所做的只是在这里和那里调整几秒钟。我们目前的闰年系统自1582 年 2 月 24 日起生效,并且在可预见的未来可能会继续有效。
  • 此代码适用于不使用 DST 的时区。
  • 此代码在实施 DST 之前的历史时期(例如 1900 年代)有效。
  • 这段代码最大程度地进行了整数优化,如果在紧密循环中调用,应该不会有任何问题。运行上面的代码片段后,向下滚动到输出的底部以查看性能基准。我的电脑能够在 FireFox 上在 29 毫秒内处理 16384 个日期。

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

function isDaylightSavingsInEffect(dateInput) {
    // To satisfy the original question
    return dstOffsetAtDate(dateInput) !== 0;
}
于 2019-06-03T14:14:00.057 回答
2

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

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

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

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

在此处输入图像描述

于 2017-11-03T20:10:33.283 回答
1

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

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

如果他们在 DST,这仍然是错误的并且会关闭一个小时。如果他们当前是否在 DST 内,您需要一个远程时间帐户并进行相应调整。尝试计算这个并将您的时钟更改为 - 比如说 2015 年 2 月 1 日,然后将时钟重新设置一个小时,就像在 DST 之外一样。然后计算一个仍应落后 2 小时的地方的偏移量。它将比两小时窗口提前一小时显示。您仍然需要考虑时间并进行调整。我为纽约和丹佛做了这件事,在丹佛总是走错(提前一小时)。

于 2015-03-20T11:54:04.997 回答
1

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

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

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

于 2020-01-06T09:46:29.740 回答
0

更新: 尝试在自定义datetime选择器中使用这些功能后,我注意到从 3 月切换到 4 月会按预期切换时区,因为我的区域在 3 月切换 DST。出乎意料的是,它切换到下一个时区,而不是在同一时区的标准和日光之间切换。

原来那是因为我的原始函数总是new Date()为当前时间或过去的任意固定时间创建。将其与 3 月和 4 月的相对时间进行比较意味着它会在逻辑上将 DST 切换检测为切换时区。

解决方案是将相对时间传递给效用函数,因此我所有的比较都是针对相对时间而不是现在或任意固定时间。失去了一些紧凑性,但现在逻辑可以根据需要工作。

工作流程更新:

  • t参数默认为new Date()
    • 对于固定时间,传入现有的Date
    • 对于当前时间,传入null或不传入
  • std()更新以用于t.setMonth(v);更改固定时间的月份
    • .getTimezoneOffset()不能链接到.setMonth(),因此我们需要从单行表示法转换为使用闭包 ( {})、终止符 ( ;) 和return
  • console.log()每个月的示例循环(011
    • 固定日期对象需要使用相同的时间戳 ( let ts = +t;)进行克隆
    • +beforeDate类型将其转换为带有numberUnix 时间戳的 a
    • Date()也接受 Unix 时间戳来创建固定时间
    • 如果我们不克隆它,每个调用都会传递同一个Date对象,并将月份设置为6,这违背了目的
    • 好的,我们实际上并没有克隆,只是使用相同的设置创建一个新对象;相同的区别;)

let ns = {
  std: (t = new Date()) => Math.max(...[0, 6].map(v => {
    t.setMonth(v);
    return t.getTimezoneOffset();
  })),
  is_dst: (t = new Date()) => t.getTimezoneOffset() < ns.std(t),
  utc: (t, std = 0) => {
    t = t || new Date();
    let z = std ? ns.std(t) : t.getTimezoneOffset(),
      zm = z % 60;
    return 'UTC' + (z > 0 ? '-' : '+') + (z / 60) + (zm ? ':' + zm : '');
  }
};

//current time only
console.log(ns.std(), ns.is_dst(), ns.utc(), ns.utc(null, 1));

//iterate each month
let t = new Date(2021,0,1);
for (let i = 0; i < 12; i++) {
  t.setMonth(i);
  let ts = +t;
  console.log(t.toDateString().split(" ")[1], ns.std(new Date(ts)), ns.is_dst(new Date(ts)), ns.utc(new Date(ts)), ns.utc(new Date(ts), 1));
}


扩展来自 @nkitku 的紧凑和神秘的解决方案,将其变成一组可重用的功能。

工作流程:

  • 所有函数都在一个命名空间中ns,因此它们不会与代码中可能具有相同名称的其他函数冲突
    • 命名空间还允许紧凑的函数表示法;std: ()=>Math.max(),相当于function std(){ return Math.max(); }
  • std()返回标准时间的时区偏移量
  • [0, 6]设置没有 DST 的月份和有 DST 的月份的比较
    • 0一月,因为Date.setMonth()是零索引
    • 6七月
    • 显然,每个人的标准时间都不是在一月,所以我们必须检查一月和七月
  • ...[]Array月份转换为 a Set,以便我们可以应用该map()函数
    • 原始数组无法运行map()
    • map()在同一个函数上运行一组变量并返回一个结果数组
  • Date用年、月、日 创建一个新对象
    • 年份(95在示例中)是任意的,因为年份对于此计算并不重要
    • 月份将我们的值[0, 6]作为变量插入v
    • 日期(1在示例中)也是任意的
    • 逻辑上我们可以创建一个new Date(), then .setMonth(v),但是使用任意数字更紧凑和更快
  • 现在我们有了日期,getTimezoneOffset()返回每个月的偏移量并将它们推送到结果数组
  • Math.max()从结果中找到最大值,这将是标准时间偏移
  • is_dst()检查当前是否为夏令时
    • new Date().getTimezoneOffset()获取当前偏移量,带或不带 DST
    • ns.std()获取标准时间的偏移量
    • 如果当前偏移量较低,则为 DST
  • utc()以 UTC 表示法返回一个字符串
    • std参数默认为关闭
    • z = std ? ns.std() : new Date().getTimezoneOffset()根据标志将时间设置为 DST 或标准
    • zm = z % 60捕获分钟,因为例如某些区域使用 30 分钟
    • (z > 0 ? '-' : '+')根据 UTC 符号分配正确的符号;正偏移值在符号中显示为负偏移
    • (z / 60).toString().padStart(2,'0根据符号以单位数格式捕获小时数,因此对于两位数格式无需)`
    • (zm ? ':' + zm : '')如果时区存在分钟,则附加分钟

由于此版本旨在紧凑,因此您可以通过去除多余的空白来节省更多空间。尽管这确实是缩小器的工作。

std:()=>Math.max(...[0,6].map(v=>new Date(95,v,1).getTimezoneOffset())),

const ns = {
  std: () => Math.max(...[0, 6].map(v => new Date(95, v, 1).getTimezoneOffset())),
  is_dst: () => new Date().getTimezoneOffset() < ns.std(),
  utc: (std = 0) => {
    let z = std ? ns.std() : new Date().getTimezoneOffset(),
      zm = z % 60;
    return 'UTC' + (z > 0 ? '-' : '+') + (z / 60) + (zm ? ':' + zm : '');
  }
};

console.log(ns.std(), ns.is_dst(), ns.utc(), ns.utc(1));

于 2021-03-30T07:56:46.047 回答
0

我最近需要使用 UTC 和 DST 创建一个日期字符串,并根据 Sheldon 的回答我把它放在一起:

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>

于 2015-09-29T23:49:06.900 回答
0

使用https://date-fns.org/v2.22.1/docs/Time-Zones可以用一行来解决

new Date().getUTCHours() + getTimezoneOffset('Europe/Amsterdam') / 1000 / 60 / 60;

于 2021-06-17T11:11:21.553 回答
0

使用有问题吗Date.toString().indexOf('Daylight Time') > -1

"" + new Date()

1 月 1 日星期六 100050 00:00:00 GMT-0500(东部标准时间)

"" + new Date(...)

Sun May 01 100033 00:00:00 GMT-0400(东部夏令时间)

这似乎与所有浏览器兼容。

于 2019-12-10T14:11:52.533 回答