0

我将行用户作为行存储在我的数据库中。我允许用户输入他们的时区,该时区也存储在数据库中。

我的应用程序每天都会在他们指定的时间给他们发送电子邮件。我将电子邮件传递作为一行存储在另一个数据库表中。这将通过 cron 作业发生。

我希望我的查询根据他们的时区提取该用户的最新电子邮件至少 1400 分钟(24 小时前)并经过他们指定时间的用户记录。

我有以下查询,但我不知道如何解释 mysql 的时区和用户的时区。有什么建议么?

SELECT u.id, u.email, u.timezone_offset, u.email_time, TIMESTAMPDIFF( 
MINUTE , CONCAT( DATE( MAX( e.created ) ) ,  ' ', u.email_time ) , NOW( ) ) AS min_since_last_email
FROM Users u
INNER JOIN Emails e ON e.user_id = u.id
WHERE min_since_last_email > 1400
GROUP BY u.id

时区偏移量是与 GMT 的偏移量。所以它对我来说就像“-5”。

4

2 回答 2

0

稍微扭转一下逻辑:在 PHP 中进行计算,以 UTC 将所有内容存储在数据库中。然后是一个简单的提取物。您可以使用时区函数在 PHP 中轻松完成此操作,并且可以按用户自定义 - SQL 语句是一个全局语句,按用户自定义更棘手(正如您所遇到的那样)。

因此,“发送电子邮件的时间”可能是世界标准时间凌晨 4 点(并且在数据库中),但您向用户显示“晚上 9 点”。

您可能遇到的一个问题是夏令时 - 当时区进入/退出夏令时时,您需要一直重新计算。但是,您当前的方法无论如何都不允许这样做...

于 2012-09-11T01:20:10.357 回答
0

您上次发送电子邮件的日期是您的日期,因此请存储该日期。

随着您发送的电子邮件越来越多,计算每个用户的最大值将变得越来越昂贵。非规范化并将该日期时间的副本也放入用户记录中。

然后,计算该日期的年龄和用户时区的偏移量。

select *, date_add(now(), interval timezone_offset hour) as email_expected_on
from users
where last_email_date <= date_add(now(), interval timezone_offset hour);

请注意,不要将公式应用于 users.last_email_date,这一点也很重要,否则您将无法在该列上使用索引。

于 2012-09-11T01:29:06.540 回答