我正在尝试使用Noda Time设计以下时区解决方案:
用户将使用移动应用程序或Web应用程序登录系统。在登录时,将以与UTC的偏移量(例如x分钟)作为参数来调用Web API。
现在,如果偏移量(x分钟)与数据库中保存的偏移量(和时区)不同,则将向用户显示一个时区列表,该时区距离UTC时为x分钟,因此他们可以从中选择一个。然后,选定的时区和相应的偏移量(x分钟)将作为用户的最新时区保存在数据库中。
如何使用Noda Time获取距UTC x分钟的时区列表?
例如,如果用户距离UTC +330分钟,那么用户将收到以下提示:
我们发现您比格林尼治标准时间早5小时30分钟。请选择您当前的时区:“亚洲/科伦坡”,“亚洲/加尔各答”
答案 0 :(得分:2)
您可以执行以下操作:
TimeZoneInfo.GetSystemTimeZones()
.Where(x => x.GetUtcOffset(DateTime.Now).TotalMinutes == 330)
现在您有了时区的集合!您可以根据情况将DateTime.Now
替换为其他日期或DateTimeOffset
。
在Noda Time中,您可以执行以下操作:
using NodaTime;
using NodaTime.TimeZones;
TzdbDateTimeZoneSource.Default.GetIds()
.Select(x => TzdbDateTimeZoneSource.Default.ForId(x))
.Where(x =>
x.GetUtcOffset(SystemClock.Instance.GetCurrentInstant()).ToTimeSpan().TotalMinutes == 330)
答案 1 :(得分:1)
Sweeper代码的另一种替代方法,使用目标偏移量而不是将每个偏移量转换为TimeSpan
,一次计算“ now”(以获得一致的结果)并使用IDateTimeZoneProvider.GetAllZones
扩展名方法。
using System;
using System.Linq;
using NodaTime;
using NodaTime.Extensions;
class Test
{
static void Main()
{
// No FromMinutes method for some reason...
var target = Offset.FromSeconds(330 * 60);
var now = SystemClock.Instance.GetCurrentInstant();
var zones = DateTimeZoneProviders.Tzdb.GetAllZones()
.Where(zone => zone.GetUtcOffset(now) == target);
foreach (var zone in zones)
{
Console.WriteLine(zone.Id);
}
}
}