2012-08-09 5 views
106

Das ist ein bisschen von meinem JS-Code, für die dieser benötigt wird:Wie überprüfe ich, ob die Sommerzeit (DST) wirksam ist und ob es sich um den Offset handelt?

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 die Datetime in vor erhalten möchten, aber wenn der DST in Gebrauch ist dann die Daten sind um 1 Stunde. Ich kann nicht überprüfen, ob die Sommerzeit in Gebrauch ist oder nicht.

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

Antwort

233

Der Code von veraltete Verknüpfung wird Ihnen sagen, ob Sommerzeit in Kraft ist. Es verwendet die Tatsache, dass getTimezoneOffset einen anderen Wert während DST und Standardzeit zurückgibt, und vergleicht den Unterschied zwischen den beiden. (Zum Beispiel in New York zurückkehrt -5 normalerweise und -4 während DST)

Bitte beachte, dass ich keine Ahnung, wie zu den Feinheiten der internationalen Zeitzonen, und habe nur getestet, dass es korrekte Ergebnisse für meine Zeitzone zurückkehrt .. aber Der Code scheint solide zu sein.

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

kann ich überprüfen, ob das international funktioniert. Momentan gibt es keine Zeitzonen, die irgendeine Form von DST verwenden, bei der sowohl der 1. Januar als auch der 1. Juli beide entweder in der DST-Periode oder beide sind. In allen Zeitzonen der TZDB (mit einer trivialen Ausnahme) (http://en.wikipedia.org/wiki/Antarctica/Casey)) ist der größere der beiden Offsets der DST-Offset. Da JavaScript 'getTimezoneOffset' den inversen Wert zurückgibt, gibt' Math.max' tatsächlich den * standard * Offset zurück. Der Code ist korrekt. –

+3

Wenn jedoch eine Zeitzone ihre Definition so ändert, dass sowohl der 1. Januar als auch der 1. Juli entweder beide in DST oder beide * nicht * in DST sind (und DST immer noch gilt), dann würde dieser Code in dieser Zone nicht funktionieren. –

+3

Das funktioniert super. Es ist wirklich nett, eine interne Konstante zu setzen wie: 'TIMEZONE_OFFSET = ((new Date()). Dst())?'-04: 00': '-05: 00'' – nessur

16

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

  • wenn Januar offset> Juni versetzt, ist Client in der nördlichen Hemisphäre
  • wenn Januar Offset < Juni Offset-Client ist in der südlichen Hemisphäre
  • wenn kein Unterschied, Client-Zeitzone nicht DST beobachten

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

  • wenn gleich Juni nördliche Hemisphäre, dann aktuelle Zeitzone DST (+1 Stunde)
  • wenn gleich Januar südliche Hemisphäre, dann aktuelle Zeitzone DST (+1 Stunde)
+0

Warum brauchen Sie die Hemisphären? Wäre es nicht genug zu sagen, wenn getTimezoneOffset() für das aktuelle Datum gleich dem kleineren der beiden getTimezoneOffset() ist, dann seine DST? [und der Offset ist der Unterschied zwischen den beiden?] – epeleg

+0

Sie brauchen nicht die Hemisphären, wie die angenommene Antwort deutlich zeigt :) –

+0

Dies wird nicht funktionieren. Am besten stellen Sie sicher, dass Sie UTC-Zeiten verwenden und den Offset für die gewünschte Region manuell festlegen. Suchen Sie dann manuell den Anfang und das Ende für die Sommerzeit für die gleiche Region (falls vorhanden). Dann möchten Sie überprüfen, ob die Zeit für diese Region innerhalb des DST-Bereichs liegt oder nicht, und dann den Offset entsprechend um +1 aktualisieren. Dies ermöglicht es, Länder zu vergleichen, die DST beobachten, und solche, die dies nicht tun. – Kebman

11

