2024.11.14
いまさらNode.jsを知ろう~環境構築も~
2019.06.25
プログラミングMySQLから取得したDATE型をPHPで文字列に変換したら紀元前2年11月30日が表示された話
こんにちは。ZYです。
MySQL上から取得した値をJSONやCSVなどに文字列で出力したい、という時はあると思います。
その際に以下のようなPHPを書いてみると、
$dateTimeObj = new \DateTime($value); $dateStr = $dateTimeObj->format('Y-m-d'); var_dump($dateStr);
こんな出力に。
-0001-11-30
西暦マイナス1年、紀元前2年の11月30日が出力されます。古代ローマ帝国初代皇帝アウグストゥスが活躍した時代です。
なんだこりゃ。と戸惑うのですが、これはMySQLでいうとDATE型のカラムに「0000-00-00 00:00:00」が入っていた場合に、それをそのまま文字列としてDateTimeを初期化。再度フォーマットしたい際に、PHPが表示する日付。
PHPのdate formatには以下のような仕様があります。出典:公式PHP マニュアル
シンボル dd と DD について、 オーバーフローやアンダーフローすることができます。 つまり、 0 日は先月の最終日の意味になりますし、 オーバーフローすると翌月に繰り越しになります。 このルールにより、”2008-08-00″ は “2008-07-31” と同一になり、 “2008-06-31” は “2008-07-01” と同一になります ( 6 月は 30 日までしかないので)。
では、”0000-00-00″の場合はどうなるかということも実例で書いています。
文字列 “0000-00-00” についても同様に “-0001-11-30” へと変形されます。 (ISO 8601 における -1 年は、予測的グレゴリオ暦 (proleptic Gregorian calendar) で言うところの紀元前 2 年になります。)
「〇月〇日の~日前」みたいな計算をする際に存在しない日付を指定しても、計算してくれる親切仕様が紀元前まで適応されたわけです。
ちなみに、この現象に対する正しい対処法は、「そもそもMySQLのDATE型に”0000-00-00 00:00:00″を入れない」です。
ついでにいえば、MySQL5.7以降であれば、デフォルトNO_ZERO_DATE, NO_ZERO_IN_DATEモードがONになっているため、”0000-00-00 00:00:00″を入れることが出来ないようになっているので、こんな現象も起こらない気がします。
【記事への感想募集中!】
記事への感想・ご意見がありましたら、ぜひフォームからご投稿ください!【テクノデジタルではエンジニア/デザイナーを積極採用中です!】
下記項目に1つでも当てはまる方は是非、詳細ページへ!Qangaroo(カンガルー)
【テクノデジタルのインフラサービス】
当社では、多数のサービスの開発実績を活かし、
アプリケーションのパフォーマンスを最大限に引き出すインフラ設計・構築を行います。
AWSなどへのクラウド移行、既存インフラの監視・運用保守も承りますので、ぜひご相談ください。
詳細は下記ページをご覧ください。
最近の記事
タグ検索