如何为不同时区的用户在正确的时间发送提醒?

时间:2011-07-12 15:12:44

标签: c# asp.net sql

我从未创建过提醒应用程序。我就是这样看的。如果我走的正确,请告诉我。

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

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();
  4. 这是有效的方式吗?这是正确的方法吗?

4 个答案:

答案 0 :(得分:8)

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

假设你确实意味着它是数据库中的UTC,即你在用户输入提醒时的当地时间转换它(假设他们这样做是为了开始)。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

通常情况下,在处理这样的日期时,您将以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 :(得分:0)

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