Comment obtenir le fuseau horaire actuel de MySQL?

217

Tout le monde sait s'il existe une telle fonction dans MySQL?

METTRE À JOUR

Cela ne génère aucune information valide:

mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM             | SYSTEM              |
+--------------------+---------------------+

Ou peut-être que MySQL lui-même ne peut pas connaître exactement l' time_zoneutilisation, c'est bien, nous pouvons impliquer PHPici, tant que je peux obtenir des informations valides pas comme SYSTEM...

user198729
la source
3
"nous pouvons impliquer PHP ici" - et cette instance de php serait-elle toujours sur la même machine que le serveur MySQL?
VolkerK
Oui, ils seront sur la même machine.
user198729
10
Essayez @@system_time_zonecomme indiqué dans ma réponse ci-dessous.
Andrew
Puisque la question a été posée, plus de réponses ont été ajoutées, peut-être reconsidérer la réponse acceptée?
Timo Huovinen du
1
Même si le serveur MySQL et PHP sont sur le même serveur, ils peuvent récupérer différents fuseaux horaires en fonction de leurs paramètres. Et ces temps peuvent différer de ce que montre votre système d'exploitation et de PHP / MySQL.
Bimal Poudel

Réponses:

227

Dans le manuel ( section 9.6 ):

Les valeurs actuelles des fuseaux horaires globaux et spécifiques au client peuvent être récupérées comme ceci:
mysql> SELECT @@global.time_zone, @@session.time_zone;

Modifier Ce qui précède revient SYSTEMsi MySQL est réglé sur esclave du fuseau horaire du système, ce qui est moins qu'utile. Puisque vous utilisez PHP, si la réponse de MySQL est SYSTEM, vous pouvez alors demander au système par quel fuseau horaire il utilise date_default_timezone_get. (Bien sûr, comme l'a souligné VolkerK, PHP peut s'exécuter sur un serveur différent, mais selon les hypothèses, en supposant que le serveur Web et le serveur de base de données avec lesquels il parle sont définis sur [sinon en fait dans ] le même fuseau horaire n'est pas un énorme saut.) Mais attention (comme avec MySQL), vous pouvez définir le fuseau horaire que PHP utilise (date_default_timezone_set), ce qui signifie qu'il peut signaler une valeur différente de celle utilisée par le système d'exploitation. Si vous contrôlez le code PHP, vous devez savoir si vous le faites et être d'accord.

Mais toute la question du fuseau horaire utilisé par le serveur MySQL peut être tangente, car demander au serveur dans quel fuseau horaire il ne vous dit absolument rien sur les données de la base de données. Lisez la suite pour plus de détails:

Discussion supplémentaire :

Si vous contrôlez le serveur, vous pouvez bien sûr vous assurer que le fuseau horaire est une quantité connue. Si vous ne contrôlez pas le serveur, vous pouvez définir le fuseau horaire utilisé par votre connexion comme ceci:

set time_zone = '+00:00';

Cela définit le fuseau horaire sur GMT, de sorte que toute autre opération (comme now()) utilise GMT.

Notez cependant que les valeurs d'heure et de date ne sont pas stockées avec les informations de fuseau horaire dans MySQL:

mysql> create table foo (tstamp datetime) Engine=MyISAM;
Query OK, 0 rows affected (0.06 sec)

mysql> insert into foo (tstamp) values (now());
Query OK, 1 row affected (0.00 sec)

mysql> set time_zone = '+01:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select tstamp from foo;
+---------------------+
| tstamp              |
+---------------------+
| 2010-05-29 08:31:59 |
+---------------------+
1 row in set (0.00 sec)

