/server/191331/should-servers-have-their-timezone-set-to-gmt-utcのフォローアップ質問
MySQLタイムゾーンをUTCに設定する必要がありますか、それともサーバーまたはPHPが設定されているのと同じタイムゾーンに設定する必要がありますか?(UTCでない場合)
長所と短所は何ですか?
/server/191331/should-servers-have-their-timezone-set-to-gmt-utcのフォローアップ質問
MySQLタイムゾーンをUTCに設定する必要がありますか、それともサーバーまたはPHPが設定されているのと同じタイムゾーンに設定する必要がありますか?(UTCでない場合)
長所と短所は何ですか?
回答:
現在のタイムゾーンに適切な時刻が設定されていて、格納する日時列のタイムゾーンがわかっていて、夏時間の問題を認識している限り、サーバーのタイムゾーンは問題ではないようです。
一方、使用するサーバーのタイムゾーンを制御できる場合は、すべてを内部でUTCに設定でき、タイムゾーンとDSTについて心配する必要はありません。
ここに、自分用のチートシートの形式としてタイムゾーンを使用する方法について収集したいくつかのメモがあります。その他は、ユーザーがサーバー用に選択するタイムゾーンと、日付と時刻を格納する方法に影響を与える可能性があります。
ノート:
GMTは秒を混同するため、UTCが発明されました。
警告!夏時間のため、異なる地域のタイムゾーンは同じ日時値を生成する可能性があります
内部的にはMySQLタイムスタンプカラムはUTCとして保存されますが、日付を選択すると、MySQLは自動的に現在のセッションのタイムゾーンに変換します。
タイムスタンプに日付を保存する場合、MySQLは日付が現在のセッションのタイムゾーンにあると想定し、保存するためにUTCに変換します。
現在のMySQLセッションがどのタイムゾーンにあっても:
SELECT
CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`
また、サーバー、グローバル、または現在のセッションのタイムゾーンをUTCに設定し、次のようにタイムスタンプを選択することもできます。
SELECT `timestamp_field` FROM `table_name`
SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), @@session.time_zone, '+00:00');
結果の例: 2015-03-24 17:02:41
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_TIMESTAMP();
SELECT @@system_time_zone;
たとえば、モスクワ時間の場合は「MSK」または「+04:00」を返します。数値のオフセットに設定した場合、夏時間を調整しないMySQLバグがあります(またはありました)。
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);
タイムゾーンが+2:00の場合、02:00:00を返します。
SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();
SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`
SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`
SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00')
FROM `table_name`
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
注:タイムゾーンは2つの形式で設定できます。
名前付きタイムゾーンは、mysqlデータベース内のタイムゾーン情報テーブルが作成され、データが入力されている場合にのみ使用できます。
default_time_zone='+00:00'
または
timezone='UTC'
それらに設定されている値を確認するには
SELECT @@global.time_zone;
値を設定するには、次のいずれかを使用します。
SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET @@global.time_zone='+00:00';
SELECT @@session.time_zone;
設定するには、次のいずれかを使用します。
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET @@session.time_zone = "+00:00";
"@@ global.time_zone variable"と "@@ session.time_zone variable"の両方が "SYSTEM"を返す場合があります。これは、 "my.cnf"で設定されたタイムゾーンを使用することを意味します。
タイムゾーン名を機能させるには(default-time-zoneでも)、タイムゾーン情報テーブルを設定する必要があります: http : //dev.mysql.com/doc/refman/5.1/en/time-zone-support。 html
注:NULLを返すため、これを行うことはできません。
SELECT
CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime`
FROM `table_name`
以下のためにCONVERT_TZ
仕事に、あなたはタイムゾーンテーブルを移入する必要があります
SELECT * FROM mysql.`time_zone` ;
SELECT * FROM mysql.`time_zone_leap_second` ;
SELECT * FROM mysql.`time_zone_name` ;
SELECT * FROM mysql.`time_zone_transition` ;
SELECT * FROM mysql.`time_zone_transition_type` ;
それらが空の場合、このコマンドを実行してそれらを埋めます
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
このコマンドで「列1の列 'abbreviation'にはデータが長すぎます」というエラーが表示される場合は、タイムゾーンの省略形の末尾にNULL文字が追加されていることが原因である可能性があります
修正はこれを実行することです
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
(if the above gives error "data too long for column 'abbreviation' at row 1")
mysql_tzinfo_to_sql /usr/share/zoneinfo > /tmp/zut.sql
echo "SET SESSION SQL_MODE = '';" > /tmp/mysql_tzinfo_to.sql
cat /tmp/zut.sql >> /tmp/mysql_tzinfo_to.sql
mysql --defaults-file=/etc/mysql/my.cnf --user=verifiedscratch -p mysql < /tmp/mysql_tzinfo_to.sql
(サーバーのdstルールが最新であることを確認してくださいzdump -v Europe/Moscow | grep 2011
https://chrisjean.com/updating-daylight-saving-time-on-linux/)
SELECT
tzn.Name AS tz_name,
tztt.Abbreviation AS tz_abbr,
tztt.Is_DST AS is_dst,
tztt.`Offset` AS `offset`,
DATE_ADD('1970-01-01 00:00:00',INTERVAL tzt.Transition_time SECOND) AS transition_date
FROM mysql.`time_zone_transition` tzt
INNER JOIN mysql.`time_zone_transition_type` tztt USING(Time_zone_id, Transition_type_id)
INNER JOIN mysql.`time_zone_name` tzn USING(Time_zone_id)
-- WHERE tzn.Name LIKE 'Europe/Moscow' -- Moscow has weird DST changes
ORDER BY tzt.Transition_time ASC
CONVERT_TZ
また、上記の表のルールと使用する日付に基づいて、必要な夏時間の変更を適用します。
注:ドキュメントに
よると、time_zoneに設定した値は変更されません。たとえば、「+ 01:00」に設定すると、time_zoneはDSTに従わないUTCからのオフセットとして設定されるため、一年中同じです。
名前付きタイムゾーンのみが夏時間の時間を変更します。
のような省略形CET
は常に冬時間で夏時間であり、+ CEST
01:00は常にUTC
時間+ 1時間であり、どちらもDSTで変更されません。
system
(MySQLはそれを決定するために失敗しない限り)タイムゾーンは、MySQLがインストールされているホスト・マシンのタイムゾーンになります
DSTの操作について詳しくは、こちらをご覧ください。
関連する質問:
出典:
table
セットmodified
= '2016-07-07 08:10 +00:00'
UNIX_TIMESTAMP(NOW());
であるCONVERT_TZ()
場合のすべての使用に影響します。UTC日時をUNIXタイムスタンプに確実に変換するには、基本的にセッションtime_zoneを最初に設定する必要があります。
PHPとMySQLには、独自のデフォルトのタイムゾーン構成があります。データベースとWebアプリケーションの間で時間を同期する必要があります。そうしないと、いくつかの問題が発生する可能性があります。
このチュートリアルを読む:PHPとMySQLのタイムゾーンを同期する方法
date_default_timezone_set("America/Los_Angeles");
そしてmysql_query("SET time_zone='" . date('P', time()) . "'");
非常にエレガントに動作しました!