Wie erhalte ich einen UTC-Zeitstempel in JavaScript?

157

Beim Schreiben einer Webanwendung ist es sinnvoll, ( datenseitig ) alle Datenzeiten in der Datenbank als UTC-Zeitstempel zu speichern .

Ich war erstaunt, als ich bemerkte, dass man in Bezug auf die Zeitzonenmanipulation in JavaScript nicht viel von Haus aus tun konnte.

Ich habe das Date-Objekt ein wenig erweitert. Ist diese Funktion sinnvoll? Grundsätzlich wird jedes Mal, wenn ich etwas an den Server sende, ein Zeitstempel mit dieser Funktion formatiert ...

Können Sie hier größere Probleme sehen? Oder vielleicht eine Lösung aus einem anderen Blickwinkel?

Date.prototype.getUTCTime = function(){ 
  return new Date(
    this.getUTCFullYear(),
    this.getUTCMonth(),
    this.getUTCDate(),
    this.getUTCHours(),
    this.getUTCMinutes(), 
    this.getUTCSeconds()
  ).getTime(); 
}

Es scheint mir nur ein wenig verworren zu sein. Und ich bin mir auch bei der Leistung nicht so sicher.

Merc
quelle
Ich weiß, dass dies eine alte Frage ist, aber versuchen Sie nicht, native Objekte wie das Date-Objekt zu erweitern. Upvoted, weil mir die Frage selbst gefällt.
Trysis
Date.parse (neues Datum (). ToUTCString ())
Sagi
25
Dies ist eine alte Frage, die heute in meinem Feed auftauchte und voller Fehlinformationen ist. Der Zeitstempel ist immer in UTC. new Date().toString()zeigt Ihnen die aktuelle Zeitzonen- new Date().toUTCString()Zeitdarstellung an, zeigt Ihnen die UTC-Zeitrepräsentation an, new Date().getTime()ist jedoch immer UTC , da die Unix-Zeit wie folgt definiert ist: "Die Unix-Zeit (auch als POSIX-Zeit oder Epochenzeit bezeichnet) ist ein System zur Beschreibung von Zeitpunkten in der Zeit, definiert als die Anzahl der Sekunden, die seit 00:00:00 Coordinated Universal Time (UTC), Donnerstag, 1. Januar 1970, vergangen sind, ohne Schaltsekunden. "
Amadan

Antworten:

155
  1. Auf diese Weise erstellte Daten verwenden die lokale Zeitzone, wodurch das erstellte Datum falsch wird. Um die Zeitzone eines bestimmten Datumsobjekts festzulegen, müssen Sie es aus einer Datumszeichenfolge erstellen, die die Zeitzone enthält. (Ich hatte Probleme, das in einem älteren Android-Browser zum Laufen zu bringen.)

  2. Beachten Sie, dass getTime()Millisekunden und keine einfachen Sekunden zurückgegeben werden.

Für einen UTC / Unix-Zeitstempel sollte Folgendes ausreichen:

Math.floor((new Date()).getTime() / 1000)

Der aktuelle Zeitzonenversatz wird in das Ergebnis einbezogen. Für eine Zeichenfolgendarstellung funktioniert die Antwort von David Ellis .

Zu klären:

new Date(Y, M, D, h, m, s)

Diese Eingabe wird als Ortszeit behandelt . Wenn die UTC-Zeit abgelaufen ist, unterscheiden sich die Ergebnisse. Beobachten Sie (ich bin gerade in GMT +02: 00 und es ist 07:50):

> var d1 = new Date();
> d1.toUTCString();
"Sun, 18 Mar 2012 05:50:34 GMT" // two hours less than my local time
> Math.floor(d1.getTime()/ 1000)
1332049834 

> var d2 = new Date( d1.getUTCFullYear(), d1.getUTCMonth(), d1.getUTCDate(), d1.getUTCHours(), d1.getUTCMinutes(), d1.getUTCSeconds() );
> d2.toUTCString();
"Sun, 18 Mar 2012 03:50:34 GMT" // four hours less than my local time, and two hours less than the original time - because my GMT+2 input was interpreted as GMT+0!
> Math.floor(d2.getTime()/ 1000)
1332042634