mysql> set time_zone = '+02:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select tstamp from foo;
+---------------------+
| tstamp              |
+---------------------+
| 2010-05-29 08:31:59 |      <== Note, no change!
+---------------------+
1 row in set (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2010-05-29 10:32:32 |
+---------------------+
1 row in set (0.00 sec)

mysql> set time_zone = '+00:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2010-05-29 08:32:38 |      <== Note, it changed!
+---------------------+
1 row in set (0.00 sec)

Donc , sachant le fuseau horaire du serveur est seulement important en termes de fonctions qui obtiennent le temps en ce moment, comme now(), unix_timestamp(), etc .; il ne vous dit rien sur le fuseau horaire utilisé par les dates dans les données de la base de données. Vous pouvez choisir de supposer qu'elles ont été écrites à l'aide du fuseau horaire du serveur, mais cette hypothèse pourrait bien être erronée. Pour connaître le fuseau horaire de toutes les dates ou heures stockées dans les données, vous devez vous assurer qu'elles sont stockées avec des informations de fuseau horaire ou (comme je le fais) qu'elles sont toujours en GMT.

Pourquoi l'hypothèse selon laquelle les données ont été écrites à l'aide du fuseau horaire du serveur est-elle défectueuse? Eh bien, d'une part, les données peuvent avoir été écrites à l'aide d'une connexion qui définit un fuseau horaire différent. La base de données a peut-être été déplacée d'un serveur à un autre, où les serveurs se trouvaient dans des fuseaux horaires différents (je suis tombé dessus lorsque j'ai hérité d'une base de données qui était passée du Texas à la Californie). Mais même si les données sont écrites sur le serveur, avec son fuseau horaire actuel, elles restent ambiguës. L'année dernière, aux États-Unis, l'heure d'été a été désactivée à 2h00 du matin le 1er novembre. Supposons que mon serveur se trouve en Californie en utilisant le fuseau horaire du Pacifique et que j'ai la valeur2009-11-01 01:30:00dans la base de données. Quand était-ce? Était-ce à 1 h 30 le 1er novembre HAP ou à 1 h 30 le 1er novembre HNP (une heure plus tard)? Vous n'avez absolument aucun moyen de le savoir. Moralité: stockez toujours les dates / heures au format GMT (qui ne fait pas l'heure d'été) et convertissez-les au fuseau horaire souhaité si / lorsque nécessaire.

TJ Crowder
la source
5
@ user198729: Ce n'est pas dénué de sens , bien que ce ne soit pas aussi utile que je l'espérais. Ce que cela signifie est: demandez au système d'exploitation, MySQL asservit à cela.
TJ Crowder
Juste curieux, pourquoi devons-nous définir le fuseau horaire nous-mêmes, puis le récupérer? Ce genre de défait le but n'est-ce pas? Je veux dire, je voudrais demander à MySQL le fuseau horaire parce que je ne connais pas la réponse. Peut-être que je suis confus et que je me trompe. Quelqu'un peut-il expliquer?
Senthil
1
@Senthil Le DATETIMEtype mySQL ne contient pas d'informations sur le fuseau horaire. Par conséquent, je pense que la philosophie sous-jacente ici est que mySQL soit aussi aveugle que possible sur le fuseau horaire - ce qui signifie que l'utilisateur doit respecter un fuseau horaire, UTC ou le fuseau horaire dans lequel se trouve le serveur, stocker tout dans cette zone, et faire des conversions au niveau de l'application ou en utilisant CONVERT_TZ()( dev.mysql.com/doc/refman/5.0/en/… ) C'est du moins ainsi que j'ai toujours compris comment il est censé fonctionner, en regardant les rares options fournies par mySQL dans ce domaine.
Pekka
Merci mais ce n'est pas encore résolu, comment puis-je obtenir les informations tz par le résultat de now()PHP?
user198729
Je suis totalement d'accord avec la partie "coller à un seul fuseau horaire lors de la sauvegarde de l'horodatage". Mais ceci-> "..ou le fuseau horaire dans lequel se trouve le serveur .." comment trouvez-vous cela? Supposons que vous ayez enregistré toutes les valeurs d'horodatage au format UTC. Mais votre serveur se trouve dans un autre fuseau horaire et vous souhaitez afficher les valeurs d'horodatage en fonction de ce fuseau horaire. Alors, comment saurez-vous dans quel fuseau horaire se trouve votre serveur? Alors seulement, vous pouvez transmettre une valeur à CONVERT_TZ () pour la convertir, n'est-ce pas?
Senthil
196

La requête ci-dessous renvoie le fuseau horaire de la session en cours.

select timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00'));
JohnZ
la source
6
C'est vraiment la bonne réponse, car elle démontre que «SYSTEM» est reconnu comme un fuseau horaire dans la conversion, ce qui le rend entièrement suffisant pour convertir par exemple NOW () en n'importe quel fuseau horaire.
nilskp
5
Merci, en utilisant cela, j'ai pu obtenir le format que je voulais:select time_format(timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00')),'%H%i');
jordanbtucker
97
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP)est plus simple.
Jakub Vrána
3
Ou SELECT TIMESTAMPDIFF(SECOND, NOW(), UTC_TIMESTAMP);pour obtenir la différence en quelques secondes.
philfreo
106

