2015-08-04 8 views
5

Wir haben Daten als Unix-Zeitstempel gespeichert. Um es einem Benutzer zu ermöglichen, nach einem bestimmten Datum zu suchen - basierend auf seiner Zeitzoneneinstellung - haben wir diesen Zeitstempel innerhalb der Abfrage konvertiert, um sicherzustellen, dass bei einer Suche nach "2012-05-03" keine Ergebnisse des vorherigen/nächsten gefunden werden Tag abhängig davon, welche Zeitzone der Benutzer eingerichtet hat.MySQL von_Untimetime nach 2038-01-19?

Wenn ein Datum als 2012-05-03 23:00 (UTC) gespeichert wird, sollte ein Benutzer mit dem richtigen Zeitzonenversatz, der nach 2012-05-04 sucht, diesen Eintrag finden.

Dies wird wie folgt zur Zeit getan:

CONVERT_TZ(FROM_UNIXTIME(`javaTimeStampColumn`/1000),'+00:00','+00:00') 

wo OFC. Die Offsets werden abhängig von der Zeitzone des Benutzers festgelegt.

Das Problem, mit dem wir im Moment konfrontiert sind: Java speichert erfolgreich Daten nach dem Jahr 2038 als Unix-Timestamp. Die MySQL Verfahren from_unixtime jedoch unterstützt keine Umwandlung von Werten größer als 2147483647 aufgrund seiner Integer-Typ Einschränkung:

SELECT FROM_UNIXTIME(2147483647); //2038-01-19 04:14:07 

SELECT FROM_UNIXTIME(2147483648); //null 

Der MySQL Server selbst 64bit, aber OFC. FROM_UNIXTIME müsste lange als Argument akzeptieren.

Ich konnte jetzt keinen richtigen Ersatz finden, irgendwelche Hinweise?


Wir könnten Ofc. Laden Sie den Zeitstempel als Long und behandeln Sie es in der Anwendung - Aber für lazylaoding müssen wir in der Lage sein, es auch während der Abfrage korrekt zu konvertieren.

+0

Gibt es einen Grund, den Datentyp nicht in 'datetime' zu ​​ändern? –

+0

@juergend Ja, leider werden die Daten von einem Teil der Anwendung erzeugt, wo wir das nicht ändern können. (3rd Party Library) – dognose

+0

Haben Sie versucht, den Datentyp Ihrer Zeitstempelspalte in 'bigint' zu ändern? –

Antwort

4

könnten Eine Abhilfe sein DATE_ADD zu verwenden, aber ich bin mir nicht sicher, wie es leistungsmäßig verhält:

SELECT DATE_ADD(FROM_UNIXTIME(0), INTERVAL 2147483647 SECOND); //2038-01-19 04:14:07 
SELECT DATE_ADD(FROM_UNIXTIME(0), INTERVAL 2147483648 SECOND); //2038-01-19 04:14:08 
... 
SELECT DATE_ADD(FROM_UNIXTIME(0), INTERVAL 4147483647 SECOND); //2101-06-06 07:47:27 

jetzt Also, ich bin mit

... 
CASE 
    WHEN `javaTimeStampColumn` > 2147483647 THEN 
    CONVERT_TZ(DATE_ADD(FROM_UNIXTIME(0), INTERVAL `javaTimeStampColumn`/1000 SECOND),'+00:00','+00:00') 
    ELSE 
    CONVERT_TZ(FROM_UNIXTIME(`javaTimeStampColumn`/1000), '+00:00','+00:00') 
END as ts 
FROM table 
... 

Dies sollte die Auswirkungen auf die Leistung minimieren, wenn es welche gibt.

+0

Es schien zu lösen Problem, bis ich darüber gestolpert bin (GMT + 1 Zeitzone): 'SELECT FROM_UNIXTIME (1469230446)' macht: 2016-07-23 ** 01 **: 34:06 'SELECT DATE_ADD (FROM_UNIXTIME (0), INTERVAL 1469230446 SECOND '' macht: 2016-07-23 ** 00 **: 34:06 Irgendeine Idee? –

+1

@ TamásMárton, verwenden Sie 'CONVERT_TZ' mit korrekten Offsets. Unix-Zeit ist immer UTC. 'DATE_ADD' verwendet Ihre Zeitzone von' GMT + 1', also müssen Sie dies beheben. – dognose

+0

Danke, die Client-Zeitzone auf '+00: 00' eingestellt, hat es wirklich behoben. –