web-dev-qa-db-ja.com

MySQL CONVERT_TZ()

ユーザーが指定した毎日のアラート時間を保存するデータベースをセットアップしようとしています。たとえば、ユーザーは、毎日午前7時から午前7時30分の間に何らかの基準が満たされた場合にアラートを受け取りたいと考えています。これを実装しようとすると、夏時間に対応する必要があります。私が試みた解決策は次のとおりです。

  1. ユーザーのローカルタイムゾーン(長い形式、たとえば「US/Eastern」)情報を1つのテーブル(userInfoなど)に保存し、アラーム時間を別のテーブル(userAlarmsなど)に保存します。
  2. UserAlarmsテーブルをクエリする場合、CONVERT_TZ(UTC_TIME(), 'UTC', userInfo.tz)を介してuserInfoテーブルに格納されているtz列で指定されているUTC時間をユーザーのローカル時間に変換します。

質問1.タイムゾーン名(US/Easternなど)を指定して、私の理解からshould夏時間を考慮に入れます。たとえば、1月1日にCONVERT_TZ('00:00:00', 'UTC', 'US/EASTERN')を呼び出すと「19:00:00」となりますが、7月1日に呼び出すと「20:00:00」となります。私は正しいですか?

質問2. Q1が正しい場合、タイムゾーンUTCオフセットを最新に保つために、MySQLのタイムゾーンテーブルを常に更新する必要がありますか

質問3。MySQLドキュメントSELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET')に記載されているサンプルは、サーバーで実行すると「NULL」になります。これは、タイムゾーンテーブルが設定されていないことが原因ですか?

これを確認するにはどうすればよいですか?

37
johnnyspo

これによりnullが生成される場合、TZテーブルはセットアップされていません。

SELECT CONVERT_TZ(now(),'US/Eastern','US/Central');

タイムゾーンテーブルが設定されていない場合は、ユーザーテーブルの時間オフセットを更新してから実行できます。

select utc_timezone() - interval user_timezone_offset_in_hours hour
from userinfo a
where user_id = 999;

ただし、ユーザーのタイムゾーンを更新する方法が必要です。

Webアプリケーション用にこれを書いている場合、javascriptを介してタイムゾーンを取得できます。ここに article があります(これは試していませんが、動作するようです)。

上記の「間隔」に関する説明の少し...

MySQLのより複雑な構造の1つは、INTERVALキーワードの使用です。これは、例で最もよく示されています(数値は式またはフィールド値にできます)

select now() today, now() - interval 1 day yesterday;
+---------------------+---------------------+
| today               | yesterday           |
+---------------------+---------------------+
| 2011-05-26 13:20:55 | 2011-05-25 13:20:55 |
+---------------------+---------------------+

あなたが好きなようにそれらを追加し、それらを減算することができます、これが日付/時刻の加算/減算/変換関数でわざわざ私neverである理由です

select now() a, now() - interval 1 day + interval 4 hour + interval 8 minute b;
+---------------------+---------------------+
| a                   | b                   |
+---------------------+---------------------+
| 2011-05-26 13:24:16 | 2011-05-25 17:32:16 |
+---------------------+---------------------+

負の数を使用できます(負のタイムゾーンオフセットに適しています)。これらは同じです。

select now() - interval 1 month a, now() + interval -1 month b;
+---------------------+---------------------+
| a                   | b                   |
+---------------------+---------------------+
| 2011-04-26 13:38:05 | 2011-04-26 13:38:05 |
+---------------------+---------------------+
27
dave

私はこのスレッドが役立ったと感じ、この情報をインポートするためのドキュメントページを共有することにしました。 CentOSおよびRHELで以下の指示どおりに実行したところ、問題なく動作しました。 「GMT」や「US/Eastern」などの引数でCONVERT_TZ関数を使用できるようになりました。

MySQLドキュメントから、これはMySQLタイムゾーンテーブル情報をインポートする方法です。

http://dev.mysql.com/tech-resources/articles/4.1/time.html


UnixベースのシステムでMySQL 4.1.3以降を実行しているすべてのユーザー(これはWindowsシステムではまだ機能しないことを思い出してください):

タイムゾーンテーブルに入力します。

そのためには、MySQLディストリビューションで提供されるmysql_tzinfo_to_sqlプログラムを実行します。 mysql_tzinfo_to_sqlは、オペレーティングシステムのタイムゾーンファイルを読み取り、それらからSQLステートメントを生成します。次に、SQLステートメントがmysqlによって処理され、タイムゾーンテーブルがロードされます。

mysql_tzinfo_to_sqlを正常に実行するには、サーバーマシンのオペレーティングシステムのタイムゾーンファイルが保存されている場所を知る必要があります。 /usr/share/zoneinfoに類似した名前のディレクトリを確認します。コマンドラインでディレクトリ名をmysql_tzinfo_to_sqlに渡し、出力をmysqlプログラムに送信します。以下に例を示します。

Shell> mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql

注:上記のコマンドは、「mysql_tzinfo_to_sql」と「mysql」がパスにあることを前提としています。そうでない場合は、コマンドの実行時に両方へのフルパスを指定するか、mysql binフォルダーに切り替えて次のようなコマンドを使用する必要があります。

Shell> ./mysql_tzinfo_to_sql /usr/share/zoneinfo | ./mysql -u root mysql
25
philwinkle

Q1:はい、CONVERT_TZは夏時間を考慮しています。この情報と各タイムゾーンのDSTの開始/終了時刻は、time_zone_ *テーブルに保存されます。

Q2:はい。mysqlのドキュメントに記載されているように、タイムゾーン情報は各地域の政治ごとに変わります。変更が発生するたびにtime_zone_ *テーブルを更新する必要があります。時々ITになりますが、これもその1つです。

Q3:これらは5つのタイムゾーンテーブルです。クエリを実行して、何かが含まれているかどうかを確認します。

select * from mysql.time_zone_transition_type;
select * from mysql.time_zone_transition;
select * from mysql.time_zone_name;
select * from mysql.time_zone_leap_second;
select * from mysql.time_zone;
19
David Parks