我对mktime函数有一个有趣的问题。我之前看过这里提供的解决方案,似乎没有解决或帮助(strotime不会改变我看到的结果)。
我有一份月度报告,我试图尽可能为我的用户提供防错功能,因此我只需要一个月和一年的时间。我将在代码中为报告提供最好的一天。
我的表单有月份的下拉选项,月份的值是两位数的整数(01,02等)。年份是四位数,由用户手动填写。
直到2038年,每一件作品都很好......我知道,这还有很长的路要走,但该项目应该有20年的范围,所以在过去的两年里,我一直在运行问题。
以下是我从表单中收到信息的方式:
$month = filter_var($_POST["month"], FILTER_SANITIZE_NUMBER_INT);
$year = filter_var($_POST["year"], FILTER_SANITIZE_NUMBER_INT);
然后,我使用mktime将月份和年份与我的日期(27日)结合起来: $ timeStamp = mktime(0,0,0,$ month,27,$ year);
然后我将它分配给MySQL喜欢的日期格式的变量: $ reportdate = date('Y-m-j',$ timeStamp);
我已经回应了$ month和$ year的结果,他们正确地遇到了,但是当我回应$ reportdate时,它总是说是12/31/1969。
03
2038
1969-12-31
我选择的月份无关紧要。 2037年12月完美地报道,除此之外的任何事情都失败了。
这是可修复的东西还是我不得不说饼干崩溃的方式......?
答案 0 :(得分:4)
这是因为您的时间戳溢出,是由year 2038 problem。
引起的基本上,整数表示为带符号的32位数字,它可以保存最大值2147483648.因此,在UNIX时间戳中,这是一个特定的秒数,大约是68年。
事实上,谷歌告诉我:
(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');
答案 1 :(得分:0)
如上所述,您使用mktime
来解决2038问题。
幸运的是,它是可以修复的:不要使用mktime。只需以另一种方式构建$reportdate
值,即不使用mktime
。如:
$reportdate = $year."-".$month."-27";