519 Stimmen

Erzeugen eines Datums mit einer bestimmten Zeitzone ohne Verwendung einer String-Darstellung

Ich habe eine Webseite mit drei Dropdown-Listen für Tag, Monat und Jahr. Wenn ich das JavaScript verwende Date Konstruktor, der Zahlen annimmt, dann erhalte ich eine Date Objekt für meine aktuelle Zeitzone:

new Date(xiYear, xiMonth, xiDate)

Geben Sie das richtige Datum an, aber aufgrund der Sommerzeit wird dieses Datum für GMT+01:00 gehalten.

Das Problem dabei ist, dass ich dann diese Date an eine Ajax-Methode, und wenn das Datum auf dem Server deserialisiert wird, wurde es in GMT umgewandelt und hat dadurch eine Stunde verloren, wodurch sich der Tag um eine Stunde nach hinten verschiebt. Jetzt könnte ich nur den Tag, Monat und Jahr einzeln in die Ajax-Methode übergeben, aber es scheint, dass es einen besseren Weg sein sollte.

Die akzeptierte Antwort wies mich in die richtige Richtung, aber nur mit setUTCHours() von selbst verändert:

Apr 5th 00:00 GMT+01:00 

まで

Apr 4th 23:00 GMT+01:00

Dann musste ich auch noch das UTC-Datum, den Monat und das Jahr einstellen, um am Ende Folgendes zu erhalten

Apr 5th 01:00 GMT+01:00

was ich auch wollte.

22 Stimmen

Wenn die akzeptierte Antwort Sie zwar in die richtige Richtung führt, aber Ihre Frage nicht beantwortet, sollte sie meiner Meinung nach nicht die akzeptierte Antwort sein. Die Antwort sollte die gestellte Frage beantworten.

3voto

meouw Punkte 40856

Jeder Kilometerstand in

var d = new Date(xiYear, xiMonth, xiDate).toLocaleString();

0 Stimmen

Das scheint bei mir zu funktionieren (eine Zeitzone von der GMT entfernt), aber da "locale" nicht unbedingt zeitzonenbezogen ist, würde ich mich nicht darauf verlassen.

2voto

Kate Punkte 31

Ich hatte ein ähnliches Problem mit einem Datumspicker. Meine Forschung führte zu einer sehr einfachen Lösung, ohne zusätzliche Bibliotheken oder hart kodierte Multiplikatoren.

Wichtige Informationen:

  1. ISO ist der von Javascript bevorzugte Datumsstandard. Gehen Sie davon aus, dass Datums-Utilities wahrscheinlich Datumswerte in diesem Format zurückgeben werden.

    • Meine Datumsauswahl zeigt das Datum in einem lokalisierten Format an: mm/dd/yyyy

    • Es gibt jedoch den Datumswert im ISO-Format zurück: yyyy-mm-dd

      //Select "08/12/2020" in Date Picker date_input 
      
      var input = $('#date_input').val();  //input: 2020-08-12
  2. Date.getTimezoneOffset() gibt den Zeitabstand in Minuten zurück.

Beispiele:

Wenn Sie den standardmäßig zurückgegebenen Datumswert verwenden, ohne das String-Format zu ändern, wird das Datum möglicherweise nicht auf Ihre Zeitzone eingestellt. Dies kann zu unerwarteten Ergebnissen führen.

var input = $('#date_input').val();  //input: 2020-08-12
var date = new Date(input);          //This get interpreted as an ISO date, already in UTC
//date:                             Tue Aug 11 2020 20:00:00 GMT-0400 (Eastern Daylight Time)
//date.toUTCString():               Wed, 12 Aug 2020 00:00:00 GMT
//date.toLocaleDateString('en-US'):       8/11/2020

Wenn Sie ein anderes Datumsformat als den ISO-Standard yyyy-mm-dd verwenden, wird Ihre Zeitzone auf das Datum angewendet.

var date = new Date("08/12/2020");  //This gets interpreted as local timezone
//date:                             Wed Aug 12 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
//date.toUTCString():               Wed, 12 Aug 2020 04:00:00 GMT
//date.toLocaleDateString('en-US'):       8/12/2020

