質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

3010閲覧

タイムゾーンを変換した時の挙動について

norio13

総合スコア53

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2016/02/26 12:58

編集2016/02/26 12:59

PHP 7.0.0
php.iniにdate.timezone = "Asia/Tokyo"を設定しました。

タイムゾーンをAsia/Tokyoに再設定したコード。

PHP

1$dt = new DateTime('2016/02/26 21:00:00'); 2for ($i=0; $i<3; $i++) { 3 $dt->setTimezone(new DateTimeZone('Asia/Tokyo')); 4 echo $dt->format('Y/m/d H:i:s') . "\n"; 5}

実行結果

2016/02/26 21:00:00 2016/02/26 21:00:00 2016/02/26 21:00:00

タイムゾーンをJSTにすると

PHP

1$dt = new DateTime('2016/02/26 21:00:00'); 2for ($i=0; $i<3; $i++) { 3 $dt->setTimezone(new DateTimeZone('JST')); 4 echo $dt->format('Y/m/d H:i:s') . "\n"; 5}

実行結果

2016/02/26 21:00:00 2016/02/27 06:00:00 2016/02/27 15:00:00

実行する毎に9時間進みます。

どうして後者のコードでは同じ日時で出力されず、実行する毎に9時間進んだ日時が出力されるのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

気になったので PHP のソースコードを確認してみました。

まず PHP の DateTime で使用されるタイムゾーンは timezonemap.h に定義されていて、これが _timelib_tz_lookup_table 構造体の値として扱われるようになっています。

Asia/Tokyo の場合は次のようなメンバーを持つ構造体が作成されています(変数名は便宜上つけました)

lang

1timelib_tz_lookuptable tokyo = { 2 .name = "jst", 3 .type = 0, 4 .gmtoffset = 32400, 5 .full_tz_name = "Asia/Tokyo", 6};

このテーブルからデータを検索する関数の実体は timelib_parse_zone 関数で、指定されたタイムゾーン文字列を次の順番で決定していることがわかります。

  1. GMT-5 のような形式であるかどうか
  2. GMT-9 のような形式であるかどうか
  3. timelib_tz_lookuptable 型の name メンバと一致するかどうか
  4. UTC であるかどうか
  5. その他(Asia/Tokyo のような形式)。結果は TIMELIB_ZONETYPE_ID

この関数に JST をタイムゾーンとして指定すると GMT 形式ではないので timelib_lookup_abbr 関数の呼び出しに到達します。内部では timelib_tz_lookuptablename メンバとタイムゾーンを比較しています。(Tokyo がヒットするはずです)

制御が timelib_parse_zone 関数に戻り、タイムゾーンが見つかった場合は t->zone_typeTIMELIB_ZONETYPE_ABBR に設定されこの関数は終了することがわかります。

タイムゾーンがどのように処理されるかはわかったので、次に見るべきはタイムゾーンのオフセット処理です。
timezone_offset_get 関数では tzobj->typeTIMELIB_ZONETYPE_ABBR に設定されている場合、値をその都度計算して返していることがわかります。つまり、タイムゾーンを取得するたびに(東京の場合は)値が 9 時間ずつ進められてしまうわけです。

もっとも、PHP のサポートには記載されていないタイムゾーンであるため使わずに済むなら使用しないのがベターです。

投稿2016/02/26 16:20

chitoku

総合スコア1610

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

サポートされているタイムゾーンの中に「JST」はありませんでした。
サポート外のものですから、使わないようにしましょう。

http://php.net/manual/ja/timezones.php

投稿2016/02/26 14:13

編集2016/02/26 14:14
shi_ue

総合スコア4437

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

norio13

2016/02/26 14:27 編集

その通りでした。サポート外のタイムゾーンを使わないようにします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問