Несколько вещей:
SYSTEMTIME
- это простая структура. Он имеет отдельные поля для года, месяца, дня недели, дня (месяца), часа, минуты, секунды и миллисекунды. Это не UT C или местное время, или что-то еще само по себе. Это не учитывается, пока вы не передадите его в функцию.
FILETIME
- это еще одна простая структура. Он представляет количество интервалов в 100 наносекунд с полуночи 1601-01-01. Большая часть документации заставит вас думать, что это всегда в UT C, но есть функции, подобные FileTimeToLocalFileTime
, которые опровергают это. Таким образом, подобно SYSTEMTIME
, каждая отдельная функция должна решать, как ее интерпретировать.
Функция SystemTimeToFileTime
принимает указатель на SYSTEMTIME
, который интерпретируется как UT C и возвращает указатель на FILETIME
, что также в терминах UT C. Не задействован местный часовой пояс.
Не пытайтесь самостоятельно настраивать местное время (st.wHour = 6
в вашем коде). Час будет меняться в зависимости от часового пояса и летнего времени.
Вы не видели никакого ответа от GetTimeZoneInformation
, кроме TIME_ZONE_STANDARD
, потому что это говорит вам о том, что в настоящее время действует - что не связано с датами, с которыми вы, возможно, работаете.
Вы не должны пытаться выяснить, как настроить DST самостоятельно. ТЛЧ не универсально применим, и это не всегда один час смещения. Вместо этого используйте функцию, которая преобразует из часового пояса, который вас интересует, в UT C.
В конечном счете, звучит так, будто вы спрашиваете, как установить время файла в полночь местный часовой пояс на определенную дату. Таким образом, я предлагаю вам go, выполнив следующие действия:
Создайте SYSTEMTIME
с датой, которая вас интересует, и компонентами времени, установленными в нули (по умолчанию).
Получить местный часовой пояс с помощью функции GetDynamicTimeZoneInformation
. Требуется версия «dynamici c», которая учитывает любые исторические различия в правилах для стандартного времени и летнего времени, о которых знает Windows, а не только текущий набор правил.
Передайте эти два значения в функцию TzSpecificLocalTimeToSystemTimeEx
. Он будет интерпретировать входное время как находящееся во входном часовом поясе (который был локальным часовым поясом системы). В результате получается FILETIME
в единицах UT C.
. Передайте это значение в SetFileTime
, что предполагает ввод в единицах UT C.
Кроме того, имейте в виду, что не все файловые системы отслеживают время файла одинаково :
NTFS сохраняет фактическое время UT C, поэтому вы можете перемещать файлы между компьютерами, и временная метка представляет одну и ту же точку в универсальном времени, даже если компьютеры имеют разные настройки часового пояса.
FAT и его варианты хранить местное время. Поэтому, когда вы звоните SetFileTime
, Windows переводится из UT C в местный часовой пояс и записывает результат. Если вы затем откроете файл в системе с другим часовым поясом, дата будет интерпретирована как , что , что приведет к другому времени UT C. (Это часто наблюдается на USB-накопителях, картах памяти и т. Д. c. При перемещении файлов с камер на компьютеры.)
Наконец, вы сказали:
... Желательно, чтобы это работало как с датами 60-х годов, так и с текущими.
К сожалению, Windows часовые пояса не отслеживают исторические даты так далеко. Политика Microsoft в отношении часовых поясов предназначена для отслеживания часовых поясов и правил перехода на летнее время на 2010 год и далее для всех населенных пунктов на Земле. Хотя в нескольких часовых поясах отслеживаются некоторые исторических изменений, произошедших до 2010 года, как артефактов до того, как эта политика была формализована. (Они точны в пределах данной зоны, но не одинаковы в начальные годы во всех зонах).
Если исторические даты важны для вашего приложения, вам понадобится совсем другой подход - тот, который не использует данные часового пояса Windows, а вместо этого использует базу данных часовых поясов IANA . (Подробнее об этом в теге часового пояса wiki .) Вот несколько идей, которые вы можете изучить:
Проект ICU имеет поддержку часовых поясов и C реализация . Это немного тяжело для этой цели, но хорошо, если вы используете его для других аспектов локализации приложения.
У Говарда Хиннанта (который прокомментировал вопрос выше) есть превосходный Библиотека дат с поддержкой часового пояса IANA.
Может быть возможно получить то, что вам нужно, из класса Windows.Globalization.Calendar
UWP. Я не проверял, будет ли он использовать исторические правила из данных IANA или данные Windows. (Если у меня будет возможность проверить, я вернусь и обновлю этот ответ.)
Имейте в виду, что база данных IANA гарантирует только с 1970 года. Вы сказали, что вам это нужно с 1960 года, и хотя есть некоторые зоны с данными для этого (а некоторые намного старше), нет никаких гарантий правильности в этот период.