Beachten Sie auch, dass getUTCDate()dies nicht ersetzt werden kann getUTCDay(). Dies liegt daran , getUTCDate()kehrt der Tag des Monats ; während, getUTCDay()gibt den Tag der Woche .

DCoder
quelle
1
1) Ich habe kein Datum erstellt ... Ich habe eine Prototypfunktion hinzugefügt, die daran funktioniert hat . 2) Guter Punkt, ich sollte Math.floor / 1000 ausführen - aber ich würde diese Funktion trotzdem benötigen, um den UTC-Zeitstempel eines vorhandenen Datumsobjekts zu haben ... richtig?
Merc
@Merc: 1) Sie rufen an new Date(), das erstellt ein neues Datum aus Ihrer UTC-Eingabe, behandelt es jedoch als lokales Datum / Uhrzeit. 2) Ja, Sie sollten Math.floor(this.getTime() / 1000)in diesem Fall verwenden.
DCoder
Hier antworten, da ich den Code aktualisieren muss ... Dies ist, um den Unix-Zeitstempel in UTC für ein vorhandenes Datum zu haben: function () {return Math.floor (neues Datum (this.getUTCFullYear (), this.getUTCMonth (), this.getUTCDate (), this.getUTCHours (), this.getUTCMinutes (), this.getUTCSeconds ()) .getTime () / 1000); } Dies bedeutet, dass ich Folgendes tun kann: var n = neues Datum (2008,10,10) ... ... n.getUTCTime (); (Dies wird anders sein als n.getUTCTime ())
Merc
1
Danke Bro Seine Arbeitsdatei Math.floor ((neues Datum ()). GetTime () / 1000)
Manoj Patel
51

Sie können dies auch mit getTimezoneOffset und getTime tun.

x = new Date()
var UTCseconds = (x.getTime() + x.getTimezoneOffset()*60*1000)/1000;

console.log("UTCseconds", UTCseconds)

Shiplu Mokaddim
quelle
4
Danke, das ist im Internet nirgends zu finden!
Theofanis Pantelides
Ich teste folgende Codes : var tt = new Date('Thu Jan 01 1970 08:00:00 GMT+0800 (China Standard Time)'); (tt.getTime() - tt.getTimezoneOffset()*60*1000)/1000. Es scheint tt.getTime() - tt.getTimezoneOffset()richtig für GMT+0800.
Zangw
1
Das ist besservar UTCseconds = (Math.floor(x.getTime()/1000) + x.getTimezoneOffset()*60)
StefansArya
Es sieht aus wie diese Arbeit nicht , wie geschrieben hat .. Es sieht aus wie Sie in der Zeit Zeichenfolge passieren müssen in , new Date()dass ein timezone..which enthält irgendwie besiegt den Zweck zu versuchen , es in js zu tun ..
claudekennilol
Das ist einfach falsch, wird der Wert zugewiesen UTCseconds ist nicht UTC Sekunden .. Ein Datum Wert Zeit ist UTC, es durch eine Änderung Egal welche Methode Mittel es einen anderen Moment in der Zeit darstellt.
RobG
34

Der einfachste Weg, UTC-Zeit in einem herkömmlichen Format zu erhalten, ist wie folgt:

new Date().toISOString()
"2016-06-03T23:15:33.008Z"
Tahsin Turkoz
quelle
3
Dies ist die richtige Antwort. Viele andere Antworten geben eine "universelle Zeitzeichenfolge" an, aber nicht die aktuelle "universelle koordinierte Zeit". Ich verstehe nicht, warum hier alles so kompliziert ist.
Gburton
Vielen Dank, dass Sie @gburton. Schätzen Sie, dass Sie den einfachen Weg zur Wahrheit sehen. :)
Tahsin Turkoz
1
Ich verwende dies zusammen mit ".split ('T') [0]" für einfache datumsbasierte Vergleiche von JJJJ-MM-TT.
Sean O
Schön, @ SeanO
Tahsin Turkoz
Dies liefert eine UTC-Zeitzeichenfolge, aber OP fragt nach einem UTC- Zeitstempel (Epoche)
Jordi Nebot
13