Simplement SELECT @@system_time_zone;

Retours PST(ou tout ce qui est pertinent pour votre système).

Si vous essayez de déterminer le fuseau horaire de la session, vous pouvez utiliser cette requête:
SELECT IF(@@session.time_zone = 'SYSTEM', @@system_time_zone, @@session.time_zone);

Qui renverra le fuseau horaire de la session s'il diffère du fuseau horaire du système.

Andrew
la source
6
Le seul inconvénient est que si le fuseau horaire change en raison des changements d'heure d'été, il signalera toujours celui qui était "mémorisé" au moment du démarrage du serveur, voir bug mysql 9518
Mark
72

Comme Jakub Vrána (Le créateur ou Adminer et NotORM ) mentionne dans les commentaires, pour sélectionner le fuseau horaire actuel décalage dans l' TIMEutilisation:

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

Il reviendra: 02:00:00si votre fuseau horaire est +2: 00 pour cette date

J'ai fait une feuille de triche ici: MySQL devrait - il avoir son fuseau horaire réglé sur UTC?

Timo Huovinen
la source
Ou SELECT TIMESTAMPDIFF(SECOND, NOW(), UTC_TIMESTAMP);pour obtenir la différence en quelques secondes.
philfreo
add-on à @philfreo - notez que les paramètres doivent être inversés dans TIMESTAMPDIFF par rapport à TIMEDIFF. Pour prendre l'exemple donné dans cette réponse, si TIMEDIFF revient 02:00:00, le TIMESTAMPDIFF correspondant retournera -2si l'unité est HOUR, -120si l'unité est MINUTE, etc. Pour obtenir le signe correspondant au fuseau horaire, permutez les paramètres: SELECT TIMESTAMPDIFF(MINUTE, UTC_TIMESTAMP, NOW())retournera le 120fuseau horaire attendu +2: 00. La raison pour spécifier des minutes est qu'il y a quelques fuseaux horaires décalés de 30 ou 45 minutes, voir en.wikipedia.org/wiki/Time_zone
ToolmakerSteve
1
c'est une bien meilleure réponse que la réponse acceptée car elle répond directement à la question et donne une solution au lieu d'une simple théorie.
supersan
10

Pour obtenir le fuseau horaire actuel du mysql, vous pouvez faire les choses suivantes:

 1. SELECT @@system_time_zone;   //from this you can get the system timezone 
 2. SELECT IF(@@session.time_zone = 'SYSTEM', @@system_time_zone, @@session.time_zone) //This will give you time zone if system timezone is different from global timezone

Maintenant, si vous voulez changer le fuseau horaire mysql alors:

 1. SET GLOBAL time_zone = '+00:00'   //this will set mysql timezone in UTC
 2. SET @@session.time_zone = "+00:00";  //by this you can chnage the timezone only for your particular session 
