Wie kann überprüft werden, ob die Sommerzeit und damit der Versatz wirksam sind?

154

Dies ist ein Teil meines JS-Codes, für den dies benötigt wird:

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

Ich möchte die Datums- und Uhrzeitangabe in "vor" erhalten, aber wenn die Sommerzeit verwendet wird, sind die Datumsangaben um 1 Stunde verschoben. Ich weiß nicht, wie ich überprüfen soll, ob die Sommerzeit wirksam ist oder nicht.

Wie kann ich wissen, wann die Sommerzeit beginnt und endet?

Jo Smo
quelle

Antworten:

313

Dieser Code verwendet die Tatsache, dass während der Standardzeit im Vergleich zur Sommerzeit (DST) getTimezoneOffsetein größerer Wert zurückgegeben wird. Auf diese Weise wird die erwartete Ausgabe während der Standardzeit bestimmt und verglichen, ob die Ausgabe des angegebenen Datums gleich (Standard) oder kleiner (DST) ist.

Beachten Sie, dass getTimezoneOffsetRenditen positive Zahlen von Minuten für die Zonen westlich von UTC, die in der Regel als angegeben sind negativ Stunden (da sie „hinter“ UTC). Zum Beispiel ist Los Angeles UTC-8h Standard, UTC-7h DST. getTimezoneOffsetkehrt 480im Dezember (Winter, Standardzeit) zurück (positive 480 Minuten) und nicht -480. Es gibt negative Zahlen für die östliche Hemisphäre zurück (wie -600für Sydney im Winter, obwohl dies "voraus" ist ( UTC + 10h ).

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!");
}
Sheldon Griffin
quelle
28
Ich kann überprüfen, ob dies international funktioniert. Derzeit gibt es keine Zeitzonen, in denen eine Sommerzeit verwendet wird, in der sowohl der 1. Januar als auch der 1. Juli entweder innerhalb oder außerhalb der Sommerzeit liegen. In allen Zeitzonen in der TZDB ( mit einer trivialen Ausnahme ) ist der DST-Versatz der größere der beiden Offsets. Da JavaScript getTimezoneOffsetden inversen Wert zurückgibt, Math.maxwird tatsächlich der Standardoffset zurückgegeben . Der Code ist korrekt.
Matt Johnson-Pint
7
Wenn jedoch eine Zeitzone jemals ihre Definition so ändert, dass sowohl der 1. Januar als auch der 1. Juli entweder beide in der Sommerzeit oder beide nicht in der Sommerzeit sind (und die Sommerzeit weiterhin gilt), funktioniert dieser Code in dieser Zone nicht.
Matt Johnson-Pint
9
Dies funktioniert im Allgemeinen nicht, z. B. gibt es Länder, die die Sommerzeit in bestimmten Jahren nicht eingehalten haben, und einige Länder setzen die Sommerzeit während des Ramadan zurück. Darüber hinaus ist die ECMAScript-Definition für Datum fehlerhaft, und in einigen Implementierungen ist auch die Behandlung der TZ-Umgebungsvariablen fehlerhaft. All dies zusammen macht diese Methode unzuverlässig. Sie sind besser dran, wenn Sie eine Bibliothek verwenden, die kein Datum verwendet, z. B.
timezonecomplete
5
Dieser Code funktioniert nicht in Ländern, in denen die Sommerzeit nicht eingehalten wird, z. B. in Südafrika oder Island. Das heißt, wenn Sie es zum Vergleich mit anderen Zeitzonen in diesen Ländern verwenden, werden dort nicht die richtigen Zeiten angezeigt. Schlagen Sie vor, UTC vollständig zu verwenden, und prüfen Sie manuell, ob die Zeit jetzt innerhalb eines bestimmten Sommerzeitbereichs liegt. Dann ist es nur noch eine Frage der Änderung des normalen UTC-Zeitversatzes um +1, um die Sommerzeit zu erhalten.
Kebman
1
Wie kann das richtig sein? Deutschland beispielsweise trat am 30.10.2016 in die Sommerzeit ein, während die USA eine Woche später am 06.11.2016 eintraten. Schlechte Informationen wie diese führen dazu, dass solche Dinge
Daniel F
22

