Intereting Posts

std :: chrono :: system_clock :: now () с учетом настраиваемого часового пояса OS

Я программирую код C ++, который работает на встроенном Linux BusyBox. Мой код и его библиотеки имеют несколько вызовов для std::chrono::system_clock::now() чтобы получить текущее время.

С тех пор мой ящик был настроен как часовой пояс dafault (UTC), и все работает отлично, процессы работают и результаты в порядке.

Теперь мне пришлось установить, чтобы мой Linux оставался в другом часовом поясе. Затем я сделал это, установив в поле /etc/profile :

 export TZ=UTC+3 

Когда я выдаю команду date и консоль, я получаю правильное время, но мои вызовы в std::chrono::system_clock::now() Я все еще получаю время UTC, а не время, указанное в команде date ( правильное время).

Я не хочу менять все мои вызовы now() – на них сотни. И это заставляет мои процессы работать с разным временем, чем правильное время, установленное на консоли.

Есть ли способ решить это без изменения моего кода? Что-нибудь мне здесь не хватает?

Спасибо за помощь.

    Несмотря на то, что стандарт не определен стандартом, каждая реализация std::chrono::system_clock::now() отслеживает Unix Time , что очень близко приближается к UTC.

    Если вы хотите перевести std::chrono::system_clock::now() в локальное время, вы можете либо перевести system_clock::time_point в time_t через system_clock::to_time_t , а затем проработать свой путь через C API (например, localtime ) , или вы можете попробовать эту современную библиотеку часового пояса, которая построена поверх :

    https://howardhinnant.github.io/date/tz.html

    Вы бы использовали это, чтобы получить текущее местное время следующим образом:

     #include "tz.h" #include  int main() { using namespace date; using namespace std::chrono; auto t = make_zoned(current_zone(), system_clock::now()); std::cout << t << '\n'; } 

    make_zoned - это заводская функция, которая возвращает тип zoned_time с любой точностью, system_clock поддерживает system_clock (например, наносекунды). Это спаривание time_zone и system_clock::time_point .

    Вы можете получить local_time который является std::chrono::time_point следующим образом:

      auto t = make_zoned(current_zone(), system_clock::now()); auto lt = t.get_local_time(); std::cout << lt.time_since_epoch().count() << '\n'; 

    Хотя библиотека имеет удаленный API для автоматической загрузки базы данных часовых поясов IANA , этот API можно отключить, компилируя с -DHAS_REMOTE_API=0 . Все это подробно описано в инструкциях по установке . При отключенном интерфейсе API вам придется вручную загрузить базу данных из базы данных часовых поясов IANA (это всего лишь tar.gz ).

    Если вам требуется текущее смещение UTC, это можно получить следующим образом:

      auto t = make_zoned(current_zone(), system_clock::now()); auto offset = t.get_info().offset; std::cout << offset << '\n'; 

    В вышеприведенном fragmentе я использую "chrono_io.h" найденный в том же репозитории github для печати offset . offset имеет тип std::chrono::seconds . Это просто для меня:

     -14400s 

    (-0400)

    Наконец, если вы хотите узнать имя IANA вашего текущего часового пояса, это просто:

     std::cout << current_zone()->name() << '\n'; 

    который для меня просто выводит:

     America/New_York 

    Тип, возвращаемый из name() - std::string . При желании можно записать эту строку, а затем использовать time_zone с этим именем, даже если это не текущий часовой пояс компьютера:

     auto tz_name = current_zone()->name(); // ... auto t = make_zoned(tz_name, system_clock::now()); // current local time in tz_name