Lösung:

Um Ihre Zeitzone auf das formatunabhängige Datum anzuwenden, ohne eine Stringmanipulation vorzunehmen, verwenden Sie Date.getTimezoneOffset() mit Protokollen. Dies funktioniert entweder mit dem ursprünglichen Format der Datumszeichenfolge (d.h. UTC-Daten oder lokalisierte Daten). Es liefert ein konsistentes Ergebnis, das dann zur Speicherung oder zur Interaktion mit anderem Code genau in UTC konvertiert werden kann.

var input = $('#date_input').val();
var date = new Date(input);
date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
//date:                             Wed Aug 12 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
//date.toUTCString():               Wed, 12 Aug 2020 04:00:00 GMT
//date.toLocaleDateString('en-US'):       8/12/2020

2voto

NBjerre Punkte 111

Wenn ich ein Datumsobjekt erstelle:

new Date(year, month, day, hour, minute)

Auf localhost funktioniert es gut. Wenn ich es auf dem Server bereitstelle bricht , weil der Server in einer anderen Zeitzone liegt.

Ich kann getTimezoneOffset() nicht verwenden. Ich brauche die timezoneOffset meines Wohnortes - abhängig von Sommerzeit / Winterzeit

// add diff minutes between myself (HOME) and server 
timezoneHomeOffset (d, tz = 'Europe/Copenhagen') {
  const utc = new Date(d.getTime())
  const dHome = new Date(d.toLocaleString('en-US', { timeZone: tz }))
  const diff = Math.round((utc - dHome) / 60000) // 60*1000 => minutes
  d.setMinutes(d.getMinutes() + diff)
  return d
}

2voto

Kyle Baker Punkte 2938

Es ist eigentlich gar nicht so schwer, dies zu tun, aber es ist sicherlich nicht intuitiv, die Lösung zu finden. Es gibt einige wirklich verworrene Antworten hier (obwohl auch einige schöne). Hier ist, was ich mir ausgedacht habe, um sicherzustellen, dass meine Server-Zeitstempel mit meinen lokalen Zeitstempeln übereinstimmen, egal in welcher Zeitzone sich mein bereitgestellter Server befindet.

(MEZ = Mitteleuropäische Zeitzone, die zufällig meine persönliche Zeitzone ist; Sie können den Offset einer beliebigen Zeitzone ermitteln und berechnen und sogar als Argument verwenden, wenn Sie möchten, aber für meinen Zweck musste ich nur meine Daten in die gewünschte einheitliche Zeitzone bringen).

    const convertDateToCET = function(date) {
        date = new Date(date)
        // let startTime = date.getTime();
        const cetOffset = -120; // this is the number you get from running 
        // `(new Date()).getTimezoneOffset()` if you're on a machine in CET
        const offsetFromCET = (date.getTimezoneOffset() - cetOffset);
        const cetMillsecondOffset = ( cetOffset* 60 * 1000);
        date = new Date( date.getTime() - cetMillsecondOffset ) 
        // let endTime = date.getTime()
        // console.log("updated date from",startTime,"to",endTime)
        return date;
    },

Damit stellen Sie einfach eine Zeit ein, wie Sie es erwarten würden, z. B.

    let myDate = new Date("12-4-2021")
    myDate.setHour(14)
    myDate.setMinute(30)
    // now myDate is 2:30pm, December 4th, 2021, in whatever the timezone the machine of code running happens to be in
    myDate = convertDateToCET(myDate)
    // now myDate will show up as 2:30pm, Dec 4th, 2021, mapped into your local timezone
    // so, if you're in the UK, and one hour behind CET, myDate is now 1:30pm, Dec 4th, 2021