Erstellen Sie zwei Daten: eine im Juni und eine im Januar. Vergleichen Sie ihre getTimezoneOffset () -Werte.

  • Wenn der Januar-Offset> der Juni-Offset ist, befindet sich der Kunde auf der Nordhalbkugel
  • Wenn der Januar-Offset <Juni-Offset ist, befindet sich der Kunde auf der südlichen Hemisphäre
  • Wenn kein Unterschied besteht, beobachtet die Client-Zeitzone keine Sommerzeit

Überprüfen Sie nun getTimezoneOffset () des aktuellen Datums.

  • Wenn gleich Juni, nördliche Hemisphäre, ist die aktuelle Zeitzone Sommerzeit (+1 Stunde)
  • Wenn gleich Januar, südliche Hemisphäre, dann ist die aktuelle Zeitzone DST (+1 Stunde)
Jon Nylander
quelle
Warum brauchst du die Hemisphären? Wäre es nicht genug zu sagen, dass wenn getTimezoneOffset () für das aktuelle Datum gleich dem kleineren der beiden getTimezoneOffset () ist, dann seine Sommerzeit? [und der Versatz ist der Unterschied zwischen den beiden?]
Epeleg
Sie brauchen die Hemisphären nicht, wie die akzeptierte Antwort deutlich zeigt :)
Jon Nylander
Das wird nicht funktionieren. Am besten stellen Sie sicher, dass Sie UTC-Zeiten verwenden und den Versatz für die Region, für die Sie ihn wünschen, manuell festlegen. Suchen Sie dann manuell den Start und das Ende für die Sommerzeit für dieselbe Region (falls vorhanden). Dann möchten Sie überprüfen, ob die Zeit für diesen Bereich innerhalb des DST-Bereichs liegt oder nicht, und dann den Offset entsprechend mit +1 aktualisieren. Dies ermöglicht es, Länder zu vergleichen, die die Sommerzeit einhalten, und solche, die dies nicht tun.
Kebman
Die Frage ist, wie Sie feststellen können, ob die Sommerzeit in der Zeitzone des Client-Computers Kebman aktuell ist, und nicht, wie Datumsangaben angezeigt werden. Web-Clients erledigen dies bereits für Sie.
Jon Nylander
Sie sollten zwischen Januar und Juli (oder Februar und August, März und September usw.) nachsehen, da sie 6 Monate voneinander entfernt sind.
kpull1
17

Diese Antwort ist der akzeptierten Antwort ziemlich ähnlich, überschreibt jedoch nicht den DatePrototyp und verwendet nur einen Funktionsaufruf, um zu überprüfen, ob die Sommerzeit wirksam ist, anstatt zwei.


Die Idee ist, dass, da kein Land die Sommerzeit einhält, die 7 Monate dauert [1] , in einem Gebiet, in dem die Sommerzeit eingehalten wird, der Versatz von der UTC-Zeit im Januar anders sein wird als im Juli.

Während die Sommerzeit die Uhren vorwärts bewegt , gibt JavaScript während der Standardzeit immer einen größeren Wert zurück. Wenn Sie also den Mindestversatz zwischen Januar und Juli erhalten, erhalten Sie den Zeitzonenversatz während der Sommerzeit.

Wir prüfen dann, ob die Zeitzone des Datums diesem Mindestwert entspricht. Wenn ja, dann sind wir in der Sommerzeit; sonst sind wir nicht.

Die folgende Funktion verwendet diesen Algorithmus. Es nimmt ein Datumsobjekt dund wird zurückgegeben, truewenn für dieses Datum Sommerzeit gilt und falsewenn dies nicht der Fall ist:

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(); 
}
Toastrackenigma
quelle
1
Dies funktioniert, aber wenn in der aktuellen Zeitzone keine Sommerzeit vorhanden ist, wird auch true angezeigt, was nicht korrekt ist. Wenn Sie auf wechseln Math.max(...) != d.get...(), wird true zurückgegeben, wenn die Sommerzeit in der angegebenen Zeitzone eingehalten wird UND das Datum derzeit in der Sommerzeit liegt. Wenn die Sommerzeit nicht eingehalten wird oder das Datum mit dem Standardversatz übereinstimmt, wird false zurückgegeben.
GreySage
12

