素の PHP を扱う技術は PHP 言語の基幹の方針転換や PHP 自体の衰退が来るまで使い続けられる技術であり長持ちします。またプログラムをフレームワークやライブラリに依存せず書くことができるので色々と使いまわせます。加えてその素の PHP のコードが読みやすく、かつ短いのであればフレームワークのエイリアスを使わなくともさほど困りません。
素の PHP を使った日時文字列の表現は date 関数と strtotime 関数を使うことで大部分をカバーできます。
PHP: date – Manual
PHP: strtotime – Manual
date 関数は与えられたフォーマットでタイムスタンプを年月日曜日時分秒を細かく指定して文字列化します。strtotime 関数は与えられた文字列とタイムスタンプから与えられた内容に対応するタイムスタンプを返します。
これらは例えば次の様に使えます。
// 昨日の日付を Y-m-d 表記で出力 // もし今日が2021年1月26日ならば 2021-01-26 となります echo date('Y-m-d', strtotime('yesterday'));
この様に strtotime 関数で目的の日時のタイムスタンプを取得し、date 関数でフォーマットを整えます。
date 関数と strtotime 関数を自在に操るために必須の PHP 公式ドキュメントが次です。
PHP: DateTime::format – Manual
PHP: サポートする日付と時刻の書式 – Manual
PHP: DateTime::format – Manual には date 関数に渡せるフォーマットがあります。無理に算術したり、文字列置換する前に一通り見ておくと案外フォーマットとして用意されている場合があり作業が省ける機会になります。PHP: サポートする日付と時刻の書式 – Manual には strtotime 関数に渡せる文字列形式が記述されています。
この方式の落とし穴はタイムゾーンです。date 関数、strtotime 関数はともにタイムゾーンに関する指定を持ちません。PHP 内部で設定されたタイムゾーンに従います。このため date_default_timezone_get, date_default_timezone_set の両関数で PHP 実行中のデフォルトタイムゾーンを設定する必要がある場合があります。
もっとも、使用環境は国内のみで PHP のタイムゾーンも Asia/Tokyo になっている、などといったタイムゾーンが決まり切っている場合はそう問題になりません。
PHP: date_default_timezone_get – Manual
PHP: date_default_timezone_set – Manual
date と strtotime を使ったコード例が次です。
// 今日を日本語らしい表記で返します。例. 今日を2021年1月4日とすると"2021年1月4日" date('Y年n月j日'); // 昨日をMySQLで通る表記で返します。例. 今日を2021年1月4日とすると"2021-01-04" date('Y-m-d', strtotime('yesterday')); // 直前の日曜日をMySQLで通る表記で返します。例. 今日を2021年1月7日(木)とすると"2021-01-03" // date('w') で日曜日を0とした今日の曜日の番号を取得。 // - date('w') dayすることで曜日が0となり直近の日曜日になります。 date('Y-m-d', strtotime('-'.date('w').' day'))); // 直前の月曜日をMySQLで通る表記で返します。例. 今日を2021年1月7日(木)とすると"2021-01-04" // date('w') で日曜日を0とした今日の曜日の番号を取得。 // - (date('w') + 1) dayすることで曜日が1となり直近の月曜日になります。 // 同様に日月火水木金土のどれでも取れます date('Y-m-d', strtotime('-'.(date('w') + 1).' day'))); // 先月の最終日をMySQLで通る表記で返します。例. 今日を2021年3月7日とすると"2021-02-28" // strtotime で先月のどこかのタイムスタンプを取得 // Y-m-t で最終日をとります。 t はおそらく tail の略です。 date('Y-m-t', strtotime('- 1 month')); // 先月の初日をMySQLで通る表記で返します。例. 今日を2021年3月7日とすると"2021-02-01" // 日付を書式を介さず直接 01 とします。 // ↑と合わせてある月の最初から最後までの範囲を表現できます。Y-m を外部から渡して任意月のほげほげな処理ができます。 date('Y-m-01', strtotime('- 1 month')); // 現在から10年前までのランダムな日時を MySQL で通る表記で返します。 // なかなか高速なので大量のテストデータを作る時に便利です。実際に使うときは$from, $to をループの外に置き、dateとrandをループの中に置くことでループ中の処理を減らします。 $from = strtotime('- 10 years'); $to = strtotime('now'); date('Y-m-d H:i:s', rand($from. $to));