Archives mensuelles : octobre 2021

La fin du monde en 2038… après ma retraite… ou pas…

Pour savoir de quoi il est question je vous invite à lire:

Bug de l’an_2038

Alors 2038 c’est loin… mais finalement non, nous gérons des abonnements pour des périodes
allant jusqu’à 10 ans… demain en 2028… nous risquons d’avoir des problèmes.

Donc avec des bases SQL MariaDB ou MySQL qui ont toujours des fonctions limitées en 32 bits, nous allons avoir des problèmes…

Voici donc comment remplacer  les fonctions SQL UNIX_TIMESTAMP() et FROM_UNIXTIME() par des fonctions ou les dates > 2038-01-19 03:14:07 UTC ne sont pas (trop) un problème.

In MySql and MariaDB the TIMESTAMP data type is used for values that contain both date and time parts.
TIMESTAMP has a range of ‘1970-01-01 00:00:01’ UTC to ‘2038-01-19 03:14:07’ UTC.
This is due to the underlying 32-bit limitation.

Avec les “SUPER” pouvoir MySQL 😉

DROP function IF EXISTS unix_timestamp_fixed;
DROP function IF EXISTS from_unixtime_fixed;

CREATE FUNCTION unix_timestamp_fixed (v DATETIME)
RETURNS BIGINT DETERMINISTIC
RETURN TIMESTAMPDIFF(SECOND, FROM_UNIXTIME(0), v);

CREATE FUNCTION from_unixtime_fixed (v BIGINT)
RETURNS DATETIME DETERMINISTIC
RETURN DATE_ADD(FROM_UNIXTIME(0), INTERVAL v second);

SHOW function status;

exemple:

SELECT unix_timestamp_fixed('2040-01-02 03:04:05');
+---------------------------------------------+
| unix_timestamp_fixed('2040-01-02 03:04:05') |
+---------------------------------------------+
| 2209082645                                  |
+---------------------------------------------+

SELECT from_unixtime_fixed( 2209082645 );
+-----------------------------------+
| from_unixtime_fixed( 2209082645 ) |
+-----------------------------------+
| 2040-01-02 03:04:05               |
+-----------------------------------+
% date -r 2209082645
Mon Jan 2 03:04:05 CET 2040

On a l’impression que c’est bon… mais non pas du tout   /!\

SELECT unix_timestamp_fixed('2021-10-10 20:29:34');
+---------------------------------------------+
| unix_timestamp_fixed('2021-10-10 20:29:34') |
+---------------------------------------------+
| 1633894174                                  |
+---------------------------------------------+
% date -r 1633894174
Sun Oct 10 21:29:34 CEST 2021

Raté 1h de décalage, probablement une question de Fuseau horaire

Donc cela ne fonctionne pas, c’est pas très utile… donc vous devez plus probablement tenir compte de votre fuseau horaire pour ne pas avoir de différence entre UNIX_TIMESTAMP() et unix_timestamp_fixed()

Ici en France à Paris en 2021 on oscille entre UTC+1 et UTC+2,  pour ceux que cela intéresse:
https://fr.wikipedia.org/wiki/Heure_en_France

Voila donc fonction unix_timestamp_fixed() “compatible” avec UNIX_TIMESTAMP()

CREATE FUNCTION unix_timestamp_fixed (v DATETIME)
RETURNS BIGINT DETERMINISTIC
RETURN TIMESTAMPDIFF(SECOND, '1970-01-01', v)+
       TIMESTAMPDIFF(SECOND, v, CONVERT_TZ(v, @@SESSION.TIME_ZONE, '+00:00'));

SELECT unix_timestamp_fixed('2021-10-10 20:29:34');
+---------------------------------------------+
| unix_timestamp_fixed('2021-10-10 20:29:34') |
+---------------------------------------------+
| 1633890574                                  |
+---------------------------------------------+

% date -r 1633890574
Sun Oct 10 20:29:34 CEST 2021

SELECT unix_timestamp_fixed('2042-10-10 20:29:34');
+---------------------------------------------+
| unix_timestamp_fixed('2042-10-10 20:29:34') |
+---------------------------------------------+
| 2296585774                                  |
+---------------------------------------------+

% date -r 2296585774
Fri Oct 10 22:29:34 CEST 2042

Arrggg Caramba, encore raté !!! Après 2038 il y a encore un décalage avant c’est ok…