【问题标题】:time() and date() problems after time change (DST - standard)时间更改后的 time() 和 date() 问题(DST - 标准)
【发布时间】:2011-08-23 06:55:16
【问题描述】:

在 PHP 中,我想输出一个 HTML 选项列表,其中包含未来 14 天的日期。

这些约会总是在 18 点:

$today_day = date('d');
$today_month = date('m');
$today_year = date('Y');
$date_entry = mktime(18, 00, 00, $today_month, $today_day, $today_year);
$optionsStr = '<select name="date">';
for ($d = 1; $d < 14; $d++) {
    $date_entry_temp = $date_entry+86400*$d;
    $optionsStr .= '<option value="'.$date_entry_temp.'">'.date('d.m.Y', $date_entry_temp).'</option>';
}
$optionsStr .= '</select>';
echo $optionsStr;

然后,用户可以从这些日期之一中进行选择并提交表单。然后将选择的时间戳插入到数据库中。

所以我的数据库中有一些条目。

在另一个页面上有一个当前约会的列表:

mysql_query("SELECT id, name FROM appointments WHERE date_time = ".time());

所以在 18 点应该有一些输出,因为数据库中有当天的条目。在时间从 DST 更改为标准时间之前,这非常有效,反之亦然。那么,确实是错的:

约会分别显示太晚或太早一小时。

我该如何解决这个问题?

【问题讨论】:

  • 请停止在标题中写标签。你的 112 道题中的很多题都答对了。
  • 对不起,我不知道是为了避免这种情况。对不起,我应该更仔细地阅读指南。
  • 18 点,我确定您的意思是 1800 小时。 (一千八百小时)
  • 不,我的意思是我说的:18 点,也就是下午 6 点。

标签: php date time dst


【解决方案1】:

当依赖时间时,请确保您始终设置一个时区,无论是在您的 php.ini 中还是在您的代码中。对于数据库条目,您无能为力,如果您按时间或日期对它们进行排序,它们最终将被交错,因为新日期早于您在时间更改之前的最后一个条目的日期。

【讨论】:

  • 我总是使用 date_default_timezone_set('Europe/Berlin') 在我的代码中设置时区。并且不应该有跳跃或重叠,因为时间戳中的时间总是连续的。
【解决方案2】:

您的时区似乎有问题:http://dev.mysql.com/doc/refman/5.0/en/timestamp.html 我会选择时间,从您的本地时间转换为 UTC,然后将其放入数据库中。如果您将其读出,请从 UTC 转换回您的本地时间。

【讨论】:

  • 因为我使用 INT(10) 列作为我的时间戳,所以时区应该没有问题,对吧? MySQL无法知道这是一个时间戳,所以错误一定是在PHP中。
  • 顺便说一句,这并没有让计算变得更容易。
【解决方案3】:

mktime() 创建一个 unix 时间戳。 unix 时间戳是从 1970 年 1 月 1 日 00:00:00 GMT +0000 开始的秒数。 (格林威治时间)

当您将时区设置为“欧洲/柏林”时,时区为 GMT+0100(冬季)或 GMT+0200(夏季)。这意味着当您有 DST 时,您预约的格林威治时间会改变一小时。这意味着更改前的第一个约会和更改后的下一个约会之间的时间不是 24 小时,而是 23 或 25。但是,您可以通过添加 86400 秒 = 24 小时来生成约会。

您可以改用 DateTime 对象和 add() 方法。它将 DST 更改考虑在内。

// create a new date object with todays date
$date = new DateTime();
// set the time to 18:00
$date->setTime(18,0,0);
$optionsStr = '<select name="date">';
for ($i = 0; $i < 14; $i++) {
    // add 1 day
    $date->add(new DateInterval('P1D'));
    $optionsStr .= '<option value="'.$date->format('U').'">'.$date->format('d.m.Y').'</option>';
}
$optionsStr .= '</select>';
echo $optionsStr;

更多信息请参见http://www.php.net/manual/en/datetime.add.php

【讨论】:

    【解决方案4】:

    您的主要问题是您没有在 GMT 日期工作。这是一篇精彩的帖子,重点介绍了由此产生的陷阱:

    http://derickrethans.nl/storing-date-time-in-database.html

    您应该做的是,将您的约会日期时间存储在 UTC 时区,比较 UTC 时区的日期时间,并将日期时间显示给您(确定)或他们(理想)首选时区的用户。

    【讨论】:

    • 实际上,原始发布者已经以UTC存储时间戳,而您链接的文章建议相反:将时间与时区一起存储在当地时间。 (“本地”是指“在活动地点”。通常活动是在特定地点的特定时间,而不是在特定的格林威治时间)
    猜你喜欢
    • 2013-09-29
    • 2015-01-11
    • 2011-12-22
    • 2021-03-10
    • 2017-07-09
    • 2010-09-20
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    相关资源
    最近更新 更多