ich war mit dem gleichen Problem konfrontiert heute aber da unser Sommerzeit zeit~~POS=HEADCOMP beginnt und endet bei Zeiten aus den USA unterscheiden (zumindest von 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 Zeitzonen-Offset mit DST und nonDST, um zu sehen, welcher übereinstimmt.

+0

So machen wir es auch. Das heißt, ermitteln Sie die Zeiten des Jahres, in denen sich die Sommerzeit in Ihrer Zielzeitzone ändert, und berechnen Sie die Offsets für den aktuellen Tag und das letzte Änderungsdatum. Sie unterscheiden sich entweder um eine Stunde oder sind gleich (unter der Annahme, dass es sich um eine Stunde Offset handelt). – Heather

+0

Es ist nicht notwendig, 365 Werte zu erstellen, ein binärer Suchansatz, der stoppt, sobald eine Änderung des Offsets festgestellt wird, sollte sehr viel effizienter sein, selbst wenn keine Sommerzeit eingehalten wird. Alle diese Ansätze gehen davon aus, dass Orte jedes Jahr die Sommerzeit beobachten, was nicht unbedingt der Fall ist. Orte übernehmen und verlassen von Zeit zu Zeit die Sommerzeit (obwohl ECMAScript davon ausgeht, dass die aktuellen Regeln, unabhängig von ihrem Bereich, immer angewendet werden). – RobG

+1

Rob - Wie können Sie dies über eine binäre Suche tun, wenn Sie nicht wissen, wo Sie suchen sollen (d. H. Ist der Ort, nach dem Sie suchen, über oder unter Ihrem Testpunkt?) – epeleg

7

Basierend auf Matt Johansons kommentieren die von Sheldon Griffin bereitgestellte Lösung habe ich den folgenden Code:

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 wird versucht, das Beste aus allen Welten Berücksichtigung aller Kommentare und zuvor vorgeschlagenen Antworten nehmen zu erhalten und gezielt it:

1) Zwischenspeichert das Ergebnis pro Jahr stdTimezoneOffset, so dass Sie es nicht neu berechnen müssen, wenn mehrere Daten im selben Jahr getestet werden.

2) Es wird nicht davon ausgegangen, dass DST (wenn es überhaupt existiert) ist unbedingt im Juli, und wird funktionieren, auch wenn es irgendwann und an einem bestimmten Ort jeden Monat sein wird. Leistung Leistungweise wird es schneller arbeiten, wenn tatsächlich Juli (oder fast Monate) tatsächlich DST sind.

3) Schlimmsten Fall wird es die GetTimezoneOffset des ersten jeden Monats vergleichen. [und tue das Einmal pro getestetem Jahr].

Die Annahme, die es immer noch macht, ist, dass das, wenn es DST-Periode gibt, größer als ein einzelner Monat ist.

Wenn jemand diese Annahme entfernen möchte, kann er Schleife in etwas mehr wie was in der Lösung von Aaron Cole - aber ich würde immer noch springen ein halbes Jahr voraus und brechen aus der Schleife, wenn zwei verschiedene Offsets gefunden werden]

1

Sie sind nahe, aber ein wenig aus. Sie müssen nie Ihre eigene Zeit berechnen, da es ein Ergebnis Ihrer eigenen Uhr ist. Es kann erkennen, wenn Sie die Sommerzeit in der Lage verwenden, aber nicht für einen entfernten Ort durch den Offset erzeugt:

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

Dies wird immer noch falsch und ab einer Stunde sein, wenn sie in DST sind. Sie benötigen für ein Remote-Zeitkonto, ob sie gerade in ihrer Sommerzeit sind oder nicht und passen sie entsprechend an. Versuchen Sie dies zu berechnen und ändern Sie Ihre Uhr auf - sagen wir 2/1/2015 und setzen Sie die Uhr eine Stunde zurück, als wäre sie außerhalb der Sommerzeit. Berechnen Sie dann einen Offset für einen Ort, der noch 2 Stunden zurückliegt. 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 immer das falsche (eine Stunde voraus) in Denver gemacht.

5

Bereits gelöst, aber nur gedacht, dass ich hinzufügen sollte, wie ich es mache (falls die Leute interessiert sind).

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

funktioniert genauso wie die ausgenommen Antwort (janurary und Juli der Zeitzonen), dann ist die Bedingung zurückgibt.

0

ich vor kurzem benötigt ein Datum Zeichenfolge mit UTC und DST zu erstellen, und basierend auf Sheldons Antwort, die ich diese zusammen:

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 \t \t = num.toString().length; 
 
     var preCeilingLength = preCeiling.toString().length; 
 
     var preOffset \t \t = preCeilingLength - numLength; 
 
     for (var i = 0; i < preOffset; i++) { 
 
      num = "0" + num; 
 
     } 
 
    } 
 
    return num; 
 
} 
 
