mysql夏时制信息似乎不正确如何确保它在windows中是最新的?

nzrxty8p  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(275)

我发现程序中的一个bug是由mysql的unix\u timestamp()函数在给定相同的输入时向php的strotime()返回不同的值引起的。
然后我发现错误发生的日期恰好是我所在时区夏时制生效的日期。
所以我需要知道为什么php知道夏时制开始日,而mysql不知道。php和mysql不都应该从操作系统获取时区和夏时制信息吗?
操作系统是Windows7,根据WindowsUpdate程序,它是最新的补丁。
这是我的密码:

// 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        : $timeString\n";
   echo "   timestampFromMySql: $timestampFromMySql\n";
   echo "   timestampFromPhp  : $timestampFromPhp\n";

   // 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秒或1小时的差异。

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点开始,时钟将提前一小时。因此,2018年10月7日的凌晨2点实际上与2018年10月7日的凌晨3点是同一时间,因此我在上面的脚本输出中从php观察到的行为是意料之中的。mysql的行为似乎不正确。
有人能告诉我如何确保mysql拥有与夏时制相关的最新信息吗?
我还发现mysql.time\u zone表都是空的。这意味着mysql没有时区信息,还是意味着mysql的时区信息来自操作系统?

wpcxdonn

wpcxdonn1#

相关文件如下:https://dev.mysql.com/doc/refman/5.5/en/time-zone-upgrades.html
关键的句子是:
“如果将mysql服务器的时区设置为system,则操作系统时间会影响mysql服务器使用的时间值”

如果在mysql中使用命名时区,请确保mysql数据库中的时区表是最新的
稍后的文档说明,如果mysql.time\u zone\u name表为空,则没有人可以使用命名时区,并且不需要更新这些表。
因此,要强制mysql使用时区和夏令时的操作系统信息,请将时区设置为“system”。
另外,如果时区设置为“system”,则不需要填写mysql.time\u 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
z2acfund

z2acfund2#

这就是众所周知的mysql中unix\u timestamp函数的“特性”
https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
注意:如果使用unix\u timestamp()和from\u unixtime()在时间戳值和unix时间戳值之间进行转换,则转换是有损的,因为在两个方向上Map不是一对一的。例如,由于本地时区更改的约定,两个unix\u timestamp()可以将两个时间戳值Map到同一个unix时间戳值。from\u unixtime()将只将该值Map回一个原始时间戳值。下面是一个示例,使用cet时区中的时间戳值:
演练-仅在php中使用时间函数,mysql仅用于存储(datetime格式)

相关问题