Включает ли структура Windows FILETIME дополнительные секунды?
FILETIME
структура считается с 1 января 1601 года (предположительно с начала этого дня) согласно документации Microsoft, но включает ли это дополнительные секунды?
7 ответов
Вопрос не должен быть, если FILETIME
включает в себя високосные секунды.
Так должно быть:
Есть люди, функции и библиотеки, которые интерпретируют
FILETIME
(т.е.FileTimeToSystemTime
) включать високосные секунды при подсчете длительности?
Простой ответ "нет". FileTimeToSystemTime
возвращает секунды как 0..59
,
Более простой ответ: "Конечно, нет, как это могло быть?".
Моя машина с Windows 2000 не знает, что за десять лет с момента ее выпуска было добавлено 2 дополнительных секунды. Любая интерпретация FILETIME
неправильно.
Наконец, вместо того, чтобы полагаться на логику, мы можем определить путем прямого экспериментального наблюдения ответ на вопрос постеров:
var
systemTime: TSystemTime;
fileTime: TFileTime;
begin
//Construct a system-time for the 12/31/2008 11:59:59 pm
ZeroMemory(@systemTime, SizeOf(systemTime));
systemtime.wYear := 2008;
systemTime.wMonth := 12;
systemTime.wDay := 31;
systemTime.wHour := 23;
systemtime.wMinute := 59;
systemtime.wSecond := 59;
//Convert it to a file time
SystemTimeToFileTime(systemTime, {var}fileTime);
//There was a leap second 12/31/2008 11:59:60 pm
//Add one second to our filetime to reach the leap second
filetime.dwLowDateTime := fileTime.dwLowDateTime+10000000; //10,000,000 * 100ns = 1s
//Convert the filetime, sitting on a leap second, to a displayable system time
FileTimeToSystemTime(fileTime, {var}systemTime);
//And now print the system time
ShowMessage(DateTimeToStr(SystemTimeToDateTime(systemTime)));
Добавление одной секунды к
12/31/2008 11:59:59pm
дает
1/1/2009 12:00:00am
скорее, чем
1/1/2009 11:59:60pm
QED
Оригинальный плакат может не понравиться, но Бог намеренно сфальсифицировал его, чтобы год не делился на день поровну. Он сделал это просто, чтобы испортить программистов.
Не может быть однозначного ответа на этот вопрос без предварительного решения: что на самом деле учитывает Windows FILETIME? Документы Microsoft говорят, что с 1601 UTC он насчитывает 100 наносекундных интервалов, но это проблематично.
Никакой формы скоординированного на международном уровне времени не существовало до 1960 года. Само название UTC не встречается ни в одной литературе до 1964 года. Официальное обозначение UTC не существовало до 1970 года. Но оно ухудшается. Королевская Гринвичская обсерватория не была создана до 1676 года, поэтому даже попытка истолковать FILETIME, поскольку GMT не имеет четкого значения, и только в это время маятниковые часы с точными спусками стали давать точность в 1 секунду.
Если FILETIME интерпретируется как среднее количество солнечных секунд, то число високосных секунд с 1601 равно нулю, поскольку UT не имеет високосных секунд. Если FILETIME интерпретируется так, как если бы были атомные хронометры, то число високосных секунд с 1601 года составляет около -60 (это минус 60 високосных секунд).
Это древняя история, а как насчет эпохи со времен атомных хронометров? Это не лучше, потому что национальные правительства не делали различий между средними солнечными секундами и секундами СИ. В течение десятилетия МСЭ-R обсуждал вопрос об отказе от високосных секунд, но они не достигли международного консенсуса. Часть причины этого можно увидеть в javascript на этой странице (см. Также ссылку delta-T на этой странице, где приведены сюжеты древней истории). Поскольку национальные правительства не проводят четкого разграничения, любая попытка определить количество секунд с 1972 года рискует оказаться недействительной в соответствии с законодательством какой-либо юрисдикции. Делегаты МСЭ-R знают об этой сложности, как и члены комитета POSIX. До тех пор, пока дипломатические вопросы не будут проработаны, пока национальные правительства и международные стандарты не проведут четкое различие и выбор между средними значениями солнечной и СИ секунд, мало надежды на то, что компьютерные стандарты могут последовать их примеру.
Вот еще немного информации о том, почему именно эта дата была выбрана.
Структура FILETIME записывает время в виде интервалов в 100 наносекунд с 1 января 1601 года. Почему была выбрана эта дата?
Григорианский календарь работает по 400-летнему циклу, и 1601 год - это первый год цикла, который был активен во время разработки Windows NT. Другими словами, это было выбрано для того, чтобы математика получилась красивой.
На самом деле у меня есть электронное письмо от Дейва Катлера, подтверждающее это.
Ответ на этот вопрос раньше был нет, но изменился на: ДА, вроде как, иногда...
Согласно статье в блоге команды Windows Networking:
Начиная с Server 2019 и API обновления Windows 10 октября [2018], теперь будут учитываться все дополнительные секунды, которые операционная система знает, когда она переводит FILETIME в SystemTime.
Поскольку с момента добавления этой функции не было выпущено дополнительных секунд, операционная система по-прежнему не знает ни о каких дополнительных секундах. Однако, когда следующая официальная секунда проложит свой путь в мир, компьютеры с Windows, на которых включена эта новая функция, будут отслеживать ее, и, таким образом, FILETIME
значения будут смещены на количество високосных секунд на компьютере в момент их интерпретации.
Сообщение в блоге продолжает описывать:
В FILETIME не вносятся изменения. Он по-прежнему представляет число интервалов в 100 нс с начала эпохи. Что изменилось, так это интерпретация этого числа, когда оно конвертируется в SYSTEMTIME и обратно. Вот список затронутых API:
- GetSystemTime
- GetLocalTime
- FileTimeToSystemTime
- FileTimeToLocalTime
- SystemTimeToFileTime
- SetSystemTime
- SetLocalTime
До этого выпуска у SYSTEMTIME были допустимые значения wSecond в диапазоне от 0 до 59. Теперь SYSTEMTIME был обновлен и теперь имеет значение 60, при условии, что год, месяц и день представляют день, в течение которого допустима дополнительная секунда.
...
Чтобы получить 60 секунд в структуре SYSTEMTIME, процесс должен явно подписаться.
Обратите внимание, что согласие применяется к поведению в функциях, перечисленных на том, как FILETIME
сопоставлен с SYSTEMTIME
, Независимо от того, подписаны вы или нет, операционная система по-прежнему будет смещена FILETIME
значения в соответствии с високосными секундами, о которых он знает.
Что касается совместимости, в статье говорится:
Приложения, которые полагаются на сторонние фреймворки, должны гарантировать, что реализация их фреймворка в Windows также вызывает правильные API для вычисления правильного времени, иначе приложение сообщит о неверном времени.
А также предоставляет ссылки на более раннюю публикацию, которая описывает, как отключить всю функцию, следующим образом:
... вы можете вернуться к предыдущему поведению операционной системы и отключить дополнительные секунды, добавив следующий раздел реестра:
HKLM:\SYSTEM\CurrentControlSet\Control\LeapSecondInformation
- Тип: "REG_DWORD"
- Имя: включено
- Значение:
0
Отключает общесистемную настройку- Значение:
1
Включает общесистемную настройкуДалее перезагрузите вашу систему.
Дополнительные секунды непредсказуемо добавляются IERS. 23 секунды были добавлены с 1972 года, когда были определены UTC и високосные секунды. Википедия говорит, что "поскольку скорость вращения Земли в долгосрочной перспективе непредсказуема, невозможно предсказать потребность в них более чем за шесть месяцев".
Поскольку вам придется вести историю о том, когда были добавлены високосные секунды, и постоянно обновлять ОС, чтобы сохранить ссылку на то, когда они были вставлены, а разница настолько мала, справедливо не ожидать, что ОС общего назначения будет компенсировать високосные секунды.
Кроме того, обычное отклонение тактовых частот простых электронных часов в вашем ПК по сравнению с UTC намного больше, чем компенсация, необходимая для високосных секунд. Если вам нужна такая точность, чтобы компенсировать високосные секунды, вам не следует использовать крайне неточные часы ПК.
Согласно этому комментарию окна совершенно не знают о високосных секундах. Если вы добавите 24 * 60 * 60 секунд к FILETIME, который представляет 1:39:45 сегодня, вы получите FILETIME, который представляет 1:39:45 завтра, несмотря ни на что.
Очень грубое резюме:
UTC = (атомное время) + (високосные секунды) ~~ (среднее солнечное время)
Документация MS говорит, в частности, "UTC", и поэтому должна включать високосные секунды. Как всегда с MS, ваш пробег может отличаться.