Ich war heute mit dem gleichen Problem konfrontiert, aber da unsere Sommerzeit zu unterschiedlichen Zeiten in den USA beginnt und endet (zumindest nach meinem Verständnis), habe ich eine etwas andere Route verwendet.

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

Dann vergleichen Sie einfach den aktuellen Zeitzonenversatz mit DST und nonDST, um festzustellen, welcher übereinstimmt.

Aaron Cole
quelle
So machen wir es auch. Ermitteln Sie also die Jahreszeiten, zu denen sich die Sommerzeit in Ihrer Zielzeitzone ändert, und berechnen Sie Offsets für den aktuellen Tag und das letzte Änderungsdatum. Sie unterscheiden sich entweder um eine Stunde oder sind gleich (vorausgesetzt, die betreffende Zeitzone ist ein Stundenversatz).
Heather
Es ist nicht erforderlich, 365 Werte zu erstellen. Ein binärer Suchansatz, der beendet wird, sobald eine Änderung des Versatzes festgestellt wird, sollte sehr viel effizienter sein, selbst wenn keine Sommerzeit beobachtet wird. Alle diese Ansätze gehen davon aus, dass Orte jedes Jahr Sommerzeit beobachten, was nicht unbedingt der Fall ist. Orte übernehmen von Zeit zu Zeit die Sommerzeit und geben sie auf (obwohl ECMAScript die aktuellen Regeln übernimmt, unabhängig davon, in welchem ​​Bereich sie angewendet werden).
RobG
2
Rob - wie können Sie dies über eine binäre Suche tun, wenn Sie nicht wissen, wo Sie suchen sollen (dh ist der Ort, den Sie suchen, über oder unter
Ihrem
9

Basierend auf Matt Johansons Kommentar zu der von Sheldon Griffin bereitgestellten Lösung habe ich den folgenden Code erstellt:

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

Es versucht, das Beste aus allen Welten zu bekommen, wobei alle Kommentare und zuvor vorgeschlagenen Antworten berücksichtigt werden und insbesondere Folgendes:

1) Zwischenspeichert das Ergebnis für stdTimezoneOffset pro Jahr, sodass Sie es nicht neu berechnen müssen, wenn Sie mehrere Daten im selben Jahr testen.

2) Es wird nicht davon ausgegangen, dass die Sommerzeit (falls überhaupt vorhanden) notwendigerweise im Juli liegt und auch dann funktioniert, wenn sie irgendwann und irgendwann in einem Monat sein wird. In Bezug auf die Leistung wird es jedoch schneller funktionieren, wenn im Juli (oder in der Nähe von Monaten) tatsächlich Sommerzeit ist.

3) Im schlimmsten Fall wird das getTimezoneOffset des ersten eines jeden Monats verglichen. [und mach das einmal pro getestetem Jahr].

Es wird immer noch davon ausgegangen, dass die Sommerzeit größer als ein einzelner Monat ist.

Wenn jemand diese Annahme aufheben möchte, kann er die Schleife in etwas ändern, das eher der Lösung von Aaron Cole entspricht - aber ich würde trotzdem ein halbes Jahr voraus springen und aus der Schleife ausbrechen, wenn zwei verschiedene Offsets gefunden werden.]

Epeleg
quelle
4

Die Bibliothek moment.js bietet eine .isDst()Methode für ihre Zeitobjekte .

moment # isDST prüft, ob der aktuelle Moment in der Sommerzeit liegt.

moment([2011, 2, 12]).isDST(); // false, March 12 2011 is not DST
moment([2011, 2, 14]).isDST(); // true, March 14 2011 is DST
Daniel F.
quelle
Ich habe versucht, var moment = require ('moment'); this.logger.info (moment ([2011, 2, 12]). isDST ()); this.logger.info (Moment ([2011, 2, 14]). isDST ()); beide sind falsch
Logan_B
Die DST-Änderungsdaten variieren zwischen den Ländern , sogar zwischen den Bundesstaaten desselben Landes (dh dem Bundesstaat Arizona). In den USA war es am 13.03.2011, in Deutschland am 31.03.2011. Das Ergebnis hängt also davon ab, in welcher Zeitzone moment.js konfiguriert ist.
Daniel F
1
Es variiert sogar innerhalb des Bundesstaates Arizona timeanddate.com/time/us/arizona-no-dst.html
Daniel F
3

