Преобразование смещения часового пояса из строки имени часового пояса в C / C ++ потокобезопасным способом - PullRequest
1 голос
/ 01 февраля 2020

Я пытаюсь реализовать функцию, которая может преобразовывать заданную строку имени часового пояса, что она делает:

  1. Принимает входную строку часового пояса, например, "Австралия / Мельбурн";
  2. Проверяет базу данных часового пояса хост-ОС (предположим, что это среда POSIX);
  3. Возвращает целое число смещения часового пояса в секундах (для Мельбурна в DST это 36000).

Это можно сделать, позвонив по номеру putenv("TZ=Australia/Melbourne"), но это , возможно, не является поточно-ориентированным .

Есть ли способ сделать это без putenv() или как-нибудь позволить ему быть поточно-ориентированным? Заранее спасибо!

Ответы [ 3 ]

2 голосов
/ 01 февраля 2020

Поскольку компиляторы еще не поддерживают все функции библиотеки C ++ 20 std::chrono, я напишу решение, использующее библиотеку Говарда Хиннанта datehttps://github.com/HowardHinnant/date. C ++ 20 вводит std::chrono::zoned_time, который вы можете использовать для достижения желаемого.

#include "date/tz.h"
#include <iostream>

int main()
{
    auto current_time = std::chrono::system_clock::now();
    auto la = date::zoned_time{"America/Los_Angeles", current_time};
    auto sy = date::zoned_time{"Australia/Sydney", current_time};
    std::cout << date::format("%T\n", sy.get_local_time() - la.get_local_time());
}

Приведенный выше пример даст вам разницу между двумя часовыми поясами. Кроме того, если вы хотите получить часовой пояс текущей ОС, вы можете использовать что-то, что, я надеюсь, будет поддерживаться компиляторами в будущем - std::chrono::time_zone::name.

1 голос
/ 01 февраля 2020

В C ++ 20 вы сможете использовать std::chrono::tzdb::locate_zone(), который преобразует данное имя часового пояса в std::chrono::time_zone объект, который вы можете запросить, чтобы получить смещение.

Нет стандартной функции C, которая работает с часовыми поясами. Есть POSIX.1-совместимые функции, но они действительно не поточнобезопасны. Однако, в зависимости от вашей операционной системы, вы можете открыть файлы базы данных часового пояса и проанализировать их вручную. Например, в Linux вы можете открыть /usr/share/zoneinfo/Australia/Melbourne и проанализировать его в соответствии с его спецификацией в справочной странице tzfile (5) .

0 голосов
/ 01 февраля 2020

В дополнение к проблемам потока OP, еще одно соображение:

"смещение часового пояса от строки имени часового пояса" в целом недостаточно, так как смещение отличается в зависимости от данных / времени в течение года.

Даже если в выбранной зоне не происходит ежегодных корректировок дневного света, смещение может изменяться в зависимости от истории зоны.

long offset(tz_name) недостаточно, long offset(tz_name, time_t t) необходимо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...