我从未创建过提醒应用程序。我就是这样看的。如果我走的正确,请告诉我。
所以我有来自不同时区的用户。
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分钟运行一次的计划流程并执行以下步骤:
var tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZneID1);
var local = TimeZoneInfo.ConvertTimeFromUtc(DateTimeUTC, tzi);
var timeNow = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Now, tzi);
if(local == timeNow)
SendReminder();
这是有效的方式吗?这是正确的方法吗?
答案 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。