ニュースモジュールの日付がずれる
わけあってタイトルの現象を追ってみた。(間抜けなオチつき)
環境
xoopsの一般設定でサーバのタイムゾーンを設定できるのだが、
これをAsia/Tokyo(GMT+9h)に設定するとニュースモジュールでの投稿時刻がずれる。
なぜかタイムゾーンをGMTに設定すると正しい日本標準時間が取れる。
問題が露呈するのは管理者メニューNewsモジュールの管理者画面の投稿画面
ここで投稿する時に現在時刻が表示されている。だがこれがズレているのだ。
まずはこの画面を表示しているphpからスタート
これはURLから容易にうかがい知ることができる。
になる。
中をのぞいてみると$opという変数に格納される値によってswitch分で処理が分岐している。
新規ニュースを投稿するときは$op = "newarticle"になるので、
読むべき場所はindex.phpの428行目〜445行目となる。
そこの中に
include "storyform.inc.php";
という記述がある。
なので次に見るべきは同じディレクトリにあるstoryform.inc.phpになる。
で、次にstoryform.inc.phpをのぞいてみる。
すると114行目〜127行目の記述がそれっぽい。
どうも120行目と125行目の以下の記述が当たりのようだ。
printf(_AM_CURRENTTIME,formatTimestamp($time));
$timeは114行目を見ればわかるが
$time = time();
なのでphpのtime関数であることがわかる。
まずここでこのtime関数が何を返すか気になったので簡単なphpを書いて調べてみた。
するとtime()関数は日本標準時を取得してきた。
phpinfo()を見るとデフォルトのタイムゾーン設定がAsia/Tokyoになっているのでこれは問題ないだろう。
すると当然formatTimestamp($time)が怪しい。
なのでこの関数の定義を探す。
すると[xoops_root]/include/functions.phpにあることを発見
この189行目〜218行目までがそれの模様。
この関数は1〜3個の引数があるが今回は最初の1つしか渡されていない。
つまり残りは定義されたデフォルト値に従うわけだ。
この関数は主にswitch文による分岐処理が大半を占めるが、それはどのフォーマットで表示するかなので関係はない。
つまり192行目の以下の文が当たりだ
$usertimestamp = xoops_getUserTimestamp($time, $timeoffset);
で、$timeは第一引数なのでphpのtime()関数で取った値となる。
$timeoffsetは第三引数なのだが、今回は指定がないのでデフォルト値""が入る。
で、このxoops_getUserTimestamp関数はどこにあるかというと直上に定義されていた。
同ファイル内の170行目〜182行目がそれだ。
ここで各ユーザのタイムゾーンの設定を読み込み、
・・・まてよ。ひょっとして管理者のタイムゾーン設定がGMTになってたらどうなる?
180行目に以下のように書いてある。
$usertimestamp = intval($time) + (intval($timeoffset) - $xoopsConfig['server_TZ'])*3600;
問題はこの$timeoffsetの値だ。
これは173行目からの
if ($timeoffset == '') { if ($xoopsUser) { $timeoffset = $xoopsUser->getVar("timezone_offset"); } else { $timeoffset = $xoopsConfig['default_TZ']; } }
と記述されている。
つまり、ユーザのタイムゾーン設定がGMTなら0になる。。。
それを踏まえて180行目の引き算をすると。。。
(現在時刻)+((GMT)-(Asia/Tokyo(+9)))= (現在時刻)- 9
ということで原因判明。。。
結局設定ミスというオチ orz...