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標準、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!");
}
于 2012-08-09T17:04:50.903 に答える
35

この回答は、受け入れられた回答と非常に似ていますが、Dateプロトタイプをオーバーライドせず、2つではなく、1つの関数呼び出しのみを使用して夏時間が有効かどうかを確認します。


7か月続く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

2つの日付を作成します。1つは6月、もう1つは1月です。それらの値を比較しgetTimezoneOffset()ます。

  • 1月のオフセット>6月のオフセットの場合、クライアントは北半球にあります
  • 1月のオフセット<6月のオフセットの場合、クライアントは南半球にあります
  • 違いがない場合、クライアントのタイムゾーンはDSTを監視しません

getTimezoneOffset()次に、現在の日付を確認します。

  • 北半球の6月に等しい場合、現在のタイムゾーンは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

SheldonGriffinによって提供されたソリューションに関するMattJohansonのコメントに基づいて、次のコードを作成しました。

    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)1年ごとのstdTimezoneOffsetの結果をキャッシュして、同じ年の複数の日付をテストするときに結果を再計算する必要がないようにします。

2)DST(存在する場合)が必ずしも7月であるとは想定しておらず、ある時点およびある場所でいつでも機能する場合でも機能します。ただし、パフォーマンスに関しては、実際に7月(または数か月近く)が実際にDSTである場合、より高速に動作します。

3)最悪の場合、毎月1日のgetTimezoneOffsetを比較します。[そしてそれをテストされた年に一度行う]。

それでも、DST期間がある場合は、1か月よりも長いと想定されます。

誰かがその仮定を取り除きたい場合、彼はループをアーロン・コールによって提供されたソルチンのようなものに変えることができます-しかし、私はまだ半年先にジャンプして、2つの異なるオフセットが見つかったときにループから抜け出します]

于 2014-11-06T11:30:28.250 に答える
9

JavaScriptのgetTimezoneOffset()メソッドは、ブラウザーで、00:00タイムゾーンからオフセットされた分数を返します。たとえば、夏時間(DST)のAmerica / New_Yorkタイムゾーンは数値300を返します。300分は、ゼロから5時間の差です。300分を60分で割ると5時間になります。すべてのタイムゾーンは、ゼロタイムゾーン、+ 00:00/その他/GMT/グリニッジ標準時と比較されます。

MDN Web Docs

次に知っておく必要があるのは、オフセットの符号が実際のタイムゾーンと反対であるということです。

タイムゾーンに関する情報は、Internet Assigned Numbers Authority(iana)によって管理されています。

ianaタイムゾーン

タイムゾーンの適切にフォーマットされたテーブルは、joda.orgによって提供されます

joda-timeタイムゾーン

+00:00またはEtc/GMTはグリニッジ標準時です

すべてのタイムゾーンは+00:00 / "Etc /GMT"/グリニッジ標準時からオフセットされています

夏時間は、夏の「通常の」時間よりも常に早い時間です。あなたは秋の季節に時計を戻しました。(何をすべきかを覚えておくための「フォールバック」スローガン)

したがって、夏時間(冬)のAmerica / New_York時間は、通常の時間の1時間前です。したがって、たとえば、夏のニューヨーク市では通常午後5時でしたが、現在は夏時間のアメリカ/ニューヨーク時間の午後4時です。「America/New_York」時間という名前は、「LongFormat」タイムゾーン名です。米国の東海岸は通常、タイムゾーンを東部標準時(EST)と呼んでいます。

今日のタイムゾーンオフセットを他の日付のタイムゾーンオフセットと比較する場合は、タイムゾーンオフセットの数学的な符号(+/-「正/負」)がタイムゾーンの反対であることを知っておく必要があります。

joda.orgのタイムゾーンテーブルを見て、「America/New_York」のタイムゾーンを見つけます。標準オフセットの前に負の符号があります。

地球はその軸を中心に反時計回りに回転します。グリニッジで日の出を見る人は、ニューヨーク市の誰かが日の出を見る5時間前に日の出を見る。そして、米国の西海岸の誰かが日の出を見た後、米国の西海岸の誰かが日の出を見るでしょう。

これらすべてを知る必要があるのには理由があります。これにより、1年のさまざまな時期にすべてのタイムゾーンをテストしなくても、一部のJavaScriptコードがDSTステータスを正しく取得しているかどうかを論理的に判断できます。

ニューヨーク市の11月で、時計が1時間遅れていると想像してみてください。ニューヨーク市の夏のオフセットは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に含まれていてはなりません。