Ich denke tatsächlich, dass Datumswerte in js weitaus besser sind als die C # DateTime-Objekte. Die C # DateTime-Objekte haben eine Kind-Eigenschaft, aber keine strikte zugrunde liegende Zeitzone als solche, und Zeitzonenkonvertierungen sind schwer zu verfolgen, wenn Sie zwischen zwei Nicht-UTC- und Nicht-Ortszeiten konvertieren. In js haben alle Datumswerte einen zugrunde liegenden UTC-Wert, der unabhängig von den von Ihnen durchgeführten Offest- oder Zeitzonen-Konvertierungen weitergegeben und bekannt ist. Meine größte Beschwerde bezüglich des Date-Objekts ist die Menge an undefiniertem Verhalten, die Browser-Implementierer ausgewählt haben, was Personen, die Datumsangaben in js angreifen, mit Versuch und Irrtum verwirren kann, als die Spezifikation zu lesen. Die Verwendung von iso8601.js löst dieses unterschiedliche Verhalten, indem eine einzelne Implementierung des Date-Objekts definiert wird.

Standardmäßig heißt es in der Spezifikation, dass Sie Datumsangaben mit einem erweiterten ISO 8601-Datumsformat wie erstellen können

var someDate = new Date('2010-12-12T12:00Z');

Auf diese Weise können Sie die genaue UTC-Zeit ableiten.

Wenn Sie den Datumswert an den Server zurückgeben möchten, den Sie aufrufen würden

someDate.toISOString();

oder wenn Sie lieber mit einem Millisekunden-Zeitstempel arbeiten möchten (Anzahl der Millisekunden ab dem 1. Januar 1970 UTC)

someDate.getTime();

ISO 8601 ist ein Standard. Sie können nicht verwechselt werden, was eine Datumszeichenfolge bedeutet, wenn Sie den Datumsversatz einschließen. Für Sie als Entwickler bedeutet dies, dass Sie sich nie selbst mit lokalen Zeitumrechnungen befassen müssen . Die lokalen Zeitwerte dienen ausschließlich dem Benutzer und Datumswerte werden standardmäßig in ihrer lokalen Zeit angezeigt. Bei allen lokalen Zeitmanipulationen können Sie dem Benutzer etwas Sinnvolles anzeigen und Zeichenfolgen aus Benutzereingaben konvertieren. Es wird empfohlen, so schnell wie möglich in UTC zu konvertieren, und das Objekt js Date macht dies ziemlich trivial.

Auf der anderen Seite gibt es nicht viel Spielraum, um die Zeitzone oder das Gebietsschema für den Client zu erzwingen (was mir bekannt ist), was für website-spezifische Einstellungen ärgerlich sein kann, aber ich denke, der Grund dafür ist, dass es sich um einen Benutzer handelt Konfiguration, die nicht berührt werden sollte.

Kurz gesagt, der Grund, warum es nicht viel native Unterstützung für die Zeitzonenmanipulation gibt, ist, dass Sie es einfach nicht tun möchten.

Matt Esch
quelle
12

Im Allgemeinen müssen Sie auf der Clientseite nicht viel von "Zeitzonenmanipulation" ausführen. In der Regel versuche ich, UTC-Daten in Form von ticksoder " Anzahl Millisekunden seit Mitternacht des 1. Januar 1970 " zu speichern und damit zu arbeiten . Dies vereinfacht das Speichern, Sortieren und Berechnen von Offsets erheblich und befreit Sie vor allem von den Kopfschmerzen bei den Anpassungen der "Sommerzeit". Hier ist ein kleiner JavaScript-Code, den ich verwende.

So erhalten Sie die aktuelle UTC-Zeit:

function getCurrentTimeUTC()
{
    //RETURN:
    //      = number of milliseconds between current UTC time and midnight of January 1, 1970
    var tmLoc = new Date();
    //The offset is in minutes -- convert it to ms
    return tmLoc.getTime() + tmLoc.getTimezoneOffset() * 60000;
}

Dann müssen Sie im Allgemeinen Datum / Uhrzeit für den Endbenutzer für die lokale Zeitzone und das Format formatieren. Im Folgenden werden alle Komplexitäten der Datums- und Uhrzeitformate auf dem Clientcomputer berücksichtigt:

