我有一个应用程序,在该应用程序中,通过使用系统名称将时区视为字符串,以便我们可以通过:
来形成一个实际的System.TimeZoneInfo
对象。
var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZone);
这样的值一直持续到数据库,现在我们面临着一个问题,要求一个这样的对象在Arizona Time
上,这不是标准的时区。从我研究的情况下,Arizona Time
改变了时区,因为它没有观察到"日光节省"。
我正在寻找一种在DB中设置一个值的方法,因此无需根据日光节省的变化来更改它。
有办法做到这一点吗?
即使我必须更改代码才能获取TimeZoneInfo
对象。对我来说真正重要的是确定与Arizona Time
关于亚利桑那时区
来自timeanddate.com:
普遍误解亚利桑那州在太平洋日光上 时间(PDT)在夏季和山区标准时间(MST) 在冬季。因为MST和PDT具有相同的UTC偏移 负7小时(UTC-7),亚利桑那州与邻近的当地时间相同 夏季在加利福尼亚州和内华达州州。尽管 时间是相同的,亚利桑那州全年都使用标准时间(MST)。 "日光"时区(例如MDT)主要用于 每年切换到DST
iana(TZ数据库)时区数据库包含亚利桑那州的两个时区:
- America/Phoenix (Mountain Standard Time -Arizona,Navajo除外),它不观察日光节省变化(DST)和
- America/Shiprock ,观察DST。
根据用户在亚利桑那州的确切位置,您应该使用 America/Phoenix 或 America/Shiprock 时区,因此您将需要数据库中的两个值。但是,如果您尝试使用TZ数据库名称获得与TimeZoneInfo.FindSystemTimeZoneById
的时区,则将获得System.TimeZoneNotFoundException
。
为了获得不观察DST( America/Phoenix )的亚利桑那时区,您可以使用:
TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time")
为了获得确实观察DST( America/Shiprock )的亚利桑那时区,您可以使用:
TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time")
因此,您的数据库,US Mountain Standard Time
和Mountain Standard Time
或其他一些字符串将在以后映射到这些.NET时区IDS中。
查看nodatime,在处理日期,时间和时区时,它可以为您提供很多帮助。
最后,这是一个示例程序(带有nodatime),证明了.net US Mountain Standard Time ( America/Phoenix ,没有DST的亚利桑那州)和山标准时间( America/Shiprock ,与DST的亚利桑那州)。
using System;
using NodaTime;
using NodaTime.TimeZones;
namespace TimeZoneExample
{
class Program
{
static void Main(string[] args)
{
// Arizona without daylight saving time (TZ: America/Phoenix)
var mstWithoutDstTz = TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time");
// Arizona with daylight saving time (TZ: America/Shiprock)
var mstWithDstTz = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
// NodaTime BclDateTimeZone for Arizona without daylight saving time
var mstWithoutDstNodaTz = BclDateTimeZone.FromTimeZoneInfo(mstWithoutDstTz);
// NodaTime BclDateTimeZone for Arizona with daylight saving time
var mstWithDstNodaTz = BclDateTimeZone.FromTimeZoneInfo(mstWithDstTz);
// January 1, 2017, 15:00, local winter date
var localWinterDate = new LocalDateTime(2017, 01, 01, 15, 00);
// NodaTime ZonedDateTime for Arizona without daylight saving time: January 1, 2017, 15:00
var winterTimeWithoutDst = mstWithoutDstNodaTz.AtStrictly(localWinterDate);
// NodaTime ZonedDateTime for Arizona with daylight saving time: January 1, 2017, 15:00
var winterTimeWithDst = mstWithDstNodaTz.AtStrictly(localWinterDate);
// Both time zones have the same time during winter
Console.WriteLine($"Winter w/o DST: {winterTimeWithoutDst}"); // 2017-01-01T15:00:00 US Mountain Standard Time (-07)
Console.WriteLine($"Winter w/ DST: {winterTimeWithDst}"); // 2017-01-01T15:00:00 Mountain Standard Time (-07)
// add 180 days to get June 30, 2017
var sixMonthsToSummer = Duration.FromTimeSpan(new TimeSpan(180, 0, 0, 0));
// During summer, e.g. on June 30, Arizona without daylight saving time is 1 hour behind.
Console.WriteLine($"Summer w/o DST: {winterTimeWithoutDst + sixMonthsToSummer}"); // 2017-06-30T15:00:00 US Mountain Standard Time (-07)
Console.WriteLine($"Summer w/ DST: {winterTimeWithDst + sixMonthsToSummer}"); // 2017-06-30T16:00:00 Mountain Standard Time (-06)
}
}
}
如果我正确理解您的问题,则要创建一个代表"亚利桑那时间"的自定义时区域,无论一年的日期与UTC都不断偏移。
如果是这样,您应该能够使用静态方法
TimeZoneInfo.CreateCustomTimeZone
只是将时间板设置为您需要的UTC的小时数(距离我可以告诉的是-7个小时)。
https://msdn.microsoft.com/en-us/library/bb309898(v = vs.110).aspx
编辑:您也可以简单地使用命名时区
获得一些成功"US Mountain Standard Time"
应该代表相同的。