現在のタイムゾーンに適切な時刻が設定されていて、保存する日時列のタイムゾーンがわかっていて、夏時間の問題を認識している限り、サーバー上のタイムゾーンは問題ではないようです。
一方、使用するサーバーのタイムゾーンを制御できる場合は、すべてを内部でUTCに設定でき、タイムゾーンとDSTについて心配する必要はありません。
これは、自分自身と他の人のチートシートの形式としてタイムゾーンを操作する方法について収集したメモです。これは、サーバー用に選択するタイムゾーンと、日付と時刻の保存方法に影響を与える可能性があります。
MySQLタイムゾーンのチートシート
注:
-
タイムゾーンを変更しても、保存されている日時やタイムスタンプは変更されません 、ただし、timestamp列から別の日時が選択されます
-
警告! UTCにはうるう秒があり、これらは「2012-06-30 23:59:60」のように見え、地球の自転が遅くなるため、6か月前に通知してランダムに追加できます
-
GMTは秒を混乱させるため、UTCが発明されました。
-
警告! 地域のタイムゾーンが異なると、夏時間のために同じ日時の値が生成される可能性があります
-
タイムスタンプ列は、制限 。
-
内部的には、MySQLタイムスタンプ列 UTC として保存されます ただし、日付を選択すると、MySQLはそれを現在のセッションタイムゾーンに自動的に変換します。
タイムスタンプに日付を保存する場合、MySQLは日付が現在のセッションのタイムゾーンにあると想定し、保存のためにUTCに変換します。
-
MySQLは、日付の一部を日時列に格納できます。これらは「2013-00-0004:00:00」のようになります
-
日時列をNULLとして設定した場合、作成時にnullを許可するように列を特に設定しない限り、MySQLは「0000-00-0000:00:00」を格納します。
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`
UTCで現在の日時を選択するには:
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が返されます。
現在のUNIXタイムスタンプ(秒単位)を取得するには:
SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();
タイムスタンプ列をUNIXタイムスタンプとして取得するには
SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
UTC日時列をUNIXタイムスタンプとして取得するには
SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`
正のUNIXタイムスタンプ整数から現在のタイムゾーン日時を取得します
SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`
UNIXタイムスタンプからUTC日時を取得する
SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00')
FROM `table_name`
負のUNIXタイムスタンプ整数から現在のタイムゾーン日時を取得します
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
MySQLでタイムゾーンが設定される可能性のある場所は3つあります:
注:タイムゾーンは2つの形式で設定できます:
- UTCからのオフセット:「+ 00:00」、「+ 10:00」、または「-6:00」
- 名前付きタイムゾーンとして:「ヨーロッパ/ヘルシンキ」、「米国/東部」、または「MET」
名前付きタイムゾーンは、mysqlデータベースのタイムゾーン情報テーブルが作成され、入力されている場合にのみ使用できます。
ファイル「my.cnf」内
default_time_zone='+00:00'
または
timezone='UTC'
@@global.time_zone変数
設定されている値を確認するには
SELECT @@global.time_zone;
値を設定するには、次のいずれかを使用します。
SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET @@global.time_zone='+00:00';
@@session.time_zone変数
SELECT @@session.time_zone;
設定するには、次のいずれかを使用します。
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET @@session.time_zone = "+00:00";
「@@global.time_zone変数」と「@@session.time_zone変数」の両方が「SYSTEM」を返す場合があります。これは、「my.cnf」で設定されたタイムゾーンを使用することを意味します。
タイムゾーン名を機能させるには(デフォルトのタイムゾーンでも)、タイムゾーン情報テーブルにデータを入力する必要があります: 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`
mysqlタイムゾーンテーブルの設定
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
このコマンドでエラー「
これを実行するための修正
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 /
)
すべてのタイムゾーンの完全なDST(夏時間)移行履歴を表示する
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
また、上記の表のルールと使用した日付に基づいて、必要なDSTの変更を適用します。
注:
ドキュメント> 、time_zoneに設定した値は変更されません。たとえば、「+ 01:00」に設定すると、time_zoneはDSTに従わないUTCからのオフセットとして設定されるため、すべて同じままになります。一年中。
名前付きの
CET
のような略語 常に冬時間であり、CEST
+01:00は常にUTC
であるのに対し、夏時間になります 時間+1時間で、どちらもDSTで変更されません。
system
タイムゾーンは、mysqlがインストールされているホストマシンのタイムゾーンになります(mysqlがそれを決定できない場合を除く)
DSTの使用について詳しくは、こちら をご覧ください。
伝説のジョンスキートがUTCを使用しない場合: https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/ (たとえば、瞬間ではなく、時間を表す将来のスケジュールされたイベント)
関連する質問:
- MySQLのタイムゾーンを設定するにはどうすればよいですか?
- MySql-UTC形式のSELECTTimeStamp列
- 方法UTC時間からMySQLでUnixタイムスタンプを取得しますか?
- サーバーのMySQLタイムスタンプをUTCに変換
- https://dba。 stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp
- 方法MySQLの現在のタイムゾーンを取得しますか?
- MySQL日時フィールドと夏時間-「余分な」時間を参照するにはどうすればよいですか?
- FROM_UNIXTIMEからの負の値の変換
出典:
- https://bugs.mysql.com/bug.php?id=68861
- http://dev。 mysql.com/doc/refman/5.0/en/date-and-time-functions.html
- http://dev.mysql.com/doc/ refman / 5.1 / en / datetime.html
- http://en.wikipedia.org/wiki/Coordinated_Universal_Time
- http://shafiqissani.wordpress.com/2010/09/30/how-to-get-the-current-epoch-time-unix-timestamp/
- https://web.ivy.net/~carton/ rant / MySQL-timezones.txt