MySQL 夏令时信息似乎不正确.如何确保它在 Windows 中是最新的?



我发现我的程序中有一个错误是由MySQL的UNIX_TIMESTAMP((函数在给定相同的输入时向PHP的strtotime((返回不同的值引起的。

然后我发现错误发生的日期恰好是夏令时在我的时区生效的日期。

所以我需要知道为什么PHP知道夏令时开始的日子,而MySQL不知道。 PHP和MySQL不应该从操作系统中获取时区和夏令时信息吗?

操作系统是Windows 7,根据Windows Update程序,它是最新的补丁。

这是我的代码:

// Checking timezones in MySQL and PHP.
echo "<pre>n";
echo "date_default_timezone_get(): " . date_default_timezone_get() . "n";
echo "date('P'): " . date('P') . "n";
echo "MySQL timezone: " . $sqlObj->fetchField('SELECT IF(@@session.time_zone="SYSTEM", @@system_time_zone, @@session.time_zone)') . "n";
// Testing MySQL and PHP conversion to unix timestamp for specific datetime values.
for ($hour = 0; $hour < 5; ++$hour)
{
$timeString         = '2018-10-07 ' . (($hour < 10)? '0': '') . "$hour:00:00";
$timestampFromMySql = $sqlObj->fetchField('SELECT UNIX_TIMESTAMP(?)', array($timeString));
$timestampFromPhp   = strtotime($timeString);
echo " * timestring        : $timeStringn";
echo "   timestampFromMySql: $timestampFromMySqln";
echo "   timestampFromPhp  : $timestampFromPhpn";
// Checking daylight savings status for the date in question in PHP.
echo "   date('I', $timestampFromMySql): " . date('I', $timestampFromMySql) . "n";
echo "   date('I', $timestampFromPhp  ): " . date('I', $timestampFromPhp  ) . "n";
echo "   difference: " . ($timestampFromMySql - $timestampFromPhp) . "n";
}
echo "</pre>n";

这是输出。 请注意,PHP 和 MySQL 在凌晨 3 点报告的 unix 时间中出现了 3600 秒或一小时的差异。

date_default_timezone_get(): Australia/Melbourne
date('P'): +10:00
MySQL timezone: +10:00
* timestring        : 2018-10-07 00:00:00
timestampFromMySql: 1538834400
timestampFromPhp  : 1538834400
date('I', $timestampFromMySql): 0
date('I', $timestampFromPhp  ): 0
difference: 0
* timestring        : 2018-10-07 01:00:00
timestampFromMySql: 1538838000
timestampFromPhp  : 1538838000
date('I', $timestampFromMySql): 0
date('I', $timestampFromPhp  ): 0
difference: 0
* timestring        : 2018-10-07 02:00:00
timestampFromMySql: 1538841600
timestampFromPhp  : 1538841600
date('I', $timestampFromMySql): 1
date('I', $timestampFromPhp  ): 1
difference: 0
* timestring        : 2018-10-07 03:00:00
timestampFromMySql: 1538845200
timestampFromPhp  : 1538841600
date('I', $timestampFromMySql): 1
date('I', $timestampFromPhp  ): 1
difference: 3600
* timestring        : 2018-10-07 04:00:00
timestampFromMySql: 1538848800
timestampFromPhp  : 1538845200
date('I', $timestampFromMySql): 1
date('I', $timestampFromPhp  ): 1
difference: 3600

谷歌告诉我,墨尔本的2018年夏令时将于10月7日星期日凌晨2:00开始,时钟将向前移动一小时。 因此,2018 年 10 月 7 日凌晨 2 点实际上与 2018 年 10 月 7 日凌晨 3 点相同,因此我在上面的脚本输出中从 PHP 观察到的行为是意料之中的。 MySQL的行为似乎是不正确的。

谁能告诉我如何确保MySQL具有与夏令时有关的最新信息?

我还发现mysql.time_zone表都是空的。 这是否意味着MySQL没有时区信息,或者是否意味着MySQL的时区信息来自操作系统?

它是MySQL中UNIX_TIMESTAMP函数的已知"功能">

https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html

注意:如果使用 UNIX_TIMESTAMP(( 和 FROM_UNIXTIME(( 进行转换 在时间戳值和 Unix 时间戳值之间,转换为 有损,因为映射在两个方向上不是一对一的。为 例如,由于本地时区更改的约定,它是 两个 UNIX_TIMESTAMP(( 可以将两个时间戳值映射到 相同的 Unix 时间戳值。FROM_UNIXTIME(( 会将该值映射回 只有一个原始时间戳值。下面是一个示例,使用 CET 时区中的时间戳值:

漫游 - 仅在PHP中使用时间函数,MySQL仅用于存储(日期时间格式(

相关文档在这里: https://dev.mysql.com/doc/refman/5.5/en/time-zone-upgrades.html

关键句子是:

"如果MySQL服务器的时区设置为SYSTEM,则操作系统时间会影响MySQL服务器用于时间的值">

"如果您在MySQL中使用命名时区,请确保mysql数据库中的时区表是最新的。

稍后的文档指出,如果mysql.time_zone_name表为空,则没有人可以使用命名时区,并且您无需更新表。


因此,要强制MySQL使用时区和夏令时的操作系统信息,请将时区设置为"系统"。

此外,如果时区设置为"系统",则无需填写mysql.time_zone表。


通过运行"SET time_zone="SYSTEM"将MySQL时区设置为"SYSTEM"后,我重新运行了问题中的脚本并得到了以下输出,其中显示PHP和MySQL的行为方式与预期相同。

date_default_timezone_get(): Australia/Melbourne
date('P'): +10:00
MySQL timezone: AUS Eastern Standard Time
* timestring        : 2018-10-07 00:00:00
timestampFromMySql: 1538834400
timestampFromPhp  : 1538834400
date('I', $timestampFromMySql): 0
date('I', $timestampFromPhp  ): 0
difference: 0
* timestring        : 2018-10-07 01:00:00
timestampFromMySql: 1538838000
timestampFromPhp  : 1538838000
date('I', $timestampFromMySql): 0
date('I', $timestampFromPhp  ): 0
difference: 0
* timestring        : 2018-10-07 02:00:00
timestampFromMySql: 1538841600
timestampFromPhp  : 1538841600
date('I', $timestampFromMySql): 1
date('I', $timestampFromPhp  ): 1
difference: 0
* timestring        : 2018-10-07 03:00:00
timestampFromMySql: 1538841600
timestampFromPhp  : 1538841600
date('I', $timestampFromMySql): 1
date('I', $timestampFromPhp  ): 1
difference: 0
* timestring        : 2018-10-07 04:00:00
timestampFromMySql: 1538845200
timestampFromPhp  : 1538845200
date('I', $timestampFromMySql): 1
date('I', $timestampFromPhp  ): 1
difference: 0

最新更新