function formatDateTimeFromTicks(nTicks)
{
    //'nTicks' = number of milliseconds since midnight of January 1, 1970
    //RETURN:
    //      = Formatted date/time
    return new Date(nTicks).toLocaleString();
}

function formatDateFromTicks(nTicks)
{
    //'nTicks' = number of milliseconds since midnight of January 1, 1970
    //RETURN:
    //      = Formatted date
    return new Date(nTicks).toLocaleDateString();
}

function formatTimeFromTicks(nTicks)
{
    //'nTicks' = number of milliseconds since midnight of January 1, 1970
    //RETURN:
    //      = Formatted time
    return new Date(nTicks).toLocaleTimeString();
}

Also folgendes Beispiel:

var ticks = getCurrentTimeUTC();  //Or get it from the server

var __s = "ticks=" + ticks + 
    ", DateTime=" + formatDateTimeFromTicks(ticks) +
    ", Date=" + formatDateFromTicks(ticks) +
    ", Time=" + formatTimeFromTicks(ticks);

document.write("<span>" + __s + "</span>");

Gibt Folgendes zurück (für mein Gebietsschema in US-Englisch):

ticks = 1409103400661, DateTime = 8/26/2014 6:36:40 PM, Date = 8/26/2014, Time = 6: 36: 40 PM

ahmd0
quelle
1
Indem Sie den getTimezoneOffsetWert in Ihrer getCurrentTimeUTCFunktion hinzufügen , geben Sie tatsächlich einen anderen Zeitpunkt zurück. Das Ergebnis von getTimeist bereits in UTC.
Matt Johnson-Pint
1
@ MattJohnson: Das ist falsch. Das Ergebnis von tmLoc.getTime()ist ein Versatz gegen die Ortszeit. Das ist einfach zu überprüfen, ob Sie Zugriff auf etwas haben, auf dem JavaScript ausgeführt wird.
ahmd0
2
Entschuldigung, aber das stimmt nicht. Siehe die MDN-Referenz . Sie können dies auch in der ECMAScript-Spezifikation sehen. §15.9.3.3 beschreibtgetTime , welcher Punkt Sie auf den in §15.9.5 definierten "Zeitwert" verweist , der a ist PrimitiveValue, wie in §15.9.3.3 explizit als UTC festgelegt.
Matt Johnson-Pint
2
Nun, da Sie tmLocüber erhalten new Date(), ist es das gleiche. Die Zeitzone wirkt sich auf die Zeichenfolgenausgabe tmLoc.toString()und ähnliche Elemente aus, jedoch nicht auf tmLoc.getTime() die Anzahl der Millisekunden seit Mitternacht 1970-01-01 in UTC.
Matt Johnson-Pint
1
@ StefansArya://The offset is in minutes -- convert it to ms
ahmd0
5

Ich denke, das ist eine bessere Lösung

// UTC milliseconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()

// UTC seconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()/1000|0
Koalex
quelle
Eine weitere falsche Antwort: getTime gibt einen UTC-Offset zurück, und das Hinzufügen des lokalen Zeitzonen-Offsets bringt ihn völlig durcheinander. Die ECMAScript-Offsets sind + ve für West und -ve für Ost, daher sollten sie von UTC subtrahiert werden, um lokal zu werden. Da der Zeitwert jedoch zunächst UTC ist, wird er durch Hinzufügen im Wesentlichen von UTC in die entgegengesetzte Richtung zum lokalen Versatz verschoben.
RobG
4

Wenn Sie einen Einzeiler wünschen , kann der UTC-Unix-Zeitstempel in JavaScript wie folgt erstellt werden:

var currentUnixTimestap = ~~(+new Date() / 1000);

Dies berücksichtigt die Zeitzone des Systems. Es ist im Grunde die Zeit, die seit der Epoche in Sekunden vergangen ist.

Wie es funktioniert:

  • Datumsobjekt erstellen : new Date().
  • Konvertieren Sie in einen Zeitstempel, indem Sie ihn unary +vor der Objekterstellung hinzufügen, in den Sie ihn konvertieren möchten timestamp integer. : +new Date().
  • Millisekunden in Sekunden umrechnen: +new Date() / 1000
  • Verwenden Sie doppelte Tildes , um den Wert auf eine Ganzzahl abzurunden. ::~~(+new Date())
