WordPressでカスタムフィールドを使って日付を入力させたりする、なんてことはよくある話だと思います。
ただしWordPressでは、wp-settings.phpで以下のコードが実行されて、タイムゾーンがUTCに変更されます。
date_default_timezone_set( 'UTC' );
なので、PHPのtimezoneの設定がどうなっていようと、UTCになってしまいます。なので、unixtime等を扱うときはかなり注意が必要だったりします。
対処法
その1 時差分を追加
get_option('gmt_offset')で、WordPressで設定されているUTCとの時差が取得できますので、それをmktimeや、strtotimeの返却する値に追加します。
<?php
function local_mktime() {
$defaults = array(
date("H"),
date("i"),
date("s"),
date("n"),
date("j"),
date("Y"),
-1,
);
$args = func_get_args();
$param = array_merge( $defaults, $args );
$offset = get_option('gmt_offset') * 60 * 60;
return mktime( $param[0], $param[1], $param[2], $param[3], $param[4], $param[5], $param[6]) + $offset;
}
function local_strtotime( $time, $now = null ) {
$offset = get_option('gmt_offset') * 60 * 60;
if( $now == null ) {
$now = time();
}
return strtotime( $time, $now ) + $offset;
}
その2 一時的にタイムゾーンを変更する
date_default_timezone_get()で現在のタイムゾーンを取得、date_default_timezone_set( $timezone )で、タイムゾーンを変更できます。なので、これを使って、一時的にタイムゾーンを変更できます。
<?php
function local_mktime() {
$defaults = array(
date("H"),
date("i"),
date("s"),
date("n"),
date("j"),
date("Y"),
-1,
);
$args = func_get_args();
$param = array_merge( $defaults, $args );
$internal_timezone = date_default_timezone_get();
date_default_timezone_set( 'Asia/Tokyo' );
$timestamp = mktime( $param[0], $param[1], $param[2], $param[3], $param[4], $param[5], $param[6]);
date_default_timezone_set( $internal_timezone );
return $timestamp;
}
function local_strtotime( $time, $now = null ) {
$offset = get_option('gmt_offset') * 60 * 60;
if( $now == null ) {
$now = time();
}
$internal_timezone = date_default_timezone_get();
date_default_timezone_set( 'Asia/Tokyo' );
$timestamp = strtotime( $time, $now );
date_default_timezone_set( $internal_timezone );
return $timestamp;
}
時差の絡んだ日付の変換はかなりややこしいです。timestampにする必要が無いところはstr_replace等で数値文字列に変換して対処する等する方が、バグなどを埋め込まずに済みそうです。