如何为特定时区创建 TimeZone 对象? C#

How to create a TimeZone object for a specific timezone? c#

我找到了我想知道的确切内容,而且非常简单(或者应该是):

TimeZone.GetDaylightChanges() returns 正是我需要的:夏令时开始和结束的时间:

为此,我想做的是:

TimeZoneInfo currentTimezone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);
TimeZone zone = new TimeZone (currentTimezone);  // Compile error here.

DaylightTime changes = zone.GetDaylightChanges();

这当然不会编译,因为 TimeZone 的构造函数不采用 TimeZoneInfo(Wtf?),而且我不知道如何以任何其他方式获取 DaylightTime Changes。我需要有人将 'timeZoneName' 设置为任何时区,并能够获得他们设置的任何时区的 start/end DateTimes。

关键重要性:服务器是 运行(很可能)UTC,而不是 'timeZoneName'

中的时区

不幸的是,您不能像这样实例化一个新的 TimeZone 对象。但是,我相信您可以通过查看 AdjustmentRules.

从 TimeZoneInfo class 中获取您想要的信息

下面是我编写的一些方法来启用您想要的功能。请参阅底部的示例用法,了解它与使用当前系统时区的 TimeZone 方法相比如何。

更新

我已将代码修改为几个 classes 以帮助计算日期,并大量借鉴了此处的示例:https://msdn.microsoft.com/en-us/library/system.timezoneinfo.transitiontime.isfixeddaterule.aspx

public static DaylightTime GetDaylightChanges(string timeZoneName, int year)
{
    TimeZoneInfo currentTimezone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);

    var currentRules =
        currentTimezone.GetAdjustmentRules().FirstOrDefault(rule =>
            rule.DateStart <= DateTime.Today &&
            rule.DateEnd >= DateTime.Today);

    if (currentRules != null)
    {
        var daylightStart = 
            GetTransitionDate(currentRules.DaylightTransitionStart, year);

        var daylightEnd = 
            GetTransitionDate(currentRules.DaylightTransitionEnd, year);

        return new DaylightTime(daylightStart, daylightEnd, 
            currentRules.DaylightDelta);
    }

    return null;
}

private static DateTime GetTransitionDate(TimeZoneInfo.TransitionTime transition, 
    int year)
{
    return (transition.IsFixedDateRule)
        ? new DateTime(year, transition.Month, transition.Day,
            transition.TimeOfDay.Hour, transition.TimeOfDay.Minute,
            transition.TimeOfDay.Second)
        : GetNonFixedTransitionDate(transition, year);
}

private static DateTime GetNonFixedTransitionDate(
    TimeZoneInfo.TransitionTime transition, int year)
{
    var calendar = CultureInfo.CurrentCulture.Calendar;
    int startOfWeek = transition.Week * 7 - 6;
    int firstDayOfWeek = (int) calendar.GetDayOfWeek(new DateTime(year, 
        transition.Month, 1));

    int changeDayOfWeek = (int) transition.DayOfWeek;

    int transitionDay = (firstDayOfWeek <= changeDayOfWeek) 
        ? startOfWeek + (changeDayOfWeek - firstDayOfWeek)
        : startOfWeek + (7 - firstDayOfWeek + changeDayOfWeek);

    if (transitionDay > calendar.GetDaysInMonth(year, transition.Month))
        transitionDay -= 7;

    return new DateTime(year, transition.Month, transitionDay, 
        transition.TimeOfDay.Hour, transition.TimeOfDay.Minute, 
        transition.TimeOfDay.Second);
}   

与使用当前 TimeZone 方法相比,这里是如何使用它的示例:

public static void Main()
{
    var daylightTime = GetDaylightChanges("Pacific Standard Time", DateTime.Today.Year);
    var dylightTime2 = TimeZone.CurrentTimeZone.GetDaylightChanges(DateTime.Today.Year);
}