从 IANA (TZDB) 时区获取偏移分钟数
Get offset minutes from IANA (TZDB) time zone
我有一个 table T1
,其中 Id
、Name
和 TimeZone
作为列。 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 查询。
我有一个 table T1
,其中 Id
、Name
和 TimeZone
作为列。 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 查询。