PHPの日時に関連する関数の制限

このエントリーをはてなブックマークに追加
はてなブックマーク - PHPの日時に関連する関数の制限
LINEで送る
Pocket

問題意識

PHPが表現できる日付に制限があり、1800年といった表記をdate関数から
出力できないため、1800年から2500年程度の時間表現を行う方法を導く。

実験内容

まず、制限値の詳細を知るために
1.date関数の第2引数に与えられるタイムスタンプの範囲を調べる。
2.strtotime関数の引数に指定できる時間の範囲を調べる。

実験結果

1.date関数の第2引数にタイムスタンプとして指定した場合:
最小値:-2147483648(1901-12-14 05:45:52)
最大値: 2147483647 (2038-01-19 12:14:07)

2.strtotime関数の引数に時間を指定した場合
最小値: 1901-12-14 05:45:52
最大値: 2038-01-19 12:14:07

まとめ

32ビット環境において、
PHPで整数を扱う場合は-2^31から2^31-1しか扱えない。

次の問題意識

pearのDateクラスは有効か調査する。

実験内容

2.1 コンストラクタに2147483647を指定し、
秒を追加してゆき、getDateを表示してみて
想定する結果との差異を検証。

2.2
コンストラクタに-2147483648を指定し、
秒を減らしてゆき、getDateを表示してみて
想定する結果との差異を検証。

実験結果

2.1
9999-12-31 23:59:59 まで表示可能その後に1秒を足すと現在時刻に初期化される。

Date.phpのソースコードを追ってみると、年・月・日や時・分・秒はそれぞれ変数になっている。
なぜ、999年までしかいけないかというと、addSpanメソッドで無理矢理4桁に処理されているため。

2.2
999-12-31 23:59:59 まで表示可能。その後に1秒を引くと9909-12-31 23:59:58となる

まとめ

西暦が4桁ならば正常に動作。

次の問題意識

3.1 mktimeのサポートする範囲

実験結果

3.1
年の入力に制限がある。
年の入力範囲:0-38,70-110,1903-2038

まとめ

mktimeは1903年から2038年まで。

次の問題意識

4.checkdateのサポートする範囲

実験結果

4.西暦1年1月1日から、西暦32767年12月31日

まとめ

西暦は16ビット分。チェックには利用可能。

次の問題意識

mktime,strtotimeが表現できる日時に制限があるため、目的の範囲を
サポートする日時のvalidation方法はあるのか。

調査

・symphonyはmktime,strtotimeを利用してチェック。
・zend frameworkはcheckdateにて日付をチェック。
・Mapleはcheckdateにて日付のみチェック。

結論

PHPのネイティブ関数でサポートする日時表記の積集合部分は
1901-12-14 05:45:52から2038-01-19 12:14:07である。

日付のチェックはcheckdateを使えば実用に問題はない。

時間のチェックは自分で書く。

ネイティブでサポートされていない日時表記のためにはPearのDateクラスを利用すれば
1000年から9999年まで表現できる。

このエントリーをはてなブックマークに追加
はてなブックマーク - PHPの日時に関連する関数の制限
LINEで送る
Pocket

matsubokkuri

Please feel free to contact me via e-mail, twitter and facebook!

あわせて読みたい

コメントを残す