在我们的ASP.NET MVC 5应用程序中,我们拥有带有时区ID(IANA)的用户配置文件。
public class User
{
public int Id { get; set; }
public string TimeZoneId { get; set; }
}
任务是在当地时间早上6点向所有用户发送电子邮件。我们的计划是每小时向所有时区发送电子邮件,当地时间是当时时间早上6点(根据服务器的UTC时间计算)。
由于我们只有时区ID,所以我希望得到相应的时区ID,比方说,偏移-4:00:00 - 考虑到DST 。< / p>
string[] timezoneIds;
然后,我可以像这样查询我的数据库:
db.Users.Where(x => timezoneIds.Contains(x.TimeZoneId));
我的问题显然是,这是一个不错的主意,还是我不了解这个问题的最佳做法?
感谢。
答案 0 :(得分:6)
更简单的代码,用于构建词典&#34; Serge显示:使用LINQ的查找,Offset
和TimeSpan
键而不是var now = SystemClock.Instance.Now;
var provider = DateTimeZoneProviders.Tzdb;
var idsByCurrentOffset = provider.Ids.ToLookup(id => provider[id].GetUtcOffset(now));
值:
var offset = Offset.FromHours(5);
foreach (var id in idsByCurrentOffset[offset])
{
...
}
然后你可以使用:
<?php echo base_url();>
(您甚至不需要首先检查是否存在,因为查找索引器在显示查找中不存在的密钥时返回空序列。)
答案 1 :(得分:3)
您可以尝试以下方法:
首先创建一个包含所有偏移量和属于该偏移量的时区的字典
Instant now = SystemClock.Instance.Now;
IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb;
Dictionary<TimeSpan, List<string>> timezonesForOffset = new Dictionary<TimeSpan, List<string>>();
foreach(var id in timeZoneProvider.Ids){
ZonedDateTime zdt = now.InZone(timeZoneProvider[id]);
var timespan = zdt.Offset.ToTimeSpan();
if(timezonesForOffset.ContainsKey(timespan)){
timezonesForOffset[timespan].Add(id);
} else {
timezonesForOffset[timespan] = new List<string> {id, };
}
}
完成后,您可以使用以下代码段获取特定时区内的所有用户
var timespan2 = new TimeSpan(1,0,0);
var timezonesWithOffset = timezonesForOffset[timespan2];
var usersinTimezone = db.Users.Where(x=> timezonesWithOffset.Contains(x.TimezoneId)).ToList();
这将使所有用户都在时区utc + 1