Abhinav bhardwaj
la source
6
SELECT EXTRACT(HOUR FROM (TIMEDIFF(NOW(), UTC_TIMESTAMP))) AS `timezone`

Cela retournera le fuseau horaire sous la forme d'un entier (par exemple -6:), gérant les temps positifs ou négatifs (voici où EXTRACTentre en jeu: la HOURfonction seule retourne les fuseaux horaires négatifs comme positifs).

Luca Fagioli
la source
6

A tous ceux qui viennent trouver le fuseau horaire de mysql db.

Avec cette requête, vous pouvez obtenir le fuseau horaire actuel:

mysql> SELECT @@system_time_zone as tz;
+-------+
|  tz   |
+-------+
|  CET  |
+-------+
ttrasn
la source
4

La commande mentionnée dans la description renvoie "SYSTEM" qui indique qu'il prend le fuseau horaire du serveur. Ce qui n'est pas utile pour notre requête.

La requête suivante aidera à comprendre le fuseau horaire

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP) as GMT_TIME_DIFF;

La requête ci-dessus vous donnera l'intervalle de temps par rapport au temps universel coordonné (UTC). Vous pouvez donc facilement analyser le fuseau horaire. si le fuseau horaire de la base de données est IST, la sortie sera 5h30

UTC_TIMESTAMP

Dans MySQL, UTC_TIMESTAMP renvoie la date et l'heure UTC actuelles sous forme de valeur au format 'YYYY-MM-DD HH: MM: SS' ou YYYYMMDDHHMMSS.uuuuuu selon l'utilisation de la fonction, c'est-à-dire dans un contexte de chaîne ou numérique.

MAINTENANT()

Fonction NOW (). MySQL NOW () renvoie la valeur de la date et de l'heure actuelles au format 'YYYY-MM-DD HH: MM: SS' ou YYYYMMDDHHMMSS.uuuuuu selon le contexte (numérique ou chaîne) de la fonction. CURRENT_TIMESTAMP, CURRENT_TIMESTAMP (), LOCALTIME, LOCALTIME (), LOCALTIMESTAMP, LOCALTIMESTAMP () sont des synonymes de NOW ().

Amitesh
la source
2

Consultez la prise en charge du fuseau horaire du serveur MySQL et la system_time_zonevariable système. Est ce que ça aide?

Pekka
la source
@utilisateur pouvez-vous préciser dans votre question quelles informations vous recherchez exactement (le fuseau horaire du serveur? Le client?) et quels outils sont à votre disposition? Vous mentionnez PHP. Pouvez-vous accéder à la ligne de commande?
Pekka
5
@user également, je trouve que vous rencontrez un peu la bite de voter pour des réponses de personnes qui essaient d'être utiles, et pas exactement fausses. Cela ne me dérange pas le vote ni la perte de points, mais votre attitude n’encourage pas exactement à chercher plus loin une solution.
Pekka
3
@user comme je l'ai dit, votre attitude ne me motive pas à rechercher d'autres réponses pour vous, surtout à la lumière des maigres informations que vous fournissez. Désolé.
Pekka
3
@ user198729: Wow, perdons l'attitude. Pekka est le genre de gars qui aide vraiment les gens. Si la courtoisie seule ne suffit pas à vous motiver, essayez l'intérêt personnel.
TJ Crowder
2
Juste mes pensées: je n'aurais pas été offensé si l'utilisateur avait fait la même chose à mon message. Je veux dire, la pression sur les délais ou la frustration ajoute des rudesse aux gens, mais je pense que nous devrions le permettre dans une certaine mesure. Peut-être que je suis trop indulgent: |
Senthil
1

Mon framework PHP utilise

SET LOCAL time_zone='Whatever'

après la connexion, où «Quoi que» == date_default_timezone_get ()

Ce n'est pas ma solution, mais cela garantit que le SYSTEMfuseau horaire du serveur MySQL est toujours le même que celui de PHP

Donc, oui, PHP est fortement impliqué et peut l'affecter

Vladkras
la source
1