夏と冬のタイムゾーンオフセットの比較を省略して(このタイムゾーンに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 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の両方を減算します:。これにより、DSTによるオフセットが発生します。xyzz - y - x
  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年後、一部の国では通常の2ではなく3つのDST期間が設定される可能性があります。このコードは、DSTが有効かどうかだけでなく、ミリ秒単位でDSTオフセットを返すことでそのケースを処理します。
  • 1年の月のサイズとうるう年の働き方は、太陽との時間を順調に保つのに完全に適合します。なんと、それはとても完璧に機能するので、私たちが今までにやったことは、あちこちでほんの数秒調整するだけです。現在のうるう年のシステムは、1582年2月24日から有効になっており、当面は有効であり続ける可能性があります。
  • このコードは、DSTを使用しないタイムゾーンで機能します。
  • このコードは、DSTが実装される前の歴史的な時代(1900年代など)で機能します。
  • このコードは最大限に整数最適化されており、タイトなループで呼び出されても問題はありません。上記のコードスニペットを実行した後、出力の一番下までスクロールして、パフォーマンスベンチマークを確認します。私のコンピュータはFireFoxで29msで16384の日付を処理することができます。

ただし、2 DSTを超える期間の準備をしていない場合は、以下のコードを使用して、DSTがブール値として有効であるかどうかを判断できます。

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

ここで説明するいくつかの概念(1月と6月を比較)でMoment.jsライブラリを使用すると、非常にうまく機能することがわかりました。

この単純な関数は、ユーザーがいるタイムゾーンが夏時間を遵守しているかどうかを返します。

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

これが(Windowsで)機能することを確認する簡単な方法は、タイムゾーンを非DSTゾーンに変更することです。たとえば、アリゾナはfalseを返しますが、ESTまたはPSTはtrueを返します。

ここに画像の説明を入力してください

于 2017-11-03T20:10:33.283 に答える
1

あなたは近くにいますが、少し離れています。それはあなた自身の時計の結果であるため、あなたはあなた自身の時間を計算する必要はありません。それはあなたがあなたの場所で夏時間を使用しているかどうかを検出できますが、オフセットによって生成された遠隔地では検出できません:

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

彼らがDSTにいる場合、これはまだ間違っており、1時間オフになります。それらが現在DST内にあるかどうかにかかわらず、リモートタイムアカウントが必要であり、それに応じて調整します。これを計算して、時計を-たとえば2015年2月1日に変更し、DSTの外にあるかのように時計を1時間戻します。次に、まだ2時間遅れているはずの場所のオフセットを計算します。2時間のウィンドウの1時間前に表示されます。それでも、時間を考慮して調整する必要があります。私はニューヨークとデンバーのためにそれをしました、そしてデンバーでいつも間違った(1時間先に)行きます。

于 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

最近、UTCとDSTを使用して日付文字列を作成する必要がありました。シェルドンの回答に基づいて、これをまとめました。

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

使用に問題がありますかDate.toString().indexOf('Daylight Time') > -1

"" + new Date()

1月1日土曜日10005000:00:00GMT-0500(東部標準時

"" + new Date(...)

5月1日日曜日10003300:00:00GMT-0400(東部夏時間

これはすべてのブラウザと互換性があるようです。

于 2019-12-10T14:11:52.533 に答える
0

更新: カスタムdatetimeピッカーでこれらの関数を使用しようとした後、3月にゾーンがDSTを切り替えるため、3月から4月に切り替えるとタイムゾーンが期待どおりに切り替わることに気付きました。予期せぬことに、同じタイムゾーンで標準とデイライトを切り替えるのではなく、次のタイムゾーンに切り替えていました。

それは、私の元の関数が常にnew Date()現在の時刻または過去の任意の固定時刻に対して作成していたためです。これを3月と4月の相対時間と比較すると、代わりにタイムゾーンの切り替えとしてDSTトグルが論理的に検出されます。

解決策は、相対時間を効用関数に渡すことでした。そのため、私の比較はすべて、現在または任意の固定時間ではなく、相対時間に対するものでした。コンパクトさの一部が失われましたが、ロジックは必要に応じて機能するようになりました。

ワークフローの更新:

  • tパラメータのデフォルトはnew Date()
    • 一定時間、既存のものを渡すDate
    • 現在の時間は、渡すnullか何もしない
  • std()t.setMonth(v);固定時間の月を変更するため に使用するように更新されました
    • .getTimezoneOffset()にチェーンできないため、クロージャ( )、ターミネータ()、および.setMonth()を使用するには、1行表記から切り替える必要があります。{};return
  • console.log()例は毎月ループします(0から11
    • 固定日付オブジェクトは、同じタイムスタンプを使用して複製する必要があります(let ts = +t;
    • タイプがUnixタイムスタンプでそれをにキャストする+Datenumber
    • 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ありの月の比較を設定します
    • 01月の場合、Date.setMonth()はゼロインデックスであるため
    • 67月
    • どうやら、標準時は誰にとっても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()標準時でオフセットを取得します
    • 現在のオフセットが低い場合は、DSTです。
  • utc()UTC表記の文字列を返します
    • stdパラメータのデフォルトはオフです
    • z = std ? ns.std() : new Date().getTimezoneOffset()フラグに基づいて時間をDSTまたは標準に設定します
    • zm = z % 60たとえば、一部のゾーンは30分を使用するため、分をキャプチャします
    • (z > 0 ? '-' : '+')UTC表記ごとに正しい符号を割り当てます。正のオフセット値は、表記では負のオフセットとして表示されます
    • (z / 60)表記ごとに1桁の形式で時間をキャプチャするため、.toString().padStart(2,'02桁の形式の場合は)`する必要はありません。
    • (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

https://date-fns.org/v2.22.1/docs/Time-Zonesを使用すると、1行で解決できます

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

于 2021-06-17T11:11:21.553 に答える