Der Schlüssel dazu ist date.getTimezoneOffset() . Wenn Sie tatsächlich in der Weiterbildung sind, wird diese Zahl sein -120 und hebt sich somit auf, so dass es keinen Unterschied macht (CET ergibt also CET out). Wenn Sie sich im Vereinigten Königreich befinden, eine Stunde hinter der MEZ, würde die Ausgabe lauten -60 was bedeutet -60 + 120 = +60 was dazu führt, dass wir die Eingabezeit um eine Stunde ändern, und so weiter .

In einem solchen Fall wäre es wahrscheinlich sinnvoller, alles in UTC zu konvertieren und zu verwenden, aber da meine gesamte Eingabezeit in MEZ ist und ich das System ursprünglich auf der Grundlage der lokalen Gegebenheiten auf meinem Rechner entwickelt hatte, konnte ich mit diesem Dienstprogramm den vorhandenen Code konvertieren, indem ich diese Funktion an einigen wichtigen Stellen aufrief.

Vorsicht! Achten Sie darauf, dass Sie diesen Funktionsaufruf nicht mehrmals am selben Tag anwenden, da Sie sonst den Offset mehrfach anwenden, was ihn verfälscht!

0 Stimmen

Ich finde diese Lösung wirklich gut, obwohl ich auf ein großes Problem gestoßen bin: die Sommerzeit. Das bedeutet, dass sich mein Offset im Frühjahr und Herbst ändert.

0 Stimmen

Ich habe seit über einem Jahr nicht mehr über diesen Code nachgedacht, und es war für ein Projekt, das damals nur einen Monat dauern sollte - ein guter Fang! Sind Sie sicher, dass es nicht automatisch gehandhabt werden würde, obwohl? Es scheint so, als ob das hier implizit nach Bedarf gehandhabt wird, wenn ich das nicht falsch verstehe: stackoverflow.com/questions/11887934/

1voto

Jeffrey L. Roberts Punkte 2635

Die beste Lösung, die ich in diesem Zusammenhang gesehen habe, stammt von

http://www.codingforums.com/archive/index.php/t-19663.html

Funktion Zeit drucken

<script language="javascript" type="text/javascript">
//borrowed from echoecho
//http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482
workDate = new Date()
UTCDate = new Date()
UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000)

function printTime(offset) {
    offset++;
    tempDate = new Date()
    tempDate.setTime(UTCDate.getTime()+3600000*(offset))
    timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours()))
    timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes())
    timeValue += " hrs."
    return timeValue
    }
    var now = new Date()
    var seed = now.getTime() % 0xfffffff
    var same = rand(12)
</script>

Banff, Canada:
<script language="JavaScript">document.write(printTime("-7"))</script>

Vollständiges Code-Beispiel

<html>

<head>
<script language="javascript" type="text/javascript">
//borrowed from echoecho
//http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482
workDate = new Date()
UTCDate = new Date()
UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000)

function printTime(offset) {
offset++;
tempDate = new Date()
tempDate.setTime(UTCDate.getTime()+3600000*(offset))
timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours()))
timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes())
timeValue += " hrs."
return timeValue
}
var now = new Date()
var seed = now.getTime() % 0xfffffff
var same = rand(12)
</script>

</head>

<body>
Banff, Canada:
<script language="JavaScript">document.write(printTime("-7"))</script>
<br>
Michigan:
<script language="JavaScript">document.write(printTime("-5"))</script>
<br>
Greenwich, England(UTC):
<script language="JavaScript">document.write(printTime("-0"))</script>
<br>
Tokyo, Japan:
<script language="JavaScript">document.write(printTime("+9"))</script>
<br>
Berlin, Germany:
<script language="JavaScript">document.write(printTime("+1"))</script>

</body>
</html>

0 Stimmen

Ihr Beispiel schließt die Sommerzeit aus. AktuelleZeit: Fri Oct 04 2013 11:13:43 GMT-0700 (Pacific Daylight Time) UtcTime: Fri, 04 Oct 2013 18:13:43 GMT Banff, Kanada: 1213 Uhr. Michigan: 1413 Uhr Greenwich, England(UTC): 1913 Uhr. Tokio, Japan: 0413 Uhr. Berlin, Deutschland: 2013 Uhr.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X