使用预选时区的 PHP 计划电子邮件提醒

标签 php timezone dst

我一直在搜索,但似乎找不到解决方案。

我有一个 PHP 网页,我可以在其中安排特定时间的电子邮件提醒。我选择发送警报的日期和时间。它以 UNIX 格式存储在 MySQL 表中。我有一份工作,每 15 分钟执行一次,如果日期和时间是过去的时间,就会发送电子邮件——这一切都很好,除了我需要为我的美国同事延长它。我住在爱尔兰,所以我需要管理美国各地的不同时区。我计划添加一个时区选择列表,用户在注册后必须选择这些时区……至少这是一个开始。管理时区很好,因为我认为我需要做的就是减去与服务器时间不同的时间,然后以 unix 格式保存日期时间。 DST 是一个不同的问题 - 有没有人对如何克服这个问题有任何想法?

我读过使用 UTC 作为基准时间,但即使是这种情况,我不会仍然遇到同样的问题吗?

非常感谢!

最佳答案

您的时间已经是 UNIX 时间戳格式,因此您只需要计算用户的时间差(偏移量)即可。例如,爱尔兰处于 UTC/UTC+1 时区。因此,您所需要做的就是像 james_t 在他的评论中提到的那样进行数学计算。如果您需要来自爱尔兰的用户在 9:00pm UTC+1 收到电子邮件,您必须在 8:00pm UTC 发送。那么什么是想法?

允许用户选择时区,这意味着他们选择与 UTC 的时差。将其保存在数据库中的某个位置(您的用户表或其他一些表,无关紧要)。

以秒为单位转换偏移量:

$delta_time = -1 * $offset * 3600

然后计算你的触发时间:

$trigger_time = time() + $delta_time;

现在您有时间根据用户的时区设置在正确的时刻发送电子邮件。

例如:

$offset = 1; // summer in Ireland
$server_time = time(); // at the moment 1350509127
$delta_time = -1 * $offset * 3600; // -3600
$trigger_time = $server_time + $delta_time; // 1350505527

您只需将 $trigger_time 与数据库中的 UNIX 时间戳进行比较,然后决定是否发送电子邮件。

Ofc,使用PHP timezones 是个不错的主意而不是纯粹的 +/- 偏移量,并在 DST 更改应用于某些位置时保持更新。

做一些测试,这并不难。

这只是一个大概的想法,不是完整的工作解决方案。

更新:

要计算任意两个时区之间的时差(以秒为单位),您可以使用如下代码:

函数 delta_offset()

  function delta_offset($server_timezone, $user_timezone) {
    $dt = new DateTime('now', new DateTimeZone($server_timezone));
    $offset_server = $dt->getOffset();
    $dt->setTimezone(new DateTimeZone($user_timezone));
    $offset_user = $dt->getOffset();
    return $offset_user - $offset_server;
    }

以秒为单位获取偏移量:

  $server_tz = "Europe/London";
  $user_tz = "America/New_York";
  $offset = delta_offset($server_tz, $user_tz);  // offset in sec.

创建一些输出:

  $dt = new DateTime('now', new DateTimeZone('UTC'));
  echo "<pre>UTC date/time: " . $dt->format('l, F jS, <b>H:i:s</b>') . "\n";
  $dt = new DateTime('now', new DateTimeZone($server_tz));
  echo "London date/time: " . $dt->format('l, F jS, <b>H:i:s</b>') . "\n";
  $dt = new DateTime('now', new DateTimeZone($user_tz));
  echo "New York date/time: " . $dt->format('l, F jS, <b>H:i:s</b>') . "\n\n";
  echo "Time difference between London (UK) and New York (USA) is: <b>$offset_h</b> ($offset s)</pre>";  

在浏览器中的输出(在写这篇文章的时候):

UTC date/time: Wednesday, October 17th, 22:32:27
London date/time: Wednesday, October 17th, 23:32:27
New York date/time: Wednesday, October 17th, 18:32:27

Time difference between London (UK) and New York (USA) is: -5:00 (-18000 s)

在这种情况下,偏移量为 -5 小时(-18000 秒),但如果 DST 规则针对作为函数参数给出的任何时区发生变化,它会自动更改。

Delta-offset 提供您必须提前或延迟多长时间向不同时区的用户发送电子邮件的信息,您现在所需要做的就是执行简单的 +/- delta-offset 与您的电子邮件发件人的调度程序。

希望这可以帮助您找到解决问题的正确方法。

更新 #2 - 示例(理论)

想象一下这种情况。

您当前的服务器时间是 X,此时在爱尔兰是 7:00pm。我住在塞尔维亚,我们有相同的 DST 规则,但我晚了一小时 (UTC+1/UTC+2)。你和我的时间差是 +3600 秒(1 小时)。

现在你必须在 10:00pm 给我发邮件(在爱尔兰是 9:00pm)。

  • 当前时间是X
  • Delta-offset 为 -1 * +3600 = -3600(delta-offset 乘以 -1)。
  • 在晚上 10:00 向您的位置发送时间是 X + 10800(3 小时后)。
  • 晚上 10 点在我的位置发送时间是 X + 10800 + delta-offset = X + 7200(2 小时后)。

检查实际时间是否等于或大于触发时间(发送时间)的公式为:

current_timestamp >= trigger_timestamp + delta_offset

delta_offset() 函数的 delta-offset 必须乘以 -1 才能在公式中使用。

现在您可以在需要时发送电子邮件,并确保使用用户的本地时间(ofc,如果用户时区设置正确)发送。

注意与此示例(塞尔维亚 - 爱尔兰 = +1 小时)的差异在夏令时更改期间有所不同,这意味着我们每年有 1 小时处于同一时区(0 delta- offset),一小时我们有 +2 小时 delta-offset。这是可能的,因为 DST 更改在塞尔维亚提前 1 小时应用,所以当我们的时间更改为 +1 时,您必须等待 60 分钟才能将相同的更改应用于爱尔兰时间 * 然后我们是 +2),当我们带回来时也是如此时钟到正常时间(0 差异)。

关于使用预选时区的 PHP 计划电子邮件提醒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12935666/

相关文章:

php - 使用 PBKDF2 在 MySQL 数据库中存储密码和盐

php - 使用 PDO 查询生成 CSV 下载

go - 如何获取本地时区的全名?

java - Java 8 和 Java 7 中的时区差异

javascript - Google Apps 脚本和 Google 日历的 DST 问题

java - 如何在java中使用DST时区获取正确的时间(毫秒)

php - 使用完全限定的 URL 时 require() 的问题

php - 如何使用 {'property-names-like-this' 声明动态 PHP 类 }

php - 仅使用偏移量获取用户选择的时区日期时间

r - 转换为没有时区的日期和时间?