Die getTimezoneOffset()Methode in JavaScript in einem Browser gibt die Anzahl der Minuten zurück, die von der Zeitzone 00:00 versetzt sind. Beispielsweise gibt die Zeitzone America / New_York in der Sommerzeit (DST) die Zahl 300 zurück. 300 Minuten sind 5 Stunden Unterschied von Null. 300 Minuten geteilt durch 60 Minuten sind 5 Stunden. Jede Zeitzone wird mit der Zeitzone Null verglichen, +00: 00 / Etc / GMT / Greenwich-Zeit.

MDN-Webdokumente

Das nächste, was Sie wissen müssen, ist, dass der Versatz das entgegengesetzte Vorzeichen der tatsächlichen Zeitzone hat.

Informationen zu Zeitzonen werden von der Internet Assigned Numbers Authority (iana) verwaltet.

iana Zeitzonen

Eine schön formatierte Tabelle mit Zeitzonen wird von joda.org bereitgestellt

joda-time Zeitzonen

+00: 00 oder Etc / GMT ist Greenwich-Zeit

Alle Zeitzonen sind von +00: 00 / "Etc / GMT" / Greenwich-Zeit versetzt

Die Sommerzeit ist immer eine frühere Zeit als die "normale" Zeit im Sommer. Sie stellen Ihre Uhren in der Herbstsaison zurück. (Slogan "Fall Back", um sich daran zu erinnern, was zu tun ist)

Die America / New_York-Zeit in der Sommerzeit (Winter) liegt also eine Stunde vor der regulären Zeit. So war beispielsweise im Sommer in New York City normalerweise um 17 Uhr nachmittags die Sommerzeit um 16 Uhr in Amerika / New York. Der Name "America / New_York" ist ein Zeitzonenname im "Langformat". Die Ostküste der USA nennt ihre Zeitzone normalerweise Eastern Standard Time (EST).

Wenn Sie den heutigen Zeitzonenversatz mit dem Zeitzonenversatz eines anderen Datums vergleichen möchten, müssen Sie wissen, dass das mathematische Vorzeichen (+/- "Positiv / Negativ") des Zeitzonenversatzes das Gegenteil der Zeitzone ist.

Schauen Sie sich die Zeitzonentabelle auf joda.org an und finden Sie die Zeitzone für "America / New_York". Vor dem Standardversatz wird ein negatives Vorzeichen angezeigt.

Die Erde dreht sich um ihre Achse gegen den Uhrzeigersinn. Eine Person, die den Sonnenaufgang in Greenwich beobachtet, sieht den Sonnenaufgang 5 Stunden bevor jemand in New York City den Sonnenaufgang sieht. Und jemand an der Westküste der USA wird den Sonnenaufgang sehen, nachdem jemand an der Ostküste der USA den Sonnenaufgang gesehen hat.

Es gibt einen Grund, warum Sie das alles wissen müssen. Damit Sie logisch feststellen können, ob ein JavaScript-Code den DST-Status korrekt erhält oder nicht, ohne jede Zeitzone zu unterschiedlichen Jahreszeiten testen zu müssen.

Stellen Sie sich vor, es ist November in New York City und die Uhren wurden um eine Stunde zurückgestellt. Im Sommer in New York City beträgt der Offset 240 Minuten oder 4 Stunden.

Sie können dies testen, indem Sie ein Datum im Juli erstellen und dann den Versatz abrufen.

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

console.log('july_Timezone_OffSet: ' + july_Timezone_OffSet)

Was wird im Konsolenprotokoll der Entwicklertools des Browsers gedruckt?

Die Antwort lautet: 240

Jetzt können Sie ein Datum im Januar erstellen und sehen, was Ihr Browser für einen Zeitzonenversatz für die Wintersaison zurückgibt.

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)

Die Antwort lautet: 300

Offensichtlich ist 300 größer als 240. Was bedeutet das? Sollten Sie Code schreiben, der prüft, ob der Winterversatz größer als der Sommerversatz ist? Oder der Sommerversatz weniger als der Winterversatz? Wenn es einen Unterschied zwischen den Sommer- und Winterzeitzonenversätzen gibt, können Sie davon ausgehen, dass die Sommerzeit für diese Zeitzone verwendet wird. Das sagt Ihnen jedoch nicht, ob heute die Sommerzeit für die Zeitzone des Browsers verwendet wird. Sie müssen also den Zeitzonenversatz für heute erhalten.

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