Kushal Likhi
quelle
7
es ist tildenicht tilda(sic). Leider kann ich keinen Tippfehler entfernen, ich muss mindestens 6 Zeichen bearbeiten. Glatt, Stapelaustausch, glatt
Fred
3
Verwenden Sie dies nicht . Mit der aktuellen ecma-Spezifikation verarbeiten bitweise Operationen (wie die Tilde - bitweise nicht) vorzeichenbehaftete Ganzzahlwerte von 32 Bit. Das bedeutet, dass diese Tilde-Magie nach dem 19. Januar 2038 nicht mehr funktioniert, wenn der Zeitstempelwert über dem Maximalwert einer 32-Bit-Ganzzahl mit Vorzeichen liegt. jsfiddle.net/phb20ymb
Sharky
3

Ich möchte klarstellen, dass new Date (). GetTime () tatsächlich einen UTC-Wert zurückgibt. Daher ist es eine sehr hilfreiche Methode, Datumsangaben auf eine Weise zu speichern und zu verwalten, die für lokalisierte Zeiten unabhängig ist.

Mit anderen Worten, kümmern Sie sich nicht um alle UTC-Javascript-Funktionen. Verwenden Sie stattdessen einfach Date.getTime ().

Weitere Informationen zur Erklärung finden Sie hier: Wenn Javascript "(new Date ()). GetTime ()" aus 2 verschiedenen Zeitzonen ausgeführt wird.

Stan Lin
quelle
3

Ich benutze folgendes:

Date.prototype.getUTCTime = function(){ 
  return this.getTime()-(this.getTimezoneOffset()*60000); 
};

Sobald Sie diese Methode definiert haben, können Sie Folgendes tun:

var utcTime = new Date().getUTCTime();
jlbofh
quelle
Sauberste Lösung. VIELEN DANK!
avalanche1
Dies ist jedoch keine saubere Lösung zum Senden von Daten, da TimeStamps immer UTC sind. Die beste Lösung für mich beim Senden von Daten besteht darin, eine Zeichenfolgendarstellung wie "TT / MM / JJJJ HH: MM: SS" zu verwenden und diese dann auf der Serverseite mit der Standard-Zeitzone des Servers zu analysieren, um einen UTC-Zeitstempel oder was auch immer zu erhalten. Siehe diese Antwort
jlbofh
2
einen String analysieren - das nennst du sauber? meh
avalanche1
Stellen Sie sicher, dass es Methoden gibt, um ein Datum im Zeichenfolgenformat gemäß den ISO-Spezifikationen zu generieren. Die Methode ist toISOString (). Sie können es sauber in Java analysieren, indem Sie DateTime dt = new DateTime ("2018-07-15T02:36:00+02:00");
Folgendes verwenden
Eine andere falsche Antwort this.getTime()gibt einen UTC-Versatz zurück. Wenn Sie den lokalen Zeitzonenversatz subtrahieren, wird dieser lokal und nicht UTC. GetUTCTime gibt also einen lokalen Versatz zurück, nicht UTC.
RobG
2

Ich bin erstaunt, wie komplex diese Frage geworden ist.

Diese sind alle identisch und ihre ganzzahligen Werte alle === EPOCH-Zeit: D.

console.log((new Date()).getTime() / 1000, new Date().valueOf() / 1000, (new Date() - new Date().getTimezoneOffset() * 60 * 1000) / 1000);

Glauben Sie mir nicht, Kasse: http://www.epochconverter.com/

Fliptopbox
quelle
2

Da new Date().toUTCString()gibt eine Zeichenfolge zurück, wie "Wed, 11 Oct 2017 09:24:41 GMT"Sie die letzten 3 Zeichen in Scheiben schneiden und die in Scheiben geschnittene Zeichenfolge an new Date()folgende Adresse übergeben können :

new Date()
// Wed Oct 11 2017 11:34:33 GMT+0200 (CEST)

