Интересно о C#: Точность и достоверность DateTime

пятница, 9 апреля 2010, Александр Краковецкий

Продолжаем цикл статей "Интересно о C#". Сегодня поговорим о точности и достоверности типа данных DateTime.

Структура DateTime хранит даты в виде 64-битного числа, которое отображает количество тиков от определенного стартового времени. 10 миллионов тиков равны одной секунде.

Это достаточно большой порядок точности. Можно представлять дату и время с точностью до микросекунд, что более, чем достаточно. Не всегда, конечно. На современном железе можно выполнить несколько сотен операций за один тик, поэтому иногда есть необходимость увеличить точность замера.

Возникает проблема, насколько достоверна эта точность? Переживать здесь не нужно. Ведь можно представить свой рост в виде числа с двойной точностью - 1.799992352094 метра, т.е. с точностью триллионной доли метра, в то время когда достоверность этого числа все равно будет в пределах сотых метра, так как не существует устройства, которое могло бы измерить ваш рост с триллионной точностью.

То же самое происходит с датами и временем. DateTime может иметь очень высокую точность, но в то же время не иметь нужной достоверности. Я регулярно синхронизирую свои компьютеры с time.gov. Но если я этого не делаю, то часы смещаются на несколько секунд в год. Допустим, мои часы теряют 1 секунду в год. Год содержит 31.5 миллионов секунд и 10 миллионов тиков в секунду, поэтому мы теряем один тик раз в 3.15 секунд. Даже если мои часы будут достоверными в определенный момент времени, то уже через 10 секунд они не будут обладать необходимой достоверностью. В течении дня большая часть точности будет утрачена.

Если провести небольшой эксперимент, то можно увидеть, что операционная система показывает время с достоверностью в тысячи раз меньшей чем точность, когда вы спрашиваете “который час?”.

long ticks = DateTime.Now.Ticks;
while(true)
{
    if (ticks != DateTime.Now.Ticks)
    {
        ticks = DateTime.Now.Ticks;
        Console.WriteLine(ticks);
    }
    else
    {
        Console.WriteLine("same");
    }
}

На моей машине этот код выдает “same” 8 или 9 раз и потом внезапно свойство Ticks “прыгает” на 160000, что эквивалентно 16 миллисекундам (различные Windows могут давать разные результаты, которые зависят от алгоритмов замера потоков и других деталей реализации).

Т.е. на практике мы получаем всего лишь точность в 16 миллисекунд (ну и кончено, это еще зависит от того, как часто мы синхронизируемся с официальным временем).

Является ли это ошибкой в DateTime.Now? Не совсем. Задача таймера – выдавать результаты для использования в реальном мире аля “когда начнется такой-то сериал?” или “когда мы переведем наши часы на летнее время?” или “покажите мне документы, которые я правил в четверг после обеда”. Это вопросы, которые не требуют высокую достоверность.

В общем, на вопрос “который час?” необходимо отвечать с той степенью точности, которая отвечает степени достоверности, которую может предоставить система. Большинство компьютеров не синхронизируется с точным временем, поэтому точность, большая за достоверность, является ложью.

Теперь, вопрос “сколько времени прошло от определенного момента” абсолютно отличается от предыдущего. Если вам необходимо узнать, сколько времени заняла та или иная операция с высокой точностью, то необходимо использовать класс StopWatch. Он измеряет периоды с точностью до наносекунд и и достоверностью, близкой к точности.

Запомните, вам не нужно знать “который час” для того, чтобы посчитать “сколько времени прошло”.

Источник: http://blogs.msdn.com/ericlippert/archive/2010/04/08/precision-and-accuracy-of-datetime.aspx

Компании из статьи


Microsoft Украина


Сайт:
http://www.microsoft.com/ukr/ua/

Microsoft Украина Украинское подразделение компании Microsoft.

Ищите нас в интернетах!

Комментарии

Свежие вакансии