console.log('todaysTimeZone : ' + todaysTimeZone)

Antwort ist: ? - Abhängig von der Jahreszeit

Wenn der heutige Zeitzonenversatz und der Sommerzeitzonenversatz gleich sind UND die Sommer- und Winterzeitzonenversätze unterschiedlich sind, darf der heutige Tag logischerweise NICHT in der Sommerzeit liegen.

Können Sie den Vergleich der Sommer- und Winterzeitzonenversätze weglassen (um zu wissen, ob die Sommerzeit für diese Zeitzone verwendet wird) und einfach den heutigen Zeitzonenversatz mit dem Sommer-TZ-Versatz vergleichen und immer die richtige Antwort erhalten?

today's TZ Offset !== Summer TZ Offset

Nun, ist heute im Winter oder Sommer? Wenn Sie das wüssten, könnten Sie die folgende Logik anwenden:

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

Das Problem ist jedoch, dass Sie nicht wissen, ob das heutige Datum im Winter oder Sommer liegt. Jede Zeitzone kann ihre eigenen Regeln für den Start und Stopp der Sommerzeit haben. Sie müssen die Regeln jeder Zeitzone für jede Zeitzone auf der Welt im Auge behalten. Wenn es also einen besseren und einfacheren Weg gibt, können Sie es genauso gut besser und einfacher machen.

Was uns bleibt, ist, dass Sie wissen müssen, ob diese Zeitzone die Sommerzeit verwendet, und dann den heutigen Zeitzonenversatz mit dem Sommerzeitzonenversatz vergleichen müssen. Das gibt Ihnen immer eine verlässliche Antwort.

Die letzte Logik lautet:

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

Funktion zum Bestimmen, ob die Zeitzone im Browser die Sommerzeit verwendet:

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
}
Alan Wells
quelle
Laut dateandtime.com begann die Sommerzeit am 10. März 2019 und ist daher im Sommer und nicht im Winter, und der New Yorker Sommerzeit-Offset beträgt -4, nicht -5.
jk7
Wenn die Antwort verbessert oder korrigiert werden muss, nehmen Sie sie bitte vor und sie wird überprüft.
Alan Wells
2

