从 IANA (TZDB) 时区获取偏移分钟数

Get offset minutes from IANA (TZDB) time zone

我有一个 table T1,其中 IdNameTimeZone 作为列。 TimeZone 列的 IANA (TZDB) 格式类似于 America/Chicago 我从 T1 获取数据,例如

response = T1.Where(t => t.Id == 9).Select(rez => new
           {
              RezName = rez .Name,
              Offset = ...
           });

Offset 内部,我需要以分钟为单位获取当前偏移量(例如 -300 表示 America/Chicago 的偏移量为 -05)。 有没有办法在 LINQ 查询中获取偏移分钟数,或者仅通过在 select 之后迭代并计算每个元素的本地时间?

正如您最初使用 nodatime 标记您的问题一样,您可以通过以下方式利用 NodaTime:

using NodaTime;

...

Instant now = SystemClock.Instance.GetCurrentInstant();
response = T1.Where(t => t.Id == 9)
   .Select(rez => new
   {
      RezName = rez.Name,
      TimeZone = rez.TimeZone
   })
   .AsEnumerable()
   .Select(x => new
   {
      RezName = x.RezName,
      Offset = (int) DateTimeZoneProviders.Tzdb[x.TimeZone]
                         .GetUtcOffset(now).ToTimeSpan().TotalMinutes
   });

如果您在 Linux 或 macOS 上使用 .NET,或者如果您在 Windows 上使用 .NET 6 或更高版本,则无需 Noda Time:

DateTimeOffset now = DateTimeOffset.UtcNow;
Instant now = SystemClock.Instance.GetCurrentInstant();
response = T1.Where(t => t.Id == 9)
   .Select(rez => new
   {
      RezName = rez.Name,
      TimeZone = rez.TimeZone
   })
   .AsEnumerable()
   .Select(x => new
   {
      RezName = x.RezName,
      Offset = (int) TimeZoneInfo.FindSystemTimeZoneById(x.TimeZone)
                         .GetUtcOffset(now).TotalMinutes
   });

另一种替代方法是使用来自 TimeZoneConverter 的 `TZConvert.GetTimeZoneInfo 以及与第二个示例类似的代码。

请记住,所有这些 return 与 UTC 的 当前 偏移量(以分钟计,正值是格林威治标准时间以东)。对于 America/Chicago,目前是 -300,因为夏令时有效。当夏令时结束时,它将 return -360.

请注意,在上述示例中,时区代码必须出现在查询具体化之后,因为像 EF 这样的 LINQ 提供程序不可能将其转换为 SQL 查询。