Подтвердить что ты не робот

Как конвертировать между локальным и универсальным временем с помощью boost:: date_time?

Как я могу конвертировать между локальным и временем UTC (в частности, от локального к UTC) с помощью boost::date_time с использованием текущего системного часового пояса? Я знаю о boost::date_time::local_adjustor, но для этого требуется аргумент шаблона, зависящий от часового пояса.

Неудачный, независимый от платформы способ, как мне это сделать конкретно в Linux?

Как в стороне, как несуществующие моменты времени обрабатываются во время преобразования? Например, если на один день короткий час из-за DST, и я пытаюсь преобразовать точку времени из пропавшего часа, каково будет итоговое универсальное время?

4b9b3361

Ответ 1

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


    using namespace boost::posix_time;
    using namespace boost::gregorian;

    time_duration UTC_Diff;
    {
        ptime someUTC_Time(date(2008, Jan, 1), time_duration(0, 0, 0, 0));
        ptime someLocalTime = boost::date_time::c_local_adjustor::utc_to_local(someUTC_Time);
        UTC_Diff = someLocalTime - someUTC_Time;
    }

Поскольку вы находите разницу, легко вычислить время UTC.

Ответ 2

Если у вас есть local_date_time в правильном часовом поясе, вы можете напрямую использовать метод utc_time, чтобы получить время в UTC.

Посмотрите, у вас есть простой ptime, который вы хотите интерпретировать как находящийся в заданном часовом поясе, а затем преобразовать его в UTC для этого, я использую этот конструктор

local_date_time(...)
  Parameters:
    date
    time_duration 
    time_zone_ptr
    bool

В соответствии с docs он переинтерпретирует данные о времени, которые должны быть в заданном часовом поясе, это означает, что он может использоваться для локализации любого заданного времени ptime и после что можно использовать метод utc_time, вот функция полезности для преобразования любого времени ptime из заданного часового пояса в UTC

ptime get_local_to_utc(const ptime& t, const time_zone_ptr& localtz){
    if(t.is_not_a_date_time()) return t;
    local_date_time lt(t.date(), t.time_of_day(), localtz, local_date_time::NOT_DATE_TIME_ON_ERROR);
    return lt.utc_time();
}

Ответ 3

Преобразование между UTC и local в зависимости от разницы между выбранным временем и UTC работает только до тех пор, пока вы остаетесь на той же стороне момента изменения DST.

Следующие действия будут работать для любой даты (извините, не local- > UTC):

    bpt::ptime utils::utcToLocal(bpt::ptime utcTime)
{
  // NOTE: the conversion functions between ptime and time_t/tm are broken so we do it ourselves.
  bpt::time_duration timeSinceEpoch = utcTime - bpt::ptime(boost::gregorian::date(1970, 1, 1), bpt::time_duration(0,0,0));
  time_t secondsSinceEpoch = timeSinceEpoch.total_seconds();
  tm* localAsTm = localtime(&secondsSinceEpoch);
  return bpt::ptime(
    boost::gregorian::date(
      localAsTm->tm_year + 1900, 
      localAsTm->tm_mon + 1, 
      localAsTm->tm_mday), 
    bpt::time_duration(
      localAsTm->tm_hour,
      localAsTm->tm_min,
      localAsTm->tm_sec));
}