PHP で日付や時刻を任意のフォーマットで出力する方法を解説します。「2000年01月01日」とか「00/01/01」とか、そーゆーことです。
3通りの方法があるので、どれを使うべきかなんて話もしていきます。
(1) date 関数で日付・時刻をフォーマットする方法
ひとつめは date
関数を使う方法です。書き方は次のとおりです。
date('フォーマット文字列', Unixタイムスタンプ)
現在の日時をフォーマットする
Unixタイムスタンプを省略すると、現在の日時を指定したことになります。
$date = date('Y年m月d日 H時i分s秒');
echo $date; //現在の日時が表示される
Unixタイムスタンプを渡してフォーマットする
Unixタイムスタンプを渡すと、任意の日時をフォーマットすることができます。
$date = date('Y年m月d日 H時i分s秒', 946652400);
echo $date; //2000年01月01日 00時00分00秒 と表示される
日付文字列を渡してフォーマットする
Unixタイムスタンプではなく、日時を表す文字列を渡したいときは、strtotime
関数を使います。strtotime
は日時を表す文字列をUnixタイムスタンプに変換する関数です。
$date = date('Y年m月d日 H時i分s秒', strtotime('2000-01-01 09:41:00'));
echo $date; //2000年01月01日 09時41分00秒 と表示される
strtotime
はどんな日付文字列でも認識できるわけではなく、例えば12th January 2000
は認識できるけど2000年1月12日
は認識できません。
どんな日時の書式がサポートされているかは下記で確認してください。
実際のところ、MySQL のDATETIME型YYYY-MM-DD hh:mm:ss
はサポートしますよということを知っておけば問題ないと思います。
フォーマット文字
フォーマット文字列で使える主なフォーマット文字は次のとおりです。
フォーマット文字 | 説明 | 戻り値 | |
---|---|---|---|
年 | Y | 4桁の西暦。 | 1999 , 2022 など |
y | 2桁の西暦。 | 99 , 22 など | |
L | うるう年かどうか。 | 1 (うるう年)、0 (うるう年でない) | |
月 | m | 月を表す数字。先頭に0をつける。 | 01 から12 |
n | 月を表す数字。先頭に0をつけない。 | 1 から12 | |
F | 月を表す英語。 | January からDecember | |
M | 月を表す3文字の英語。 | Jan からDec | |
t | その月の日数(その月の最終日) | 28 から31 | |
日 | d | 日を表す2桁の数字。先頭に0をつける。 | 01 から31 |
j | 日を表す数字。先頭に0をつけない。 | 1 から31 | |
曜日 | D | 曜日を表す3文字の英語。 | Mon からSun |
l | 曜日を表す英語。 | Monday からSunday | |
w | 曜日を表す数字。 | 0 (日曜)から6 (土曜) | |
時 | g | 12時間単位。先頭に0をつけない。 | 1 から12 |
G | 24時間単位。先頭に0をつけない。 | 0 から23 | |
h | 12時間単位。先頭に0をつける。 | 01 から12 | |
H | 24時間単位。先頭に0をつける。 | 00 から23 | |
a | 午前/午後。小文字。 | am ,pm | |
A | 午前/午後。大文字。 | AM ,PM | |
分 | i | 先頭に0をつける。 | 00 から59 |
秒 | s | 先頭に0をつける。 | 00 から59 |
上記以外のフォーマット文字は下記のページで確認してください。
無料で利用できるプログラミング学習サービスをお探しならば Code Lesson はいかがでしょうか。プロのエンジニアが監修した学習ロードマップで効率的に学習、AIに質問、最後にクイズで理解度をチェックできます。
(2) DateTime クラスで日付・時刻をフォーマットする方法
ふたつめが DateTime
クラスの format
メソッドを使う方法です。次のように書きます。
$date = new DateTime('日付文字列');
$date->format('フォーマット文字列');
サポートされる日付文字列は strtotime
関数と同じです。日付文字列を省略すると、現在の日時を指定したことになります。
フォーマット文字は date
関数と同じです。
使用例です。
$date = new DateTime('2000-01-01 09:41:00');
echo $date->format('Y年m月d日 H時i分s秒'); //2000年01月01日 09時41分00秒 と表示される
(3) DateTimeImmutable クラスで日付・時刻をフォーマットする方法
3つめは DateTimeImmutable
クラスです。
DateTime
クラスとほぼ同じ動作をします。使い方はまったく同じです。唯一違うところは、DateTime
はミュータブルなのに対して、DateTimeImmutable
はイミュータブルだということです。以上(冷たい)。
ミュータブルとは、オブジェクトの作成後にその状態を変えることができること、イミュータブルとはその状態を変えることができないことだそうです。
なんかよく分からないので実験してみましょう。
//DateTime クラス
$date = new DateTime('2000-01-01');
echo $date->modify('+10 days')->format('Y-m-d'); //10日足すと 2000-01-11 と表示される
echo $date->modify('+5 days')->format('Y-m-d'); //5日足すと 2000-01-16 と表示される
//DateTimeImmutable クラス
$date = new DateTimeImmutable('2000-01-01');
echo $date->modify('+10 days')->format('Y-m-d'); //10日足すと 2000-01-11 と表示される
echo $date->modify('+5 days')->format('Y-m-d'); //5日足すと 2000-01-06 と表示される
おわかりいただけただろうか。1回目のmodify
はどちらも同じ結果なのに、2回目は違ってます。DateTime
クラスでは1回目のmodify
で$date
オブジェクトが書き換えられたのに対して、DateTimeImmutable
では書き換えられなかったということです。
どっちの動作が好きですか?私はDateTimeImmutable
のほうが好きです。クラス名が長いので敬遠されがちですが、日時の計算をする場合はDateTimeImmutable
のほうが意図した動作をしてくれそうです。
曜日を日本語で表示する方法
フォーマット文字のセクションではあえて触れませんでしたが、曜日を英語でしか表示できないことに不満を感じてはいませんか?激おこぷんぷん丸(死語)ではありませんか?私は激おこスティックファイナリアリティぷんぷんドリームです(やかましい)。
曜日の日本語表示、やってみましょう。
//日本語の曜日を配列に入れる
$week_jp = array('日','月','火','水','木','金','土');
//date関数の場合
echo $week_jp[date('w')] ;
//DateTimeクラスの場合
$date = new DateTime();
echo $week_jp[$date->format('w')];
どれを使うべきか
日付・時刻をフォーマットする方法として、date
関数、DateTime
クラス、DateTimeImmutable
クラスの3つを紹介しましたが、どれを使うのがよいのでしょうか。
結論からいうと、DateTimeImmutable
を使いましょう。
2038年問題
2038年問題とは2038年1月19日にコンピュータが日時を正しく処理できなくなって誤動作する可能性がある問題です。Y2K問題と似たようなものです。
PHP ではdate
関数やstrtotime
関数がこの2038年問題の影響を受けます。もうちょい詳しく言うと、64ビット版PHPでは問題ないのですが、32ビット版PHPでは死亡します。
DateTime
クラス、DateTimeImmutable
クラスは2038年問題の影響を受けません。
ということなので、date
関数よりもDateTime
、DateTimeImmutable
クラスを使っておくほうが安全といえます。
速度の比較
date
関数、DateTime
クラス、DateTimeImmutable
クラスの3つの方法の速度を比較してみました。
現在の日時をフォーマットする場合
//date
$start = microtime(true);
for ($i = 0; $i < 100000; $i++) {
$date = date('Y年m月d日 H時i分s秒');
}
echo $time = microtime(true) - $start;
//DateTime
$start = microtime(true);
for ($i = 0; $i < 100000; $i++) {
$date = new DateTime();
$date->format('Y年m月d日 H時i分s秒');
}
echo $time = microtime(true) - $start;
//DateTimeImmutable
$start = microtime(true);
for ($i = 0; $i < 100000; $i++) {
$date = new DateTimeImmutable();
$date->format('Y年m月d日 H時i分s秒');
}
echo $time = microtime(true) - $start;
date関数 | DateTimeクラス | DateTimeImmutableクラス | |
---|---|---|---|
1回目 | 0.06986403465271 秒 | 0.082677841186523 秒 | 0.083433866500854 秒 |
2回目 | 0.069616079330444 秒 | 0.085881948471069 秒 | 0.082491874694824 秒 |
3回目 | 0.077422142028809 秒 | 0.084145069122314 秒 | 0.082370042800903 秒 |
引数を渡さずに現在の日時をフォーマットする場合は、date
関数がやや早くて、DateTime
、DateTimeImmutable
クラスが互角という結果でした。
日付文字列を渡してフォーマットする場合
$str = '2000-01-01 09:41:00';
//date
$start = microtime(true);
for ($i = 0; $i < 100000; $i++) {
$date = date('Y年m月d日 H時i分s秒', strtotime($str));
}
echo $time = microtime(true) - $start;
//DateTime
$start = microtime(true);
for ($i = 0; $i < 100000; $i++) {
$date = new DateTime($str);
$date->format('Y年m月d日 H時i分s秒');
}
echo $time = microtime(true) - $start;
//DateTimeImmutable
$start = microtime(true);
for ($i = 0; $i < 100000; $i++) {
$date = new DateTimeImmutable($str);
$date->format('Y年m月d日 H時i分s秒');
}
echo $time = microtime(true) - $start;
date関数 | DateTimeクラス | DateTimeImmutableクラス | |
---|---|---|---|
1回目 | 0.11821389198303 秒 | 0.11678004264832 秒 | 0.11568713188171 秒 |
2回目 | 0.11990690231323 秒 | 0.1165189743042 秒 | 0.11692309379578 秒 |
3回目 | 0.11591219902039 秒 | 0.11851000785828 秒 | 0.11643695831299 秒 |
日付文字列を渡してフォーマットする場合は、3つともほぼ同じでした。
つまり、
- 2038年問題を考慮して
date
関数は使わない。 - 日時の計算をするならば
DateTime
よりもDateTimeImmutable
のほうが安全。 - 処理速度は3つともほとんど変わらない。
ということで、DateTimeImmutable
を使いましょうということに決定しました。以上です。
でわでわ
無料で利用できるプログラミング学習サービスをお探しならば Code Lesson はいかがでしょうか。プロのエンジニアが監修した学習ロードマップで効率的に学習、AIに質問、最後にクイズで理解度をチェックできます。
コメント