我使用unix时间戳整数为我的数据库中的每个预订存储时间。我遇到的问题是我的查询没有正确选择,似乎是休息日。
例如,在我的网站上,我有一个日历表,显示每月的每一天。我使用以下代码来填充每天的产品:
$sql = "select b.*, p.name as p_name, p.color as p_color
from `bookings` as b
left join `products` as p on (p.id = b.id_product)
where date_format(from_unixtime(b.timestamp), '%M %e %Y') = date_format(from_unixtime(:timestamp), '%M %e %Y')
order by b.timestamp asc";
$stm = $this->app->db->prepare($sql);
$stm->bindParam(':timestamp', $this->timestamp);
$stm->execute();
$res = $stm->fetchAll();
现在,它显示了我在日历中第25天1月24日的预订。
问题似乎在于查询的这一部分:
where date_format(from_unixtime(b.timestamp), '%M %e %Y') = date_format(from_unixtime(:timestamp), '%M %e %Y')
例如,当$this->timestamp = '1453698000'
(第25位)和b.timestamp = '1453618800'
(第24位)时,它会在我日历中的25日显示此记录。
我完全不知道为什么会这样。我已尝试更改date_format查询以使用'%d-%m-%Y',我已尝试添加' 00:00',我&# 39;我尝试在PDO结构中手动设置时区,我通过使用PHP date()函数回显时间戳,确保所有时区都正确排列(它们是正确的)。
为什么会这样?任何帮助将不胜感激。
答案 0 :(得分:1)
首先,您可以通过运行以下方式更彻底地调试:
SELECT date_format(from_unixtime(1453698000), '%M %e %Y')
和
SELECT date_format(from_unixtime(1453618800), '%M %e %Y')
看看每个人的结果。这应该揭示问题。
我不知道你在传递unix时间戳时如何设置时区,但我不认为这是可能的。时区用于根据通用时间戳计算本地时间和日期。
PHP认为每个时间戳都在哪个时区并不重要,这就是你的PHP date()函数匹配的原因。重要的是您的MySQL引擎所在的时区,因为这是您进行转换的地方。
我会从您应用程序中的正确日期时间计算确切的时间戳(例如,在00:00:00为25日)并将其传递给查询。
转换本身:
where date_format(from_unixtime(b.timestamp), '%M %e %Y') = date_format(from_unixtime(:timestamp), '%M %e %Y')
使时间戳上的任何索引无效,因此可能会导致性能下降。
最好把它写成:
WHERE b.timestamp >= :timestamp
AND b.timestamp < :timestamp + INTERVAL 1 DAY
您的其他选择是更改timezone of mysql。