CURRENT_TIMESTAMP in Millisekunden


71

Gibt es eine Möglichkeit, Millisekunden aus einem Zeitstempel in MySqloder PostgreSql(oder anderen nur aus Neugier) herauszuholen?

SELECT CURRENT_TIMESTAMP
--> 2012-03-08 20:12:06.032572

Gibt es so etwas:

SELECT CURRENT_MILLISEC
--> 1331255526000

oder die einzige alternative ist die DATEDIFFaus dem era?


FROM_UNIXTIME (UNIX_TIMESTAMP (CONCAT (DATE (NOW ()), '', CURTIME (3))) erstellt einen Zeitstempel mit Millisekunden. Passen Sie den Parameter im Zeitlimit an, um die Anzahl der Dezimalstellen zu ändern.
user1119648

@ user1119648 - Welche Datenbank? CURTIME(3)Unterstützt keine DB auch NOW(3)? So CONCAT(DATE(NOW()), ' ', CURTIME(3))könnte es sein NOW(3), zumindest in MySQL 5.6.4+ auch, FROM_UNIXTIMEund UNIX_TIMESTAMPsind invers zueinander, so FROM_UNIXTIME( UNIX_TIMESTAMP( whatever ) )ergibt sich whatever. Ist dein langer Ausdruck nicht der gleiche wie NOW(3)?
ToolmakerSteve

Antworten:


42

So erhalten Sie den Unix-Zeitstempel in Sekunden in MySQL:

select UNIX_TIMESTAMP();

Details: http://dev.mysql.com/doc/refman/5.5/de/date-and-time-functions.html#function_unix-timestamp

Nicht getestet PostgreSQL, aber laut dieser Website sollte es funktionieren: http://www.raditha.com/postgres/timestamp.php

select round( date_part( 'epoch', now() ) );

30
Ist das nicht sekundengenau?
Matt Esch

1
Dies ist zum zweiten. Ich habe die Frage, die ich denke, falsch gelesen. Ich glaube nicht, dass MySQL Millisekunden zurückgibt, aber es sollte in der Lage sein, sie zu verarbeiten, wenn Sie sie bereitstellen: stackoverflow.com/questions/2572209/…
Billy Moon

In postgreSQL getestet, funktioniert, gibt jedoch einen gerundeten Wert in Sekunden anstelle eines millisekundengenauen Werts als bigint zurück. Siehe meine Antwort für die Lösung in postgreSQL: stackoverflow.com/a/28760763/3197383
Rémi Becheras

55

Für MySQL (5.6+) können Sie dies tun:

SELECT ROUND(UNIX_TIMESTAMP(CURTIME(4)) * 1000)

Welches wird zurückkehren (zB):

1420998416685 --milliseconds

1
In einer DST-Zeitzone unzuverlässig! (Falsch für eine Stunde jedes Jahr)
Doin

35

In MySQL ist es möglich, die UUID-Funktion zum Extrahieren von Millisekunden zu verwenden.

select conv( 
            concat(
                   substring(uid,16,3), 
                   substring(uid,10,4), 
                   substring(uid,1,8))
                   ,16,10) 
            div 10000 
            - (141427 * 24 * 60 * 60 * 1000) as current_mills
from (select uuid() uid) as alias;

Ergebnis:

+---------------+
| current_mills |
+---------------+
| 1410954031133 |
+---------------+

Es funktioniert auch in älteren MySQL-Versionen!

Vielen Dank an diese Seite: http://rpbouman.blogspot.com.es/2014/06/mysql-extracting-timstamp-and-mac.html


4
Zuerst habe ich gelacht, aber es ist der einzige Weg, den ich bisher gefunden habe, um die genaue Zeit in MySQL 5.5 zu ermitteln ... das ist also die Lösung :) Prost.
Elliot Chance

1
Wow - das ist großartig! Ich hoffe, dass sie dieses Verhalten nie beheben .
Billy Moon

Wenn Sie nur die MIKROSECONDS benötigen, können Sie SELECT SUBSTR( CONV( CONCAT( SUBSTR(uid,16,3), SUBSTR(uid,10,4), SUBSTR(uid,1,8)), 16, 10) DIV 10, -6) FROM (SELECT UUID() AS uid) AS alias;
Folgendes

13

Das Hauptmissverständnis in MySQL mit Zeitstempeln besteht darin, dass MySQL standardmäßig Zeitstempel ohne Bruchteil zurückgibt und speichert .

