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

时间:2015-03-19 00:21:14

标签: c# .net date datetime .net-4.5

我发现了我知道的确切事情,它很简单(或应该是):

TimeZone.GetDaylightChanges()完全返回我需要的内容:当白天时间开始和结束时:

为此,我想做:

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

DaylightTime changes = zone.GetDaylightChanges();

这当然不会编译,因为TimeZone的构造函数不接受TimeZoneInfo(Wtf?),我无法弄清楚如何以任何其他方式获取DaylightTime更改。我需要有人将'timeZoneName'设置为任何时区,并能够为他们设置的任何时区获取开始/结束日期时间。

关键重要性:服务器正在运行(最有可能)UTC,而不是'timeZoneName'中的时区

1 个答案:

答案 0 :(得分:2)

不幸的是,您无法像这样实例化一个新的TimeZone对象。但是,我相信您可以通过浏览AdjustmentRules从TimeZoneInfo类中获取所需信息。

以下是我编写的一些方法,可以实现您想要的功能。请参阅底部的示例用法,了解与当前系统时区使用TimeZone方法的比较。

<强>更新

我已将代码修改为几个类以帮助处理日期数学,并从此处的示例中大量借用: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);
}