new Date(new Date().toUTCString().slice(0, -3))
// Wed Oct 11 2017 09:34:33 GMT+0200 (CEST)
Maurice Wipf
quelle
1

BEARBEITEN: Der folgende Code funktioniert NICHT. Ich ging immer davon aus, dass new Date (). GetTime () die Anzahl der Sekunden seit dem 1. Januar 1970 in der aktuellen Zeitzone zurückgibt. Dies ist nicht der Fall: getTime () gibt die Anzahl der Sekunden in UTC zurück. Der folgende Code führt also eine grobe Überanpassung durch. Dank euch allen!]

Zunächst einmal vielen Dank für Ihre fantastischen Einblicke. Ich denke, meine Frage hatte den falschen Titel ... es hätte lauten sollen "Holen Sie sich den UTC-Unix-Zeitstempel für ein vorhandenes Datum".

Also, wenn ich ein Datumsobjekt habe:

var d = new Date(2009,01,31)

Ich war nach einer Funktion, die mir "The UTC Unix Timestamp" sagen würde.

Diese Funktion scheint der wahre Trick zu sein:

Date.prototype.getUTCUnixTime =  function (){
  return Math.floor( new Date(
    this.getUTCFullYear(),
    this.getUTCMonth(),
    this.getUTCDate(),
    this.getUTCHours(),
    this.getUTCMinutes(), 
    this.getUTCSeconds()
  ).getTime() / 1000); 
}

Beachten Sie, dass es auf "this" funktioniert. Dies bedeutet, dass ich Folgendes tun kann:

var n = new Date(2008,10,10)
...
...

n.getUTCUnixTime();

Und erhalten Sie die Anzahl der Sekunden seit dem 1. Januar 1970 in Unix-Zeit. Richtig?

Für mich ist es ein bisschen verrückt, dass Javascript alles in UTC-Zeiten speichert, aber um diese Nummer zu erhalten, muss ich ein neues Date-Objekt erstellen, das die einzelnen UTC-Getter übergibt, und schließlich getTime () dafür aufrufen ...

Merc.

Merc
quelle
1
Hast du @ DCoders Update zu seiner Antwort gesehen? Ihre Methode getUTCUnixTimeerhält die falsche Zeit, und JavaScript bietet eine einfache Möglichkeit, den Unix-Zeitstempel Datemithilfe der getTimeMethode von einem Objekt abzurufen . Alle anderen Antworten anzeigen.
Anurag
1
Ugh du hast recht, habe sie gerade gesehen. (Kopf gegen Wand schlagen)
Merc
1

Ich denke das, was Sie erwarten ...

var currTimestamp = Date.now(), //1482905176396
    utcDateString = (new Date(currTimestamp)).toUTCString(); //"Wed, 28 Dec 2016 06:06:50 GMT"

Jetzt,

new Date(utcDateString).getTime(); //This will give you UTC Timestamp in JavaScript
Kapilrc
quelle
0

Sobald Sie dies tun

new Date(dateString).getTime() / 1000

Es ist bereits UTC Zeitstempel

   const getUnixTimeUtc = (dateString = new Date()) => Math.round(new Date(dateString).getTime() / 1000)

Ich habe auf https://www.unixtimestamp.com/index.php getestet

am fummeligsten
quelle
0

Mit day.js

Im Browser:

dayjs.extend(dayjs_plugin_utc)
console.log(dayjs.utc().unix())
<script src="https://cdn.jsdelivr.net/npm/dayjs@latest/dayjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dayjs@latest/plugin/utc.js"></script>

In node.js:

import dayjs from 'dayjs'
dayjs.extend(require('dayjs/plugin/utc'))
console.log(dayjs.utc().unix())

Sie erhalten einen UTC-Unix-Zeitstempel ohne Millisekunden.

Iljitsch
quelle
-2

Dies gibt den Zeitstempel in UTC zurück:

var utc = new Date(new Date().toUTCString()).getTime();

Yash Pandya
quelle
2
Dies gibt nicht die Zeit in UTC zurück: new Date(new Date().toUTCString())gibt Mi 04. Oktober 2017 07:20:14 GMT + 0200 (GMT + 02: 00)
Bas van Dijk