2016-12-19 4 views
0

Мне нужно импортировать измеренные данные (по одному времени на каждый час) и хотите представлять даты с noda time. На серию влияют переходные процессы на летнее время - и у меня есть некоторые проблемы.Импорт списка дат из часового пояса с помощью Noda Time

Я создал несколько тестов даты с летнего времени меняющийся дни 2016 года (Европа/Берлин): (год, месяц, день, час)

2016,3,27,0
2016 года, 3,27,1
2016,3,27,3
2016,3,27,4
2016,10,20,0
2016,10,20,1
2016,10,20,2
2016,10,20,2
2016,10,20,3

Каждая строка увеличивается на один час. Разрыв и двойные данные дур для перехода на летнее и зимнее время

Я использую следующий код для проверки импорта:

private void TestImport() 
{ 
    List<ZonedDateTime> resultSet = new List<ZonedDateTime>(); 

    IDateTimeZoneProvider provider = DateTimeZoneProviders.Tzdb; 
    DateTimeZone dtz = provider.GetZoneOrNull("Europe/Berlin"); 
    bool first = true; 

    foreach (string line in File.ReadAllLines(@"C:\tmp\problemdates.txt")) 
    { 
     string[] split = line.Split(",".ToCharArray()); 
     LocalDateTime ldt = new LocalDateTime(Convert.ToInt32(split[0]), Convert.ToInt32(split[1]), Convert.ToInt32(split[2]), Convert.ToInt32(split[3]), 0); 

     resultSet.Add(Convert2Zoned(ldt, dtz, ref first)); 
    } 

    DataGrid_Results.DataContext = return resultSet; 
} 


private ZonedDateTime Convert2Zoned(LocalDateTime ldt, DateTimeZone dtz, ref bool isFirstAmbigue) 
{ 
    try 
    { 
     return ldt.InZoneStrictly(dtz); 
    } 
    catch (SkippedTimeException ex) 
    { 
     // rethrow 
    } 
    catch (AmbiguousTimeException ex) 
    { 
     if (isFirstAmbigue) 
     { 
      isFirstAmbigue = false; 
      return ldt.InZone(dtz, Resolvers.CreateMappingResolver(Resolvers.ReturnEarlier, Resolvers.ThrowWhenSkipped)); 
     } 
     else 
     { 
      isFirstAmbigue = true; 
      return ldt.InZoneLeniently(dtz); 
     } 
    } 
} 

Edith: Вот простой GUI application, который выполняет импорт

Что я ожидал -

27.03. Час 3: TickOfDay 7200 ... вместо 10800 ... потому что это второй час дня

20.10. Час 2: второе появление должно быть TickOfDay 10800 ... вместо 7200 ... снова, так как это на один час позже первого появления. Кроме того, смещение должно быть +01 вместо +02 от второго появляющегося, так как мы снова в зимнее время.

Я также ожидал бы LocalDateTime быть "нормализованы" (например, 1:00, 2:00, 3:00 ...), но это migfht относятся к Offset ...

Спасибо за вашу помощь,
Frank

+0

В настоящее время это неполно, кажется, нужен пользовательский интерфейс и ожидает файл. Не могли бы вы отредактировать это, чтобы быть полным консольным приложением (чтобы мы могли копировать, вставлять, компилировать, запускать) с использованием жестко кодированных данных и с ожидаемыми и фактическими результатами? –

+0

уверен, дайте мне scecond :) – Aaginor

+0

Это все еще графическое приложение, и это не полный пример. На самом деле стоит довольствоваться написанием коротких * консольных приложений для демонстрации проблем. Они помогают сосредоточиться только на проблеме, без каких-либо посторонних сложностей. –

ответ

1

.TickOfDay собственности на ZonedDateTime или OffsetDateTime связана с его LocalDateTime, который timezoneless. Это не связано с его мгновенным временем, а скорее на настенные часы, как показано.

Таким образом, ожидаемые вами ожидания недействительны. Местное время 03:00 всегда будет TickOfDay == 10800.

Если вы хотите нормализовать эти значения таким образом, чтобы 3:00 был идентифицирован как второй час дня, вам придется сначала настроить их все, чтобы использовать тот же самый сдвиг - тот, который действовал с самого начала дня.

Факс:
+0

Эй, Мэтт, спасибо за ваш ответ! Смещение автоматически создавалось с помощью операции LocalDateTime.InZone [Leniently]. К сожалению, кажется, что нет никакого способа создать ZonedDateTime из зонированного значения и часовой пояс – Aaginor

+0

А? Я не уверен, к чему вы клоните. Я ничего не говорил о смещении, кроме того, что вы должны были бы нормализовать их, чтобы все было одинаковым, если вы хотели получить эквивалентные значения времени на стене. 'TickOfDay' - время на стене. –

1
Факс:

Часы, показывающие местное время в Берлине.

Что-то (A) происходит, когда мои часы показывают 2016-03-27T00: 00: 00.

Что-то (B) происходит, когда мои часы показывают 2016-03-27T03: 00: 00.

Истекшее время между (А) и (В) составляет 2 часа. Это единственное «действительное» ожидание, потому что это правда.

Вопрос в том, можем ли мы представить это действительное ожидание с помощью любого артефакта программного обеспечения. Если нет, программное обеспечение недействительно, а не ожидаемое.

+0

Эй, Хорхе! Я думаю, что мы * можем * представить ожидание - нам нужно время UTC, часовой пояс и логика, чтобы преобразовать его в «ZonedDateTime» (и обратно). То, что мне не хватает, - это способ прямого чтения даты/времени в структуре ZonedDateTime. – Aaginor

+0

. Проблема заключается в том, что, наконец, 'ZonedDateTime.TickOfDay' не представляет фактическое время, прошедшее с полуночи, когда происходит переход по часам в середине , И вы ожидаете, что «27.03. Hour 3: TickOfDay 7200 ... вместо 10800 ... потому что это второй час дня», то есть вы ожидаете, что фактическое время истечет с полуночи. Обратите внимание, что 27.03 имеет только 23 часа настенных часов и 10.20 имеет 25 часов настенных часов. –

+0

(Пожалуйста, измените 10.20 до 20.10). –

Смежные вопросы