Verwenden Sie Moment.js ( https://momentjs.com/ )

moment().isDST(); gibt Ihnen, wenn Sommerzeiteinsparungen beobachtet werden.

Es hat auch eine Hilfsfunktion, um die relative Zeit für Sie zu berechnen. Sie müssen keine manuellen Berechnungen durchführen, zmoment("20200105", "YYYYMMDD").fromNow();

Santhosh S.
quelle
1

Du bist nah dran, aber ein bisschen daneben. Sie müssen niemals Ihre eigene Zeit berechnen, da dies ein Ergebnis Ihrer eigenen Uhr ist. Es kann erkennen, ob Sie an Ihrem Standort Sommerzeit verwenden, jedoch nicht für einen entfernten Standort, der durch den Versatz erzeugt wird:

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

Dies ist immer noch falsch und eine Stunde später, wenn sie sich in der Sommerzeit befinden. Sie benötigen ein Remote-Zeitkonto, wenn sie sich derzeit in ihrer Sommerzeit befinden oder nicht, und passen sie entsprechend an. Versuchen Sie dies zu berechnen und ändern Sie Ihre Uhr auf - sagen wir 2/1/2015 und stellen Sie die Uhr eine Stunde zurück, als ob sie außerhalb der Sommerzeit liegt. Berechnen Sie dann einen Versatz für einen Ort, der noch 2 Stunden zurückliegen sollte. Es wird eine Stunde vor dem zweistündigen Fenster angezeigt. Sie müssten immer noch die Stunde berücksichtigen und anpassen. Ich habe es für NY und Denver gemacht und bin in Denver immer falsch gelaufen (Stunde voraus).

Larry Enzer
quelle
1

Ich habe das mit der Moment.js gefunden Bibliothek mit einigen der hier beschriebenen Konzepte (Vergleich von Jan mit Juni) sehr gut funktioniert.

Diese einfache Funktion gibt zurück, ob die Zeitzone, in der sich der Benutzer befindet, die Sommerzeit einhält:

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

Eine einfache Möglichkeit, um zu überprüfen, ob dies funktioniert (unter Windows), besteht darin, Ihre Zeitzone in eine Nicht-Sommerzeitzone zu ändern. Beispielsweise gibt Arizona false zurück, während EST oder PST true zurückgeben.

Geben Sie hier die Bildbeschreibung ein

Nico Westerdale
quelle
1

Zukunftssichere Lösung, die in allen Zeitzonen funktioniert

  1. Lassen x die erwartete Anzahl von Millisekunden im Jahr des Interesses sein, ohne die Sommerzeit zu berücksichtigen.
  2. Sei ydie Anzahl der Millisekunden seit der Epoche ab Jahresbeginn des Zinsdatums.
  3. Sei zdie Anzahl der Millisekunden seit der Epoche des vollständigen Datums und der Uhrzeit des Interesses
  4. Sei tdie Subtraktion von beiden xund yvon z: z - y - x. Dies ergibt den Versatz aufgrund der Sommerzeit.
  5. Wenn tNull ist, ist die Sommerzeit nicht wirksam. Wenn tnicht Null ist, ist die Sommerzeit wirksam.

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

Ich glaube, dass das obige Code-Snippet aus vielen Gründen allen anderen hier veröffentlichten Antworten überlegen ist.

  • Diese Antwort funktioniert in allen Zeitzonen, auch in der Antarktis / Casey .
  • Die Sommerzeit kann sich stark ändern. Es kann sein, dass in 20 Jahren in einigen Ländern 3 DST-Perioden anstelle der normalen 2 vorliegen. Dieser Code behandelt diesen Fall, indem der DST-Offset in Millisekunden zurückgegeben wird, nicht nur, ob die DST in Kraft ist oder nicht.
  • Die Größe der Monate des Jahres und die Art und Weise, wie Schaltjahre funktionieren, passen perfekt dazu, unsere Zeit mit der Sonne in Einklang zu halten. Heck, es funktioniert so perfekt, dass wir nur hier und da nur Sekunden einstellen . Unser derzeitiges System der Schaltjahre ist seit dem 24. Februar 1582 in Kraft und wird wahrscheinlich auf absehbare Zeit in Kraft bleiben.
  • Dieser Code funktioniert in Zeitzonen, in denen keine Sommerzeit verwendet wird.
  • Dieser Code funktioniert in historischen Zeiten vor der Implementierung der Sommerzeit (z. B. in den 1900er Jahren).
  • Dieser Code ist maximal ganzzahloptimiert und sollte kein Problem darstellen, wenn er in einer engen Schleife aufgerufen wird. Scrollen Sie nach dem Ausführen des obigen Code-Snippets nach unten zum Ende der Ausgabe, um den Leistungsbenchmark anzuzeigen. Mein Computer kann 16384 Daten in ~ 97 ms auf Chrome verarbeiten.

Wenn Sie sich jedoch nicht auf mehr als 2 Sommerzeitperioden vorbereiten, können Sie mit dem folgenden Code bestimmen, ob die Sommerzeit als Boolescher Wert wirksam ist.

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

Ich musste kürzlich eine Datumszeichenfolge mit UTC und DST erstellen und basierend auf Sheldons Antwort habe ich Folgendes zusammengestellt:

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>

Akinuri
quelle
0

Gibt es ein Problem mit der Date.toString().indexOf('Daylight Time') > -1

"" + new Date()

Sa Jan 01 100050 00:00:00 GMT-0500 (Eastern Standard Time)

"" + new Date(...)

So Mai 01 100033 00:00:00 GMT-0400 (Eastern Daylight Time)

Dies scheint mit allen Browsern kompatibel zu sein.

YC
quelle
Ja, es funktioniert nicht auf der ganzen Welt. Im Sommer in Europa bekommen Sie"Thu Jul 02 2020 14:07:01 GMT+0200 (Central European Summer Time)"
Tadej Krevh
0

ES6 Style

Math.min(...[0, 6].map(v => new Date(95, v, 1).getTimezoneOffset() * -1));
nkitku
quelle