2010-10-25 13 views
1

J'ai hérité d'une application héritée où toutes les dates et heures sont stockées dans le fuseau horaire local (UK). Je ne suis pas en mesure de changer la façon dont ils sont stockés.Détecter si une date est en heure d'été dans MySQL

Cependant, l'exigence est d'afficher toutes les dates en GMT dans l'application. Par conséquent, lorsque je récupère une liste d'événements de la base de données, j'en ai besoin pour les afficher tous dans ce format horaire tout en observant si l'heure d'été est en cours pour chaque date d'événement particulière. En utilisant la logique suivante je peux déterminer si le changement d'été est activée dans la requête:

IF(CAST(TIMEDIFF(NOW(), UTC_TIMESTAMP()) AS SIGNED) >0, 
DATE_FORMAT(CONVERT_TZ(ADDTIME(`event_date`, IFNULL(`event_time`, '00:00')), '+01:00', '+00:00'), '%H:%i'), `event_time`) AS event_time 

Ceci est cependant évident que la date vérifier qu'il est en cours d'exécution à. Ainsi, les événements futurs qui traversent les limites de l'heure d'été ne fonctionnent pas.

Existe-t-il un moyen que je peux détecter si une date donnée est en heure d'été dans la requête mysql elle-même?

Toute aide, très appréciée.

+1

Pouvez-vous pas utiliser la fonction CONVERT_TZ dans une base MySQL? Ou ne vous donne-t-il pas les bons résultats? http://dev.mysql.com/doc/refman/5.1/fr/date-and-time-functions.html#function_convert-tz – Dave

+0

Je le fais. Le point est que j'ai besoin de savoir si l'appliquer ou non. Comme il est stocké en heure locale, certains d'entre eux sont GMT + 1 autres sont GMT + 0. Je ne peux pas l'appliquer sans discernement à tous. J'ai donc besoin de savoir si la date est +1 ou non –

+1

J'avais l'impression que CONVERT_TZ prenait automatiquement en compte l'heure d'été basée sur le contenu des tables time_zone_blah, donc si celles-ci sont correctement configurées, vous devriez pouvoir simplement faites 'CONVERT_TZ (event_time," US/Eastern "," GMT ")' et faites-le donner l'heure exacte en GMT – Dave

Répondre

1

Les fuseaux horaires ne sont pas stockés dans les valeurs DATETIME. Fait intéressant, ils sont pour TIMESTAMPs. Étant donné une date enregistrée, vous pouvez déterminer à titre posthume si l'heure d'été était à ce moment-là basée sur les règles locales. Puisque vous ne pouvez pas changer les dates, je suppose que vous ne pouvez pas ajouter une colonne pour stocker le fuseau horaire ...

Faire une procédure stockée qui contient les règles et convertit une date donnée en GMT.

Notez que seules les personnes qui habitent autour de Greenwich veulent afficher leurs heures en GMT. :)

Bonne chance.

+0

** Incorrect. ** Le type 'TIMESTAMP' ne mémorise pas * les informations de fuseau horaire.Juste le contraire: le type 'TIMESTAMP' ajuste les valeurs d'entrée dans UTC, puis rejette les informations de fuseau horaire d'origine. Citation de [la doc] (https://dev.mysql.com/doc/refman/5.7/en/datetime.html): * MySQL convertit les valeurs TIMESTAMP du fuseau horaire actuel en UTC pour le stockage, et de retour de UTC à le fuseau horaire actuel pour la récupération. * –

+0

Pour les mortels, UTC est fonctionnellement un fuseau horaire. –

0

Vous êtes au Royaume-Uni. Ainsi, votre ZT devrait être CET ou CEST (heure d'été d'Europe centrale). Vous pouvez obtenir les informations de cette façon:

mysql> SELECT @@system_time_zone; 
+--------------------+ 
| @@system_time_zone | 
+--------------------+ 
| CEST    | 
+--------------------+ 

Je l'utilise dans plusieurs de mes procédures stockées. Note: J'ai besoin des deux formes d'information TZ, que je doive calculer des offsets avec ou sans DST appliqué.

CASE @@system_time_zone 
    WHEN 'CET' THEN SET l_tz = 'Europe/Paris'; SET l_tzOff = '+1:00'; 
    WHEN 'CEST' THEN SET l_tz = 'Europe/Paris'; SET l_tzOff = '+1:00'; 
    WHEN 'SGT' THEN SET l_tz = 'Asia/Singapore'; SET l_tzOff = '+8:00'; 
    ELSE    SET l_tz = 'Europe/Paris'; SET l_tzOff = '+1:00'; 
END CASE; 

Vous pouvez vous inspirer de cela.

0

trouvé une manière compliquée laid, @DT est entrée Date de & Heure

Set @DT=20150329020304; # -> 0 

Set @DT=20150329030304; # -> 1(-0.0511) 

Set @DT=20150329040304; # -> 1(-1) 

Select 0!=(UNIX_TIMESTAMP(@DT)- UNIX_TIMESTAMP(Concat(Year(@DT),'0101',Time_Format(@DT,'%H%i%s')))-DateDiff(@DT,Concat(Year(@DT),'0101',Time_Format(@DT,'%H%i%s')))*86400)/3600 as DlsIsOn 
+0

Je ne peux pas expliquer comment cela fonctionne même ... mais il le fait – ChiMo

Questions connexes