Как мы можем разработать методы кодирования, разработанные для защиты от ошибок високосного года? [закрыто]

Microsoft только что объявила об ошибке в программном обеспечении при расчете дат (в течение високосного года) вызвал серьезный сбой в работе Windows Azure на прошлой неделе.

Было ли это действительно простой ошибкой в ​​суждении, работающей вокруг DateTime.Now.AddYears(1) в високосный год?

Какие методы кодирования могли бы предотвратить это?

ИЗМЕНИТЬ Как указал dcstraw, DateTime.Now.AddYears(1) в високосный год действительно возвращает правильную дату в .NET. Так что это не ошибка фреймворка, а, очевидно, ошибка в вычислениях Date.

81 голос | спросил Fixer 10 MarpmSat, 10 Mar 2012 18:38:10 +04002012-03-10T18:38:10+04:0006 2012, 18:38:10

3 ответа


0

Бесстыдная вилка:

Используйте лучший API даты и времени

Встроенные библиотеки даты и времени .NET ужасно сложны в использовании. Они делают позволяют вам делать все, что вам нужно, но вы не можете выразить себя четко через систему типов. DateTime беспорядок , DateTimeOffset может заставить вас думать, что вы на самом деле сохранение информации о часовом поясе, когда вас нет, и TimeZoneInfo не заставляет вас думать обо всем, что вы должны учитывать.

Ни один из них не дает хорошего способа сказать «просто время дня» или «просто дата», а также не проводит четкого различия между «местным временем» и «временем в определенном часовом поясе». И если вы хотите использовать календарь, отличный от григорианского, вам нужно все время проходить через класс Calendar.

Именно поэтому я создаю время Noda - альтернативную библиотеку даты и времени, основанную на порт «движка» Joda Time , но с новым (и более компактным) API сверху.

Некоторые моменты, о которых вы, возможно, захотите подумать, которые легко пропустить, если вы о них не знаете:

  • Отображение локальной даты /времени в определенном часовом поясе не так просто, как вы думаете. Конкретные локальные дата /время могут появляться один, два раза (неоднозначность) или ноль раз (пропускается) из-за переходов на летнее время
  • Часовые пояса отличаются друг от друга исторически - более чем TimeZoneInfo, как правило, откровенны. (Он не поддерживает часовой пояс, чье представление о «стандартном времени» меняется со временем или которое переходит в постоянное летнее время.)
  • Даже с базой данных zoneinfo идентификаторы часовых поясов не всегда стабильны. (CLDR решает эту проблему; кое-что я надеюсь поддержать в Noda Time.)
  • Текстовые представления даты и времени - это кошмар, и не только с точки зрения упорядочения, но и с разделителями даты, с разделителями времени и странными вещами, такими как родительные названия месяцев
  • Начало дня не всегда полночь - например, в Бразилии весенний переход на летнее время переводит настенные часы с 11:59:59 на час ночи
  • В некоторых случаях (о чем я знаю) часовой пояс может пропустить целый день - 30 декабря 2011 года в Самоа не произошло! Я подозреваю, что большинство разработчиков могут игнорировать это, но ...
  • Если вы собираетесь использовать календарь, отличный от григорианского, будьте осторожны и убедитесь, что вы действительно знаете, как он будет себя вести.

Что касается конкретных методов разработки:

  • Подумайте о том, что вы на самом деле пытаетесь представить. Я ожидаю, что основное преимущество Noda Time будет заставлять разработчиков выбирать между различными типами представления своих данных. Получите это право, а все остальное проще.
  • Модульное тестирование всего, что вы можете придумать. Конечно, это будет зависеть от того, что именно делает ваша система, но особенно учитывает разные часовые пояса, что происходит при переходах на летнее время и, конечно же, на високосные годы.
  • Я бы посоветовал ввести "интерфейс, похожий на часы" - сервис для определения текущего времени, - а не явно вызывать DateTime.Now или DateTime.UtcNow; это облегчает (выполнимо!) юнит-тестирование
  • Если вы выполняете несколько операций с "сейчас", получите эту дату /время один раз и запомните ее, а не неоднократно запрашивая "сейчас" - в противном случае значение может измениться неудачным образом между вызовы.
  • "Делать все в UTC" тоже не всегда ответ - если я хочу знать, "когда именно" две недели спустя "происходят в моем местном часовом поясе?" тогда мне нужно сохранить локальную дату /время, а также часовой пояс.
ответил Jon Skeet 10 MarpmSat, 10 Mar 2012 18:43:56 +04002012-03-10T18:43:56+04:0006 2012, 18:43:56
0

Стоит отметить, что ошибка, вероятно, была вызвана не той строкой, которую вы опубликовали:

DateTime.Now.AddYears(1)

Это не создает недопустимую дату. Если вы запустите:

(new DateTime(2012, 2, 29)).AddYears(1)

вы получите 28 февраля 2013 года. Я не знаю, на чем написан гостевой агент Azure, но, должно быть, произошел сбой другого вызова. Плохой способ сделать это в .NET был бы:

new DateTime(today.Year + 1, today.Month, today.Day)

Это вызывает исключение, если today является високосным днем. Однако в блоге Microsoft о проблеме Azure говорится, что они создали недопустимую дату 29 февраля 2013 года, что, я не уверен, возможно сделать с DateTime в .NET.

Я не говорю, что DateTime и DateTimeOffset не подвержен ошибкам, просто я не думаю, что они вызвали бы именно эту проблему.

ответил dcstraw 10 MarpmSat, 10 Mar 2012 20:13:32 +04002012-03-10T20:13:32+04:0008 2012, 20:13:32
0
  

Как мы можем разработать методы кодирования, предназначенные для защиты от ошибок високосного года?   Какие методы кодирования могли бы предотвратить это?

Конкретные даты модульного тестирования, как упомянул Джон, - это одна из практических программ, которая поможет, однако, ничто не сравнится с тем, что я определяю как «ручной тест интеграции»

измените время на своем сервере разработки /испытательном стенде и посмотрите, что произойдет, когда время истечет.

Не зацикливайтесь на деталях, является ли это «практикой кодирования» - очевидно, вы не можете сделать это для каждой даты в календаре - выберите даты, которые вас интересуют, будь то 29 февраля, конец Даты за месяц или переход на летнее время.

ответил wal 14 MaramWed, 14 Mar 2012 03:35:05 +04002012-03-14T03:35:05+04:0003 2012, 03:35:05

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132