【问题标题】:Why does this calendar break between the years 111 and 1753?为什么这个日历在 111 年和 1753 年之间中断?
【发布时间】:2013-07-16 14:42:21
【问题描述】:

我在这里写了一个 PHP 日历生成器,http://shodor.org/~amalani/portfolio/apprenticeship/summer/phpstuff/calendar.php,它可以工作,除了 111 和 1753 之间的年份。我确定问题出在这一行

$first=date('w',mktime(0, 0, 0, $month, 1,$year));

这决定了当月第一天的数字表示。这将返回 -1 作为日期,因此日历函数永远不会开始新的一周。

这里是所有代码

<?php
$date=getdate();


?>
<form action="calendar.php" method="POST">
    <input type='number' name='year' value=
    <?php if(isset($_POST['year'])){echo $_POST['year'];}else{echo $date['year'];}?>
    />
    <select name="month">

    <?php
        $m=1;
        for($x=60;$x<400;$x+=30){
            $month=jdmonthname($x,1);
            if(isset($_POST['month'])){
                $selected=($m==$_POST['month'])?"selected='selected'":"";
                echo $selected;
            }
            echo "
            <option value='$m' $selected>$month</option>";
            $m++;
        }
    ?>

    </select><br><br>
    <input type='submit'/>
</form>
<table border='1'>
<tr>
    <td>Sunday</td><td>Monday</td><td>Tuesday</td><td>Wednesday</td><td>Thursday</td><td>Friday</td><td>Saturday</td>
</tr>
<?php
    if(isset($_POST['month'])){
        $year=$_POST['year'];
        $month=$_POST['month'];
        $days=cal_days_in_month(CAL_GREGORIAN,$month,$year);

        //Get the numerical representation of the first day  of the month
        $first=date('w',mktime(0, 0, 0, $month, 1,$year));

        //This tabs over until the appropriate day is reached in the beginning of the month
        $week=1;
        //Output the month and year
        echo date('F',mktime(0,0,0,$month))." ".    $year." Calendar";
        //Start a new week
        echo "<tr>";

        for($x=1;$x<=$days;$x++){
            $day=date('w',mktime(0,0,0,$month,$x,$year));
            if($week==1){
                for($y=0;$y<$first;$y++){
                    echo "<td></td>";
                }
            }
            //Starts new week
            if($day==0){
                echo "</tr><tr><td>$x</td>";
            }else{
                echo "<td>$x</td>";
            }
            $week++;

        }
        echo "</tr>";

    }
?>
</table>

【问题讨论】:

  • 日历改革。不要尝试使用 1753 年之前的年份,因为在此之前各个地方对日历的概念完全不同。
  • @IgnacioVazquez-Abrams 但是为什么它不适用于
  • 我刚刚在您提到的范围内尝试了一年,使用您确定是问题的行,但我没有得到有效的一天。这可能取决于时区设置或 PHP 版本。
  • 无论如何都不会工作。 MySQL 的内部时间戳是一个 32 位有符号整数。除非您升级到具有 64 位 time_t 的 64 位版本,否则您不能表示 1901 年之前或 2038 年之后的日期。
  • @MarcB OP 不在任何地方使用 MySQL

标签: php date


【解决方案1】:

问题在于您对 mktime() 的使用

请注意php手册中的粗体部分

年份

年份的数字,可以是两位数或四位数字, 0-69 之间的值映射到 2000-2069 和 70-100 到 1970-2000。上 time_t 是 32 位有符号整数的系统,如当今最常见的那样, 年份的有效范围介于 1901 和 2038 之间。然而, 在 PHP 5.1.0 之前,这个范围被限制在 1970 到 2038 之间 系统(例如 Windows)。

您需要消除对 mktime() 的需求来解决此问题,可能通过使用 OOP Datetime class 这有其自身的限制,与小于 100 年有关

这个answer可以帮助你进一步理解问题

【讨论】:

  • 但是有吗?您可能有 a 数字作为日期返回,但由于公历直到 1582 年或任何时候才存在,所以谁能真正说 109 年的某个日期是星期二?在范围或有效年份之外,如果没有充分了解 php 内部结构和 c 数据类型来理解为什么它会滚动或不滚动,行为是不可预测的
【解决方案2】:

大多数系统(包括 mysql 和 php)都使用 unix 时间戳。这些时间戳是从 1970 年 1 月 1 日开始计数的整数值。根据整数大小(例如 32 位整数),日历的可用范围是有限的。

这解释了@Anigel 描述的范围。

【讨论】:

    猜你喜欢
    • 2012-02-23
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-16
    • 2016-07-30
    • 1970-01-01
    相关资源
    最近更新 更多