C# 如何在正确的时间为不同时区的用户发送提醒?
我从未创建过提醒应用程序。以下是我的看法。如果我走对了,请告诉我 所以我有来自不同时区的用户C# 如何在正确的时间为不同时区的用户发送提醒?,c#,asp.net,sql,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 TimeZneID
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分钟运行一次的计划流程,并执行以下步骤:
A.发送提醒
var tzi=TimeZoneInfo.findsystemtimezonebyd(TimeZneID1)
var local=TimeZoneInfo.ConvertTimeFromUtc(日期时间UTC,tzi)
var timeNow=TimeZoneInfo.ConvertTimeFromUtc(DateTime.Now,tzi)
如果(本地==timeNow)
发送提醒()
这是一种有效的方法吗?这条路对吗 如果数据库中的日期/时间值已经是UTC格式,则无需执行任何转换,当然。。。您只需查看当前UTC瞬间是否匹配,如果匹配,请发送提醒
这是假设你的意思是数据库中的UTC,也就是说,当用户输入提醒时,你已经从用户的本地时间转换了UTC(假设他们从一开始就这样做)。我认为你可能把它复杂化了。因为您是在UTC中存储东西,所以请在UTC中设置提醒,并在UTC上进行匹配。然后只需将提醒与要提醒的用户相关联。通常,在处理此类日期时,您将以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(GetRememberDateTimes()中的dateTimeUtc)
{
如果(dateTimeUtc>lastRun&&dateTimeUtc我想做类似的事情,并且一直在讨论什么是合适的方法。基本上,我正在编写一个应用程序,它将在午夜(本地时间)为特定国家发送消息.我有大约100个这样的国家,我还必须注意夏令时。我只能想出两种方法来做到这一点,
1.为每个国家创建一个对应的线程,该线程大约每小时醒来一次,检查是否是午夜(当地时间)并发送消息。因此,基本上,我将创建100个线程,大部分时间不做任何事情。
2.在这种方法中,只有一个计时器,每分钟或30秒检查100个国家的当地时间并发送消息。需要一些额外的逻辑,因为永远不会有精确的午夜匹配。
不确定,是否有更好的方法来解决上述情况。如果我能在这里得到一些想法/建议,那就太好了。
谢谢
SP.为了再次强调Jon的观点,如果您希望在从数据库中提取数据时能够进行这种类型的日期计算,则必须先将时间转换为UTC,然后才能将其存储到数据库中。
var currentRun = DateTime.UtcNow;
foreach ( dateTimeUtc in GetReminderDateTimes() )
{
if ( dateTimeUtc > lastRun && dateTimeUtc <= currentRun )
{
}
}
lastRun = currentRun;