Установка часового пояса в Windows с помощью C ++ несовместима - PullRequest
0 голосов
/ 28 марта 2020

Я работаю над проектом с функцией, которая устанавливает часовой пояс системы на основе координат GPS. Координаты передаются в библиотеку ZoneDetect, которая используется для заполнения структуры TIME_ZONE_INFORMATION.

Проблема, с которой я сталкиваюсь, заключается в том, что, хотя это отлично работает в моей системе разработки, когда я запускаю программу на целевом компьютере (мобильная система в транспортном средстве), время составляет один час. Я проверил, что координаты верны и что он ищет правильный часовой пояс. Я предполагаю, что проблема связана с переходом на летнее время, но я не могу объяснить, почему он работает в одной системе, а не в другой. Насколько я могу судить, системные настройки, относящиеся ко времени, абсолютно одинаковы для обоих. Для справки, обе системы работают Windows 10; моя система разработки работает как VirtualBox VM.

Любая помощь будет принята с благодарностью.

bool timezonelookup::set_system_timezone(double lat, double lon) const
{
    auto [ID, info] = lookup(lat, lon);
    if (ID == "ERROR") return false;

    HANDLE hToken;
    TOKEN_PRIVILEGES tkp;
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
    LookupPrivilegeValue(NULL, SE_TIME_ZONE_NAME, &tkp.Privileges[0].Luid);
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
    TIME_ZONE_INFORMATION tzinfo;
    tzinfo.Bias = 0 - ((info.GMT_offset.hours * 60) + info.GMT_offset.minutes);
    wstring stdname;
    stdname.assign(info.standard_name.begin(), info.standard_name.end());
    wcsncpy_s(tzinfo.StandardName, stdname.c_str(), sizeof(stdname));
    if (!info.DST_name.empty())
    {
        memset(&tzinfo.StandardDate, 0, sizeof(SYSTEMTIME));
        tzinfo.StandardDate.wHour = info.DST_endtime.hours;
        tzinfo.StandardDate.wMinute = info.DST_endtime.minutes;
        tzinfo.StandardDate.wDayOfWeek = info.DST_endrule.day_of_week;
        tzinfo.StandardDate.wDay = info.DST_endrule.occurrence_of_day;
        tzinfo.StandardDate.wMonth = info.DST_endrule.month;
        tzinfo.StandardBias = 0;
        wstring dstname;
        dstname.assign(info.DST_name.begin(), info.DST_name.end());
        wcsncpy_s(tzinfo.DaylightName, dstname.c_str(), sizeof(dstname));
        memset(&tzinfo.DaylightDate, 0, sizeof(SYSTEMTIME));
        tzinfo.DaylightDate.wHour = info.DST_starttime.hours;
        tzinfo.DaylightDate.wMinute = info.DST_starttime.minutes;
        tzinfo.DaylightDate.wDayOfWeek = info.DST_startrule.day_of_week;
        tzinfo.DaylightDate.wDay = info.DST_startrule.occurrence_of_day;
        tzinfo.DaylightDate.wMonth = info.DST_startrule.month;
        tzinfo.DaylightBias = 0 - ((info.DST_adjustment.hours * 60) + info.DST_adjustment.minutes);
    }
    return SetTimeZoneInformation(&tzinfo);
}
...