Pour obtenir l'heure actuelle en fonction de votre fuseau horaire, vous pouvez utiliser ce qui suit (dans mon cas, son '+5: 30')

sélectionnez DATE_FORMAT (convert_tz (now (), @@ session.time_zone, '+ 05:30'), '% Y-% m-% d')

Sanjoy Kanrar
la source
0

Il vous suffit de redémarrer mysqld après avoir modifié le fuseau horaire du système.

Le fuseau horaire global de MySQL prend le fuseau horaire du système. Lorsque vous modifiez un tel attribut de système, vous avez juste besoin d'un redémarrage de Mysqld.

Storm Young
la source
après avoir changé le fuseau horaire sur le système d'exploitation, les insertions mysql utiliseront le nouveau fuseau horaire mais sélectionnez maintenant (); et sélectionnez current_timestamp; les commandes utiliseront toujours l'ancien fuseau horaire. Pour synchroniser tout cela, le service mysql doit être redémarré.
Manoj Kumar G
0

Insérez un enregistrement factice dans l'une de vos bases de données qui possède un horodatage Sélectionnez cet enregistrement et obtenez la valeur de l'horodatage. Supprimez cet enregistrement. Obtient avec certitude le fuseau horaire que le serveur utilise pour écrire des données et ignore les fuseaux horaires PHP.

alee
la source
0

Vous pouvez essayer ce qui suit:

select sec_to_time(TIME_TO_SEC( curtime()) + 48000);

Ici, vous pouvez spécifier votre décalage horaire en secondes

Bala Kayan
la source
1
vous ne devez pas ajouter ni soustraire de décalages. avec la lumière du jour disant des règles etc c'est un champ de mines
eweb
0

Utilisez LPAD(TIME_FORMAT(TIMEDIFF(NOW(), UTC_TIMESTAMP),’%H:%i’),6,’+')pour obtenir une valeur au format de fuseau horaire de MySQL que vous pouvez facilement utiliser avec CONVERT_TZ(). Notez que le décalage de fuseau horaire que vous obtenez n'est valide qu'au moment où l'expression est évaluée, car le décalage peut changer au fil du temps si vous avez l'heure d'été. Pourtant, l'expression est utile avec NOW()pour stocker le décalage avec l'heure locale, ce qui NOW()rend sans ambiguïté ce qui donne. (Dans les fuseaux horaires DST, NOW()recule d'une heure une fois par an, a donc des valeurs en double pour des moments distincts).

rtc
la source
0

C'est possible

select timediff(current_time(),utc_time())

Vous n'obtiendrez pas directement la valeur du fuseau horaire de cette façon.

@@global.time_zonene peut pas être utilisé car il s'agit d'une variable et il renvoie la valeur 'SYSTEM'.

Si vous devez utiliser votre requête dans une session avec un fuseau horaire modifié à l'aide de session SET TIME_ZONE =, vous obtiendrez cela avec @@session.time_zone. Si vous interrogez @@global.time_zone, vous obtenez 'SYSTEM'.

Si vous essayez datediff, date_subou timediffavec now()et utc_time(), vous rencontrerez probablement des problèmes de conversion.

Mais les choses suggérées ci-dessus fonctionneront probablement au moins avec certaines versions de serveur. Ma version est 5.5.43-37 et est une solution hébergée.

dwaid
la source
Cela ne répond pas clairement à la question. Vous pouvez peut-être le modifier pour vous concentrer sur la question posée.
Mogsdad
-3

Essayez d'utiliser le code suivant:

//ASP CLASSIC
Set dbdate = Server.CreateObject("ADODB.Recordset")
dbdate.ActiveConnection = MM_connection
dbdate.Source = "SELECT NOW() AS currentserverdate "
dbdate.Open()
currentdate = dbdate.Fields("currentserverdate").Value
response.Write("Server Time is "&currentdate)
dbdate.Close()
Set dbdate = Nothing
Oscar Rojas
la source