BST引发了日历日期的噩梦


BST causing a nightmare with calendar dates

我正在制作一个周视图日历,但到了10月28日,也就是时钟前进的时候,我遇到了问题。日历跳过一天

到目前为止我的代码。。。

//get viewed date from form and add either a week to it or take a week away
        if(isset($_POST['add_week'])){
                $last_week_ts = strtotime($_POST['last_week']);
                $display_week_ts = $last_week_ts + (3600 * 24 * 7);
        } else if (isset($_POST['back_week'])) {
                $last_week_ts = strtotime($_POST['last_week']);
                $display_week_ts = $last_week_ts - (3600 * 24 * 7);
        } else {
                //sets the current day as the first day of the week so no good
                /*$display_week_ts = floor(time() / (3600 * 24)) * 3600 * 24;*/
                //Does't account for british summer time so days are out after 28th October
                $display_week_ts = strtotime("Monday noon");
        }
              $week_start = new DateTime(date("Y-m-d", $display_week_ts));
           for ($i = 0; $i < 7; $i++)  
       {
            echo '<td class="day">';
            $current_day_ts = $display_week_ts + ($i * 3600 *24);
            $daily_date = date('d-m-Y', $current_day_ts);
            $StartDate =  date('d', $current_day_ts);
            $MonthName = date('m', $current_day_ts);
            $Year = date('Y', $current_day_ts);
                            echo $daily_date;
                            echo '</td>';
        }

$week_start包含日历中当前查看的周开始的值。第一次打开时显示当前星期。如果按下"下一周"按钮,则会将一周添加到$week_start值中。目前保存在表中的隐藏字段中,并在提交时返回。我还尝试将$week_start存储为会话中的TimeDate()对象

        $week_start = new DateTime(date("Y-m-d", $display_week_ts));
        $S_SESSION['week_start'] = $week_start;

但当我试图回拨会话并使用它时,将向前移动一周

        $week_start = $S_SESSION['week_start'];
        $week_start->modify('+1 week');

我得到错误"Warning:DateTime::modify()[DateTime.modify]:DateTime对象的构造函数未正确初始化"。经过一些挖掘,我发现DateTime似乎在5.3之前不支持会话,我使用的是5.2.17

如果有人能帮我锻炼,让变量$week_start成为一周中由$display_week_ts表示的第一天,这样BST就不会造成问题,我将不胜感激。我已经在这方面扎实地工作了3天了,现在

使用date_default_timezone_set('UTC');

$week_start->setTimezone(new DateTimeZone('UTC'));

这就是问题所在:

$display_week_ts = $last_week_ts + (3600 * 24 * 7);

由于您正在经历夏令时变更,因此一周的时间是不是3600*24*7秒,实际上是3600*24*6600秒。你从夏令时的轮班中损失了一个小时,所以你实际上提前了8天。你前一周的计算也是如此——它会损失一个小时,只倒退6天。

为了确保这些类型的计算是安全的,您应该使用DateTime对象,并为这类计算提供适当的DateIntervals。它会为您考虑夏令时的变化。

例如

$now = new DateTime();
$now->setTimeZone(new DateTimeZone('Whatever/Wherever'));
$oneweek = new DateInterval('P7D');
$nextweek = $now->add($oneweek);
$lastweek = $now->sub($oneweek);