Number.prototype.getSign = function() { 
 
    var num \t = 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>

1

Die moment.js Bibliothek stellt eine .isDst() Methode auf seine Zeit Objekte.

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

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

Ich habe, dass die Moment.js Bibliothek mit einigen der hier beschriebenen Konzepte unter Verwendung gefunden (Vergleich Januar bis Juni) sehr gut funktioniert.

Diese einfache Funktion, ob der Zeitzone zurückkehren wird, dass sich der Benutzer befindet beobachtet Sommerzeit:

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

Ein einfacher Weg, um zu überprüfen, dass dies funktioniert (unter Windows) ist Ihre Zeitzone zu einem nicht DST zu ändern zone z. B. wird Arizona falsch zurückgeben, während EST oder PST wahr zurückgibt.

enter image description here

0

getTimezoneOffset() Die Methode in JavaScript, in einem Browser, gibt die Anzahl der Minuten vom 00.00 Zeitzone ausgeglichen.Zum Beispiel gibt die Zeitzone America/New_York in Daylight Savings (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 Nullzeitzone + 00: 00/Etc/GMT/Greenwich-Zeit verglichen.

MDN Web Docs

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

Informationen über Zeitzonen wird durch die Internet Assigned Numbers Authority (IANA)

iana time zones gehalten

Eine schön formatierte Tabelle der Zeitzonen von geliefert wird joda.org

joda-time Time Zones

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

Alle Zeitzonen ar e Offset von +00: 00/"Etc/GMT"/Greenwich-Zeit

Sommerzeit ist immer eine frühere Zeit als die "reguläre" Zeit im Sommer. Sie stellen Ihre Uhren im Herbst zurück. ("Fallen" Slogan zu erinnern, was zu tun ist)

So, Amerika/New_York Zeit in Daylight Savings (Winter) ist eine Stunde vor der regulären Zeit. Also zum Beispiel, was normalerweise 17 Uhr war. Nachmittags in New York City im Sommer, ist jetzt 16.00 Uhr. America/New_York Zeit in Daylight Savings. Der Name "America/New_York" -Zeit ist ein "Long Format" -Zeitzonenname. Die Ostküste der USA fordert der Regel ihre Zeitzone Eastern Standard Time (EST)

Wenn Sie Zeitzone des heute wollen Offset der Zeitzone von einem anderen Zeitpunkt versetzt vergleichen, können Sie das Vorzeichen wissen müssen (+/- "Positiv/Negativ") des Zeitzonen-Offsets ist das Gegenteil der Zeitzone.

Sehen Sie sich die Zeitzonentabelle auf joda.org an und finden Sie die Zeitzone für "America/New_York". Sie wird ein negatives Vorzeichen vor dem Standard Offset haben.

Die Erde dreht sich gegen den Uhrzeigersinn um ihre Achse. Eine Person, die den Sonnenaufgang in Greenwich sieht, sieht den Sonnenaufgang 5 Stunden bevor jemand in New York City den Sonnenaufgang sehen wird. 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 können Sie logisch feststellen, ob JavaScript-Code den DST-Status korrekt ermittelt oder nicht, ohne dass Sie jede Zeitzone zu unterschiedlichen Zeiten im Jahr testen müssen.

Stellen Sie sich vor, es ist November in New York City, und die Uhren wurden 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 Offset 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 in der Protokolldatei des Browsers für Entwicklerwerkzeuge gedruckt?

Antwort ist: 240

So, jetzt können Sie ein Datum im Januar erstellen und sehen, was Ihr Browser für eine Zeitzone zurückkehrt für die Wintersaison ausgeglichen.

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) 

Antwort ist: 300

Offensichtlich 300 ist größer als 240. Also, was bedeutet das? Solltest du Code schreiben, der testet, dass der Winter-Offset größer als der Sommer-Offset ist? Oder der Sommer-Offset weniger als der Winter-Offset? 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. Aber das sagt Ihnen nicht, wenn heute DST für die Zeitzone des Browsers verwendet. Sie müssen also den Zeitzonen-Offset für heute abrufen.

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

console.log('todaysTimeZone : ' + todaysTimeZone) 

Antwort ist:? - Abhängig von der Jahreszeit

Wenn die Zeitzone der heutigen versetzt und die Sommerzeit-Offset-Zone ist die gleiche, UND die Sommer- und Winterzeitzone Offsets unterschiedlich ist, dann durch logische Deduktion, muss heute nicht in sein wird DST.

Können Sie den Vergleich der Sommer- und Winterzeitzonen-Offsets auslassen (um zu wissen, ob DST für diese Zeitzone verwendet wird) und einfach den heutigen Zeitzonen-Offset mit dem Sommer-TZ-Offset vergleichen und immer die richtige Antwort erhalten?

today's TZ Offset !== Summer TZ Offset 

Nun, ist heute im Winter oder Sommer? Wenn Sie, dass dann wussten, dass Sie die folgende Logik anwenden könnten:

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

Aber das Problem ist, dass Sie nicht wissen, ob die heutige Datum im Winter oder Sommer. Jede Zeitzone kann eigene Regeln für den Beginn und das Ende der Sommerzeit haben. Sie müssen die Regeln jeder Zeitzone für jede Zeitzone der Welt im Auge behalten. Also, wenn es einen besseren und leichteren Weg gibt, dann könntest du es auch besser und einfacher machen.

Wir müssen wissen, ob diese Zeitzone DST verwendet, und dann den heutigen Zeitzonen-Offset mit dem Sommer-Zeitzonen-Offset vergleichen. Das gibt dir immer eine zuverlässige Antwort.

Die letzte Logik ist:

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

Funktion, um zu bestimmen, ob die Zeitzone im Browser DST 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 
}