SELECT current_timestamp()  => 2018-01-18 12:05:34

die in Sekunden Zeitstempel als konvertiert werden kann

SELECT UNIX_TIMESTAMP(current_timestamp()) => 1516272429

So fügen Sie einen Bruchteil hinzu:

SELECT current_timestamp(3) => 2018-01-18 12:05:58.983

die in Mikrosekunden Zeitstempel als konvertiert werden kann

SELECT CAST( 1000*UNIX_TIMESTAMP(current_timestamp(3)) AS UNSIGNED INTEGER) ts => 1516272274786

Es gibt nur wenige Tricks beim Speichern in Tabellen. Wenn Ihre Tabelle wie erstellt wurde

    CREATE TABLE `ts_test_table` (
      `id` int(1) NOT NULL,
      `not_fractional_timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

als MySQL wird NICHT Bruchteil darin speichern:

    id, not_fractional_timestamp
    1,  2018-01-18 11:35:12

Wenn Sie Ihrer Tabelle einen Bruchteil hinzufügen möchten, müssen Sie Ihre Tabelle auf andere Weise erstellen:

    CREATE TABLE `ts_test_table2` (
      `id` int(1) NOT NULL,
      `some_data` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
      `fractional_timestamp` timestamp(3) NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

das führt zum gewünschten Ergebnis:

    id, some_data, fractional_timestamp
    1,  8,         2018-01-18 11:45:40.811

Die Funktion current_timestamp () darf Werte bis zu 6 empfangen, aber ich habe herausgefunden (zumindest in meiner unter Windows installierten MySQL 5.7.11-Version), dass die Bruchgenauigkeit 6 zu demselben konstanten Wert von 3 Stellen am Ende führt. in meinem Fall 688

    id, some_data, fractional_timestamp
    1,  2,         2018-01-18 12:01:54.167688
    2,  4,         2018-01-18 12:01:58.893688

Das bedeutet, dass die wirklich nutzbare Zeitstempelgenauigkeit von MySQL plattformabhängig ist:

  • unter Windows: 3
  • unter Linux: 6

12

In MySQL 5.7+ können Sie ausführen

select current_timestamp(6)

für mehr Details

https://dev.mysql.com/doc/refman/5.7/en/fractional-seconds.html


3
Hinweis: Dies war auch in MySQL 5.6.4 verfügbar: dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html Ist auch current_timestampein Synonym für now, now(6)ist also ein kürzerer Weg, um diesen Wert zu erhalten.
ToolmakerSteve

Dies funktioniert in Version 5.7.26 nicht. Es wird laufen, aber etwas wie "2019-06-24 12: 05: 50.931222"
letzte Schatten

8

Die richtige Methode zum Extrahieren von Millisekunden aus einem Zeitstempelwert in PostgreSQL gemäß der aktuellen Dokumentation ist:

SELECT date_part('milliseconds', current_timestamp);

--OR

SELECT EXTRACT(MILLISECONDS FROM current_timestamp);

mit Rückgabe: Das Sekundenfeld, einschließlich Bruchteilen, multipliziert mit 1000. Beachten Sie, dass dies volle Sekunden enthält.


Danke Falco, sorry, ich war nicht klar, aber ich brauchte tatsächlich den aktuellen Zeitstempel in Millisekunden. Siehe Beispiel
Marsellus Wallace

Ihre Lösung gibt die Anzahl der Millisekunden ab Tagesbeginn zurück, nicht ab dem 17.01.1970. Siehe meine Antwort für die Lösung in postgreSQL: stackoverflow.com/a/28760763/3197383
Rémi Becheras

7

Verwenden:

Select curtime(4);

Dies gibt Ihnen Millisekunden.


4
Stellen Sie außerdem sicher, dass die Spalte DATETIME die Länge 6 hat, in der diese gespeichert ist. Außerdem benötigen Sie MySQL 5.6.x, um mit Millisekunden arbeiten zu können.
TanuAD

1
Gibt '11: 08: 31.1845 ', enthält also nicht das Datum
Malhal

@malhal ist korrekt, gibt nicht die Anzahl der Millisekunden als die angeforderten Fragen an.
MCToon

In MySQL> 5.6 verwenden Sie - SELECT NOW (4);
TanuAD

6

Poster fragt nach einem ganzzahligen Wert von MS seit Epoche , nicht nach einer Zeit oder S seit Epoche.

Dazu müssen Sie verwenden NOW(3), was Ihnen Zeit in Bruchteilen von Sekunden auf 3 Dezimalstellen (dh MS-Genauigkeit) gibt: 2020-02-13 16: 30: 18.236

Dann UNIX_TIMESTAMP(NOW(3)), um die Zeit in Sekundenbruchteilen seit Epoc zu erhalten : 1581611418.236

Zum Schluss FLOOR(UNIX_TIMESTAMP(NOW(3))*1000)noch eine schöne runde Ganzzahl für ms seit epoc: 1581611418236

Machen Sie es zu einer MySQL-Funktion:

CREATE FUNCTION UNIX_MS() RETURN BIGINT DETERMINISTIC
BEGIN
    RETURN FLOOR(UNIX_TIMESTAMP(NOW(3))*1000);
END

Jetzt renn SELECT UNIX_MS();

Hinweis: Dies wurde alles von Hand kopiert. Wenn es also Fehler gibt, können Sie diese gerne beheben.


würde UNIX_TIMESTAMP () * 1000 nicht genauso gut funktionieren, da UNIX_TIMESTAMP () in Sekunden ist?
Brill Pappin

Sie könnten das tun, aber Sie verlieren die Granularität der letzten 3 Ziffern. Ihr Vorschlag fügt dem Ende des Zeitstempels nur 3 Nullen hinzu.
CompEng88

Ahh, ja natürlich! Das würde es in erster Linie so nützlich wie Sekunden machen.
Brill Pappin

Dies sollte die richtige Antwort auf die eigentliche Frage sein.
Brill Pappin

4

In PostgreSQL können Sie Folgendes verwenden:

SELECT extract(epoch from now());

auf MySQL:

SELECT unix_timestamp(now());

6
Unter MySQL ist das nur auf die Sekunde genau, nicht auf die Millisekunde.
Jeffrey Van Alstine

In postgreSQL gibt Ihre Lösung den Unix-Zeitstempel in Bruchteilen von Sekunden zurück. Sehen Sie meine Antwort, um es in Millisekunden als bigint zu erhalten: stackoverflow.com/a/28760763/3197383
Rémi Becheras

Verwenden Sie niemals UNIX_TIMESTAMP () mit NOW (), da dies als Ortszeit behandelt wird und in der letzten Stunde der Sommerzeit fehlschlägt!
Bazardshoxer

4

Keine dieser Antworten löst das Problem in postgreSQL wirklich , dh:

Abrufen des Unix-Zeitstempels eines Datumsfelds in Millisekunden

Ich hatte das gleiche Problem und testete die verschiedenen vorherigen Antworten ohne zufriedenstellendes Ergebnis.

Schließlich fand ich einen wirklich einfachen Weg, wahrscheinlich den einfachsten:

SELECT (EXTRACT (EPOCH FROM <date_column>::timestamp)::float*1000 as unix_tms
FROM <table>

nämlich:

  • Wir extrahieren den pgSQL EPOCH , dh den Unix-Zeitstempel in schwebenden Sekunden aus unserer Spalte, die in Zeitstempel-Vorsicht umgewandelt wurde (in einigen komplexen Abfragen kann pgSQL einen Fehler auslösen, wenn diese Umwandlung nicht explizit ist. Siehe)
  • Dann wandeln wir es in float und multiplizieren es mit 1000, um den Wert in Millisekunden zu erhalten

3

Hier ist ein Ausdruck, der für MariaDB und MySQL funktioniert> = 5.6:

SELECT (UNIX_TIMESTAMP(NOW()) * 1000000 + MICROSECOND(NOW(6))) AS unix_now_in_microseconds;

Dies beruht auf der Tatsache, dass NOW () während einer Abfrage immer dieselbe Zeit zurückgibt . Es ist möglich, dass eine Ebene UNIX_TIMESTAMP()auch funktioniert. Ich bin mir aufgrund der Dokumentation nicht sicher . Für das neue Genauigkeitsargument für die NOW()Funktion ist außerdem MySQL> = 5.6 erforderlich (MariaDB funktioniert auch).


1
UNIX_TIMESTAMP(NOW())wird am Ende der Sommerzeit für eine Stunde falsch sein, wenn Sie sich in einer Sommerzeitzone befinden. Verwenden Sie UNIX_TIMESTAMP()stattdessen einfach und die Antwort funktioniert, obwohl ich nicht 100% sicher bin, was während der Schaltsekunden passiert.
Doin

3

Der einfachste Weg, die aktuelle Zeit in Millisekunden in MySql zu erhalten:

SELECT (UNIX_TIMESTAMP(NOW(3)) * 1000)

Seit MySql 5.6.


1
Wer hat herabgestimmt, was ist mit dieser Antwort falsch? Soweit ich das beurteilen kann, funktioniert es. Beachten Sie jedoch, dass .000anstelle einer Ganzzahl eine Dezimalzahl zurückgegeben wird .
Benjamin

Gibt falsche Ergebnisse am Ende der Sommerzeit, wenn in einer Sommerzeitzone!
Doin

2

In MariaDB können Sie verwenden

SELECT NOW(4);

Milisecs bekommen. Siehe auch hier .


1

Für MySQL:

SELECT (UNIX_TIMESTAMP() * 1000) AS unix_now_in_microseconds; --- 1600698677000

0

Ich hatte das Bedürfnis, weiter zu verfeinern, also in MySQL:

Aktueller Zeitstempel in Millisekunden:

floor(unix_timestamp(current_timestamp(3)) * 1000)

Zeitstempel in Millisekunden ab gegebener Datumszeit (3):

floor(unix_timestamp("2015-04-27 15:14:55.692") * 1000)

Zeitstempel in Millisekunden in Datum / Uhrzeit konvertieren (3):

from_unixtime(1430146422456 / 1000)

Konvertieren Sie datetime (3) in Millisekunden in einen Zeitstempel:

floor(unix_timestamp("2015-04-27 14:53:42.456") * 1000)

1
In einer Sommerzeitzone ist Ihr erstes Beispiel eine Stunde pro Jahr falsch (um eine Stunde). Besser zu bedienenUNIX_TIMESTAMP()*1000+FLOOR(MICROSECONDS(UTC_TIME(3))*0.001)
Doin

0

In PostgreSQL verwenden wir diesen Ansatz:

SELECT round(EXTRACT (EPOCH FROM now())::float*1000)

0

Für alle hier, hören / lesen Sie einfach die Kommentare von Doin sehr gut! Die UNIX_TIMESTAMP()Funktion kontaktiert, wenn eine Datenzeitzeichenfolge angegeben wird, eine Ortszeit basierend auf der Zeitzone der MySQL-Verbindung oder des Servers mit einem Unix-Zeitstempel. Wenn Sie sich in einer anderen Zeitzone befinden und eine Stunde pro Jahr mit Sommerzeit zu tun haben, wird dies schief gehen!

In den Niederlanden wird beispielsweise am letzten Sonntag im Oktober, eine Sekunde nach dem ersten Erreichen von 02:59:59, die Zeit wieder auf 02:00:00 zurückgesetzt. Wenn Sie die NOW(), CURTIME()oder SYSDATE()-Funktionen von MySQL verwenden und an die UNIX_TIMESTAMP()Funktion übergeben, sind die Zeitstempel für eine ganze Zeit falsch.

Am 27. Oktober 2018 in Satudray waren Zeit und Zeitstempel beispielsweise wie folgt:

Local time                        |  UTC Time                 |  Timestamp   |  Timestamp using MYSQL's UNIX_TIMESTAMP(NOW(4))
----------------------------------+---------------------------+--------------+-----------------------------------------------------
2018-10-27 01:59:59 CET (+02:00)  |  2018-10-26 23:59:59 UTC  |  1540598399  |  1540598399
2018-10-27 02:00:00 CET (+02:00)  |  2018-10-27 00:00:00 UTC  |  1540598400  |  1540598400 + 1 second
2018-10-27 02:59:59 CET (+02:00)  |  2018-10-27 00:59:59 UTC  |  1540601999  |  1540601999 
2018-10-27 03:00:00 CET (+02:00)  |  2018-10-27 01:00:00 UTC  |  1540602000  |  1540602000 + 1 second
2018-10-27 03:59:59 CET (+02:00)  |  2018-10-27 01:59:59 UTC  |  1540605599  |  1540605599
2018-10-27 04:00:00 CET (+02:00)  |  2018-10-27 02:00:00 UTC  |  1540605600  |  1540605600 + 1 second

Aber am Sonntag, den 27. Oktober 2019, wenn wir die Uhr um eine Stunde eingestellt haben. Da die Ortszeit keine Informationen darüber enthält, ob es sich um +02: 00 oder +01: 00 handelt, geben beide beim Konvertieren der Zeit 02:00:00 beim ersten und beim zweiten Mal denselben Zeitstempel an (ab dem zweiten 02:00) : 00) bei Verwendung der MYSQL- UNIX_TIMESTAMP(NOW(4))Funktion. Beim Überprüfen der Zeitstempel in der Datenbank wurde Folgendes ausgeführt: +1 +1 +3601 +1 +1 ... +1 +1 -3599 +1 +1 usw.

Local time                        |  UTC Time                 |  Timestamp   |  Timestamp using MYSQL's UNIX_TIMESTAMP(NOW(4))
----------------------------------+---------------------------+--------------+-----------------------------------------------------
2019-10-27 01:59:59 CET (+02:00)  |  2019-10-26 23:59:59 UTC  |  1572134399  |  1572134399
2019-10-27 02:00:00 CET (+02:00)  |  2019-10-27 00:00:00 UTC  |  1572134400  |  1572138000 + 3601 seconds
2019-10-27 02:59:59 CET (+02:00)  |  2019-10-27 00:59:59 UTC  |  1572137999  |  1572141599
2019-10-27 02:00:00 CET (+01:00)  |  2019-10-27 01:00:00 UTC  |  1572138000  |  1572138000 - 3599 seconds
2019-10-27 02:59:59 CET (+01:00)  |  2019-10-27 01:59:59 UTC  |  1572141599  |  1572141599
2019-10-27 03:00:00 CET (+01:00)  |  2019-10-27 02:00:00 UTC  |  1572141600  |  1572141600 + 1 second

Das Weiterleiten der UNIX_TIMESTAMP () - Funktion von MySQL beim Konvertieren von Ortszeiten ist leider sehr unzuverlässig! Anstatt zu verwenden SELECT UNIX_TIMESTAMP(NOW(4)), verwenden wir jetzt den folgenden Code, der das Problem löst.

SELECT ROUND(UNIX_TIMESTAMP() + (MICROSECOND(UTC_TIME(6))*0.000001), 4)

-1

Ich hatte kürzlich das gleiche Problem und habe ein kleines Github-Projekt erstellt, das eine neue MySQL-Funktion enthält UNIX_TIMESTAMP_MS() , die den aktuellen Zeitstempel in Millisekunden zurückgibt.

Sie können auch Folgendes tun:

SELECT UNIX_TIMESTAMP_MS(NOW(3)) oder SELECT UNIX_TIMESTAMP_MS(DateTimeField)

Das Projekt befindet sich hier: https://github.com/silviucpp/unix_timestamp_ms

Zum Kompilieren müssen Sie nur ausführen make compile im Projektstamm .

Dann müssen Sie nur die gemeinsam genutzte Bibliothek in die kopieren /usr/lib/mysql/plugin/ (oder einen beliebigen Plugin-Ordner auf Ihrem Computer) .

Öffnen Sie danach einfach eine MySQL-Konsole und führen Sie Folgendes aus:

CREATE FUNCTION UNIX_TIMESTAMP_MS RETURNS INT SONAME 'unix_timestamp_ms.so';

Ich hoffe das wird helfen, Silviu


Nach einer Refactoring-Runde gelingt es mir, weitaus bessere Leistungen zu erzielen als mit der eingebauten UNIX_TIMESTAMP-Funktion
silviu

Da Sie auf urheberrechtlich geschützten Code verlinken , klären Sie bitte die Lizenzbedingungen. Idealerweise durch Hinzufügen einer Lizenzdatei zu Ihrem Github-Repository. Siehe github.com/blog/1530-choosing-an-open-source-license
ToolmakerSteve

1
Funktioniert dies eher wie NOW () oder SYSDATE (), dh ist es über die Dauer einer Anweisung festgelegt, oder verwendet jeder Verweis darauf (z. B. beim Einfügen in mehrere Zeilen) einen aktuellen Wert?
Doin

Die Referenz existiert nicht.
g4ost

-1

Gehen Sie für Millisekunden wie folgt vor:

select round(date_format(CURTIME(3), "%f")/1000)

Sie können Mikrosekunden wie folgt erhalten:

select date_format(CURTIME(6), "%f")
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.