メニューを閉じる

テクノモバイルグループ

メニューを開く

2019.06.25

プログラミング

MySQLから取得したDATE型をPHPで文字列に変換したら紀元前2年11月30日が表示された話

こんにちは。ZYです。

MySQL上から取得した値をJSONやCSVなどに文字列で出力したい、という時はあると思います。
その際に以下のようなPHPを書いてみると、

こんな出力に。

-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つでも当てはまる方は是非、詳細ページへ!
  • 自分でアプリを作ってみたい
  • ITで世の中にワクワクを生み出したい
  • 使いやすさ、デザインにこだわったWebサイトを開発したい

採用情報の詳細はこちら


Qangaroo(カンガルー)

  • 徹底した見やすさと優れた操作性で、テストの「見える化」を実現。
  • テストの進捗が見える。開発がスマートに進む。
  • クラウド型テスト管理ツール『Qangaroo(カンガルー)』
https://qangaroo.jp/

最近の記事

SNS共有

X CLOSE
X CLOSE
X CLOSE