С # летнее время дублирующий час конвертировать в UTC

я использую TimeZoneInfo для преобразования между настенными часами на стороне клиента «Восточное время» и UTC. Моя проблема связана с «повторяющимся» часом, который возникает во время осеннего перехода на летнее время.

При преобразовании с UTC на восточное:
2010-11-07 06:00 UTC -> дает 2010-11-07T 01 : 00: 00-03: 30
2010-11-07 07:00 UTC -> дает 2010-11-07T 01 : 00: 00-03: 30
Как я могу узнать, какой час первый, а какой второй? DateTime.IsDaylightSavingTime () возвращает false для обоих часов, но разве он не должен возвращать true для первого часа?

Аналогично, как сохранить 2010-11-07 01:00:00 -03 : 30? Как мое приложение может преобразовать в UTC, поскольку это может быть 2010-11-07 06 : 00 или 2010-11-07 07 : 00

Для тех, кому нужен код, я Я просматриваю таблицу данных со столбцом даты и времени в формате UTC, пытаясь преобразовать в Восточный с столбцом «DupHr» для второго повторяющегося часа, но я всегда получаю в обоих часах 01:00 «DupHr» = 1.

    TimeZoneInfo est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

    DateTime EasternTime;
    DateTime DuplicateHour = new DateTime(2010, 11, 7, 1, 0, 0);  // hard coded for this example
    TimeZoneInfo.AdjustmentRule[] rules =  est.GetAdjustmentRules();

    foreach (DataRow row in dt.Rows)
    {
        row["DupHr"] = 0;  // by default not duplicate hour
        EasternTime = TimeZoneInfo.ConvertTimeFromUtc((DateTime)row[UTCColumnName], est);
        if (!EasternTime.IsDaylightSavingTime())
        {
            if (EasternTime.Equals(DuplicateHour ))
            {
                row["DupHr"] = 1;   // This is the second duplicate hour !
            }
        } else

            EasternTime.Add(rules[1].DaylightDelta);  // Add DST offset from rule #1

        row[newESTColumnName] = EasternTime;        
    }

СПАСИБО!

Решение

Для повторяющихся часов важно знать больше, чем «двусмысленное». Часы должны быть уникальными (первая и вторая). Рассмотрим приложение счетчика денег в будке, которое должно работать 24 часа в сутки, 7 дней в неделю и суммировать сбор за каждый час. Деньги, собранные каждый час, должны быть идентифицированы. Первый час с 1:00 до 1:59 отличается от второго часа с 1:00 до 1:59. Подпрограмма ниже isSecondHour вернет истину только в том случае, если прошло секунда час осеннего перехода на летнее время. Пользовательский интерфейс может отображать этот флаг соответствующим образом.

 // Get the DST rule for the year and zone  (rules may change from year to year as in 2004)
    public static TimeZoneInfo.AdjustmentRule GetDSTrule(int Year, TimeZoneInfo zone)
    {
        TimeZoneInfo.AdjustmentRule[] rules = zone.GetAdjustmentRules();

        foreach (TimeZoneInfo.AdjustmentRule rul in rules)
        {
            if (rul.DateStart < new DateTime(Year, 1, 1) && rul.DateEnd > new DateTime(Year, 1, 1))
            {
                return rul;
            }
        }
        return null;
    }

    // Determine if 'localtime' is in the second duplicate DST hour.
    public static Boolean isSecondHour(TimeZoneInfo localzone, DateTime localtime, DateTime UTCtime)
    {

        if (localzone.IsAmbiguousTime(localtime))
        {
            TimeZoneInfo.AdjustmentRule rul = GetDSTrule(localtime.Year, localzone);
            return UTCtime.Add(localzone.GetUtcOffset(localtime)) == localtime;
        }
        else
            return false;
    }


    static void Main(string[] args)
    {
        var est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

        var times = new DateTime[] {
        new DateTime (2010, 11, 7, 3,  0, 0, DateTimeKind.Unspecified),
        new DateTime (2010, 11, 7, 4,  0, 0, DateTimeKind.Unspecified),
        new DateTime (2010, 11, 7, 5,  0, 0, DateTimeKind.Unspecified),
        new DateTime (2010, 11, 7, 5,  30, 0, DateTimeKind.Unspecified),
        new DateTime (2010, 11, 7, 6,  0, 0, DateTimeKind.Unspecified),
        new DateTime (2010, 11, 7, 6,  30, 0, DateTimeKind.Unspecified),
        new DateTime (2010, 11, 7, 7,  0, 0, DateTimeKind.Unspecified),
        new DateTime (2010, 11, 7, 8,  0, 0, DateTimeKind.Unspecified)

    };

    DateTime EasternTime;
    Console.WriteLine("UTC Time  |  Est Time   | IsDaylightSaving | IsAmbiguousTime | isSecondHour ");

    foreach (var utc in times)
    {
        // Get Eastern Time from UTC using standard convert routine.
        EasternTime = TimeZoneInfo.ConvertTimeFromUtc(utc, est);
        Console.WriteLine("{0:HH:mm}     |   {1:HH:mm}     | {2,11}      |      {3,5}      |      {4,5}", utc,EasternTime, est.IsDaylightSavingTime(EasternTime), est.IsAmbiguousTime(EasternTime),isSecondHour(est,EasternTime, utc));
     }

результаты

UTC Time  |  Est Time   | IsDaylightSaving | IsAmbiguousTime | isSecondHour
03:00     |   23:00     |        True      |      False      |      False
04:00     |   00:00     |        True      |      False      |      False
05:00     |   01:00     |       False      |       True      |      False
05:30     |   01:30     |       False      |       True      |      False
06:00     |   01:00     |       False      |       True      |       True
06:30     |   01:30     |       False      |       True      |       True
07:00     |   02:00     |       False      |      False      |      False
08:00     |   03:00     |       False      |      False      |      False
15
задан amackay11 2 June 2011 в 16:13
поделиться