【问题标题】:How to send reminders at correct time for users in different timezones?如何在正确的时间为不同时区的用户发送提醒?
【发布时间】:2011-07-12 15:12:44
【问题描述】:

我从未创建过提醒应用程序。这是我的看法。如果我走对了,请告诉我。

所以我有来自不同时区的用户。

ID         DateTimeUTC               TimeZoneID            

1          2011-07-12 02:15:15.000   TimeZneID1
2          2011-07-13 16:00:00.000   TimeZneID2
3          2013-11-03 17:00:00.000   TimeZneID3
4          2011-08-22 03:00:00.000   TimeZneID4
5          2011-07-16 22:00:00.000   TimeZneID5

创建一个每 15 分钟运行一次的计划进程并执行以下步骤:

  1. 获取记录;
  2. 第二个是将DateTimeUTC转换为正确时区的时间
  3. 比较是否匹配
    一种。发送提醒
    var tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZneID1);
    var local = TimeZoneInfo.ConvertTimeFromUtc(DateTimeUTC, tzi);
    var timeNow = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Now, tzi);
    if(local == timeNow)
    SendReminder();

这是有效的方法吗?这是正确的方法吗?

【问题讨论】:

    标签: c# asp.net sql


    【解决方案1】:

    如果数据库中的日期/时间值已经采用 UTC,则您无需执行 任何 转换,当然...您只需要查看当前 UTC 时刻是否匹配,如果是,发送提醒。

    假设您真的表示它是数据库中的 UTC,即您已将其从用户输入提醒时的本地时间转换(假设他们开始时这样做了)。

    【讨论】:

    • 再次强调 Jon 的观点 - 如果您希望在从数据库中提取数据时能够执行此类日期数学运算,则必须在将时间存储到数据库之前将其转换为 UTC .
    【解决方案2】:

    通常,在处理这样的日期时,您会以 UTC 进行所有计算,并且仅在需要显示结果时(没有双关语)切换到本地时间。我从您的问题中假设这是一个管理所有任务的集中式数据库,您只需要它们在正确的本地时间运行?

    if ( dateTimeUtc == DateTime.UtcNow )
    {
        // If your reminder needs to display the local time, pass it in:
        var tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZneID1);
        SendReminder(TimeZoneInfo.ConvertFromUtc(DateTime.UtcNow, tzi));
    }
    

    注意DateTime.Now 是在本地时间;您希望 DateTime.UtcNow 跨时区保持一致。

    需要注意的另一件事是,您仅每 15 分钟运行一次任务调度程序,因此像 02:15:15 这样的时间完全匹配的几率很小。您通常想要做的是检查自上次运行后出现的任何提醒时间

    var currentRun = DateTime.UtcNow;
    foreach ( dateTimeUtc in GetReminderDateTimes() )
    {
        if ( dateTimeUtc > lastRun && dateTimeUtc <= currentRun )
        {
        }
    }
    lastRun = currentRun;
    

    【讨论】:

      【解决方案3】:

      在我看来,您可能过于复杂了。由于您在 UTC 中存储内容,因此在 UTC 中有提醒,并在 UTC 上匹配。然后只需将提醒与您要提醒的用户相关联。

      【讨论】:

        【解决方案4】:

        我想做类似的事情,并且一直在争论什么是合适的方法。本质上,我正在编写一个应用程序,它将在午夜(当地时间)向特定国家/地区发送消息。我有大约 100 个这样的国家,我还必须注意夏令时。我只能想到两种方法来做到这一点, 1.为每个国家创建一个对应的线程,每隔一小时左右醒来,检查是否是午夜(当地时间)并发送消息。所以本质上,我将创建 100 个线程,大部分时间什么都不做。 2. 在这种方法中,将只有一个计时器,每分钟或 30 秒检查 100 个国家/地区的当地时间并发送消息。将需要一些额外的逻辑,因为永远不会有精确的午夜匹配。 不确定,是否有更好的方法来解决上述情况。如果我能在这里得到一些想法/建议,那就太好了。 谢谢, SP。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-10-23
          • 2021-12-09
          • 1970-01-01
          • 2022-11-12
          • 2023-04-09
          • 2019-02-10
          • 1970-01-01
          相关资源
          最近更新 更多