1

mktime 関数で興味深い問題が発生しています。以前にここで提供されたソリューションを見ましたが、解決または解決されたものはありませんでした (strotime は表示される結果を変更しません)。

私は月次レポートを持っており、ユーザーのためにできる限りエラーを防止するようにしています。そのため、1 か月と 1 年のみを要求しています。コードでレポートに最適な日を提供します。

私のフォームには月のドロップダウン選択があり、月の値は 2 桁の整数 (01、02 など) です。年は 4 桁で、ユーザーが手動で入力します。

すべてが 2038 年までうまく機能します... それはまだ先のことだと思いますが、プロジェクトは 20 年間のスコープを持つことになっているため、過去 2 年間で問題が発生しています。

フォームから情報を受け取る方法は次のとおりです。

$month = filter_var($_POST["month"], FILTER_SANITIZE_NUMBER_INT);
$year = filter_var($_POST["year"], FILTER_SANITIZE_NUMBER_INT);

次に、mktime を使用して月と年を日 (27 日) と結合します。

次に、MySQL が好む日付形式で変数に割り当てます。 $reportdate = date('Ymj',$timeStamp);

$month と $year の結果をエコーアウトしましたが、それらは正しく表示されていますが、$reportdate をエコーアウトすると、常に 12/31/1969 と表示されます。

03
2038
1969-12-31

何月を選んでも構いません。2037 年 12 月は完全に報告されますが、それを超えると失敗します。

これは修正可能なものですか、それともクッキーが崩れる方法だと言わざるを得ないのでしょうか...?

4

2 に答える 2

4

これは、タイムスタンプがオーバーフローしているためで、2038 年問題が原因です。

基本的に、整数は 2147483648 の最大値を保持できる符号付き 32 ビット数として表されます。したがって、UNIX タイムスタンプでは、これは秒単位の一定量であり、約 68 年です。

実際、Google は次のように教えてくれます。

(2^31) * seconds = 68.0511039 years

したがって、UNIX タイムスタンプは UNIX エポック (1970 年 1 月 1 日 00:00:00 UTC) からの時間です。つまり、32 ビットの UNIX タイムスタンプで表すことができる最大の日付は次の年になります。

1970 + ~68 = ~2038.

これらの日付をサポートする必要がある場合は、DateTimeそのような制限がないため、次のようにクラスを使用します。

$date = new DateTime( "now", new DateTimeZone( 'America/New_York'));
$date->setDate( $year, $month, 27);
// $date->setTime( 0, 0, 0);
echo $date->format('Y-m-j');
于 2012-07-02T20:03:17.853 に答える
0

上で説明したように、2038 年問題にmktime.

幸いなことに、これは修正可能です。mktime を使用しないでください。$reportdateを使用しない別の方法で値を構築するだけmktimeです。そのような:

 $reportdate = $year."-".$month."-27";
于 2012-07-02T20:12:15.623 に答える