如何检查DST(日光节约时间)是否有效,如果是,偏移量?

这是我的一点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小时。我不知道如何检查夏令时是否有效。

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

250885 次浏览

这段代码使用了这样一个事实:getTimezoneOffset在标准时间和日光节约时间(DST)期间返回更大的值。因此,它确定标准时间内的预期输出,并比较给定日期的输出是否相同(标准)或更少(DST)。

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

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!");
}

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

  • 如1月抵销>6月偏移,客户在北半球
  • 如果1月份冲抵<6月偏移,客户在南半球
  • 如果没有差异,则客户端时区不遵守夏令时

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

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

我今天也遇到了同样的问题,但由于我们的夏令时开始和结束的时间与美国不同(至少从我的理解来看),我使用了稍微不同的路线。

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和非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月, 即使在任何一个月的某个时间某个地点,它也会起作用。 但是在性能方面,如果确实是7月(或附近的月份)确实是夏令时,它会工作得更快

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

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

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

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

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

这仍然是错误的,如果他们是夏令时。您需要一个远程时间帐户,如果他们目前在他们的DST内或不在,并相应地调整。试着计算一下,把你的时钟调到2015年2月1日,把时钟调回一个小时,就像在夏令时之外一样。然后计算一个应该仍然落后2小时的地方的补偿。它会在两小时窗口前一小时显示。你仍然需要考虑时间和调整。我在纽约和丹佛都做过,在丹佛总是走错(提前一小时)。

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


其思想是,由于没有国家遵守持续7个月的夏时制__abc0,在遵守夏时制的地区,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();
}

我最近需要用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>

moment.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

我发现使用Moment.js库和这里描述的一些概念(比较Jan和June)非常有效。

这个简单的函数将返回用户所在的时区是否遵守日光节约时间:

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

检查它是否有效的一个简单方法(在Windows上)是将您的时区更改为非夏令时区域,例如亚利桑那州将返回false,而EST或PST将返回true。

enter image description here

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

MDN Web Docs

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

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

iana time zones

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

joda-time Time Zones . Time时区

+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。但这并没有告诉你今天< em > < / em >是否在浏览器时区使用夏令时。所以,你需要得到今天的时区偏移。

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
}

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

  1. x为在不考虑夏令时的情况下进入利息年的预期毫秒数。
  2. y时代自感兴趣日期的年份开始以来的毫秒数。
  3. z为自感兴趣的完整日期和时间的时代以来的毫秒数
  4. tz: z - y - xxy的减法。这会产生夏令时的偏移量。
  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");

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

  • 这个答案适用于所有时区,甚至南极洲/凯西
  • 夏时制很容易改变。也许20年后,一些国家可能会有3个夏时制而不是正常的2个。这段代码通过返回以毫秒为单位的DST偏移量来处理这种情况,而不仅仅是DST是否有效。
  • 一年中月份的大小和闰年的工作方式完全符合我们的时间与太阳的轨道。见鬼,它工作得如此完美,以至于我们所做的只是到处调整几秒钟。我们目前的闰年系统从1582年2月24日开始生效,并可能在可预见的未来继续有效。
  • 这段代码适用于不使用DST的时区。
  • 这段代码适用于DST实现之前的历史时期(例如1900年代)。
  • 这段代码是最大限度的整数优化,如果在一个紧密循环中调用,应该不会有任何问题。运行上面的代码片段后,向下滚动到输出的底部以查看性能基准测试。我的电脑在火狐浏览器上可以在29毫秒内处理16384个日期。

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

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

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

"" + new Date()

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

"" + new Date(...)

5月01日100033 00:00:00 GMT-0400(东部日光时间)

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

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

moment().isDST();将告诉你是否观察到日光节约。

也有辅助功能,为您计算相对时间。你不需要手动计算 如moment("20200105", "YYYYMMDD").fromNow(); < / p >

< >强更新: 在尝试在自定义datetime选择器中使用这些函数后,我注意到从3月切换到4月会像预期的那样切换时区,因为我的zone在3月切换夏令时。出乎意料的是,它正在切换到下一个时区,而不是在同一时区的标准和日光之间切换

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

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

更新工作流程:

  • t参数默认为new Date()
    • 对于固定时间,传入一个现有的Date
    • 对于当前时间,传入null或不传入任何值
  • std()已更新为使用t.setMonth(v);更改固定时间的月份
    • .getTimezoneOffset()不能链接到.setMonth(),所以我们需要从一行符号转换为使用闭包({})、终止符(;)和return
  • console.log()示例循环每个月(011)
    • 固定日期对象需要使用相同的时间戳克隆(let ts = +t;)
    • Date类型之前的+将其转换为带有Unix时间戳的number
    • 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]设置一个没有夏令时的月份和一个有夏令时的月份的比较
    • 0为一月份,因为Date.setMonth()是零索引
    • 6七月
    • 显然,并不是每个人的标准时间都在1月,所以我们必须同时检查1月和7月
  • ...[]将月份的Array转换为Set,因此我们可以应用map()函数
    • 原始数组不能运行map()
    • map()在同一个函数上运行一组变量,并返回一个结果数组
  • 创建一个包含年、月、日的新Date对象
    • 年份(例子中的95)是任意的,因为年份对于这个计算并不重要
    • 月份插入我们的值[0, 6]作为变量v
    • 日期(例子中的1)也是任意的
    • 逻辑上,我们可以先创建new Date(),再创建.setMonth(v),但使用任意数字更紧凑、更快
  • 现在我们有了日期,getTimezoneOffset()返回每个月的偏移量,并将它们推入结果数组
  • Math.max()从结果中找到最大的值,这将是标准时间偏移量
  • is_dst()检查当前是否为日光节约时间
    • new Date().getTimezoneOffset()获取当前偏移量,有或没有DST
    • ns.std()获取标准时间的偏移量
    • 如果电流偏移量较低,则为夏令时
  • utc()返回UTC格式的字符串
    • std参数默认为off
    • 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));

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

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