Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从NodaTime中的偏移量获取所有IANA时区?_C#_Asp.net Mvc_Timezone_Datetimeoffset_Nodatime - Fatal编程技术网

C# 如何从NodaTime中的偏移量获取所有IANA时区?

C# 如何从NodaTime中的偏移量获取所有IANA时区?,c#,asp.net-mvc,timezone,datetimeoffset,nodatime,C#,Asp.net Mvc,Timezone,Datetimeoffset,Nodatime,在我们的ASP.NET MVC 5应用程序中,我们有带有时区ID(IANA)的用户配置文件 任务是在当地时间早上6点向所有用户发送电子邮件。我们的计划是每小时向所有时区发送电子邮件,当地时间为该时间点的上午6点(根据服务器的UTC时间计算) 因为我们只有时区ID,所以我希望得到相应的时区ID,比如偏移量-4:00:00--,考虑到DST string[] timezoneIds; 然后我可以这样查询我的数据库: db.Users.Where(x => timezoneIds.Contai

在我们的ASP.NET MVC 5应用程序中,我们有带有时区ID(IANA)的用户配置文件

任务是在当地时间早上6点向所有用户发送电子邮件。我们的计划是每小时向所有时区发送电子邮件,当地时间为该时间点的上午6点(根据服务器的UTC时间计算)

因为我们只有时区ID,所以我希望得到相应的时区ID,比如偏移量-4:00:00--,考虑到DST

string[] timezoneIds;
然后我可以这样查询我的数据库:

db.Users.Where(x => timezoneIds.Contains(x.TimeZoneId));
我的问题是,很明显,这是一个不错的想法,还是有解决这个问题的最佳实践我不知道


谢谢。

您可以尝试以下方法:

首先创建一个包含所有偏移量和属于该偏移量的时区的字典

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, };
    }
}
这将使时区utc+1中的所有用户获得Serge显示的“构建字典”的更简单代码:使用LINQ的查找、
DateTimeZone.GetUtcOffset
Offset
键,而不是
TimeSpan
值:

var now = SystemClock.Instance.GetCurrentInstant();
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])
{
    ...
}

(您甚至不需要首先检查存在性,因为查找索引器在出现查找时不存在的密钥时返回空序列)。这个方法很好,不过考虑生成的SQL可能相当大,这取决于匹配的时区。另外,如果代码提前运行,那么一定要传递正确的

即时
作为实际执行时间,而不是
现在
。哦,我相信它与字典中的
偏移量
键一样有效,这并不重要
var now = SystemClock.Instance.GetCurrentInstant();
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])
{
    ...
}