Самый простой способ получить текущее время в текущем часовом поясе, используя boost:: date_time?

Если я делаю date +%H-%M-%S в командной строке (Debian/Lenny), я получаю удобное для пользователя (не UTC, не DST-less, время, которое нормальный человек показывает на своих наручных часах) время.

Какой самый простой способ получить то же самое с boost::date_time ?

Если я сделаю это:

std::ostringstream msg;

boost::local_time::local_date_time t = 
  boost::local_time::local_sec_clock::local_time(
    boost::local_time::time_zone_ptr()
  );

boost::local_time::local_time_facet* lf(
  new boost::local_time::local_time_facet("%H-%M-%S")
);

msg.imbue(std::locale(msg.getloc(),lf));
msg << t;

Тогда msg.str() на час раньше того времени, которое я хочу увидеть. Я не уверен, связано ли это с тем, что он показывает время UTC или местного часового пояса без поправки на летнее время (я нахожусь в Великобритании).

Каков самый простой способ изменить приведенное выше, чтобы получить время местного часового пояса с поправкой на летнее время? У меня есть идея, что это связано с boost::date_time:: c_local_adjustor, но я не могу понять это из примеров.


person timday    schedule 10.04.2010    source источник
comment
Я считаю, что это дубликат stackoverflow.com/ вопросы/2492775/get-local-time-with-boost/. Краткая версия: используйте boost::posix_time для создания объекта времени из системных часов. Это отлично работает для местного времени (локаль C). Возможность построения времени для других часовых поясов зависит от того, какие локали у вас есть.   -  person Nate    schedule 12.04.2010
comment
Спасибо за указатель; фундаментальная проблема в том, что я не особо оценил разницу между local_time/posix_time.   -  person timday    schedule 13.04.2010


Ответы (3)


Это делает то, что я хочу:

  namespace pt = boost::posix_time;
  std::ostringstream msg;
  const pt::ptime now = pt::second_clock::local_time();
  pt::time_facet*const f = new pt::time_facet("%H-%M-%S");
  msg.imbue(std::locale(msg.getloc(),f));
  msg << now;
person timday    schedule 12.04.2010
comment
Он сказал простой способ. Нет простого способа с датой/временем Boost. Они слишком много абстрагировались и обобщали. - person std''OrgnlDave; 13.04.2012
comment
Я думаю, что это немного грубо (хотя и не совсем неоправданно). Приведенное выше достаточно просто (хотя и многословно со всеми пространствами имен). Проблема часто заключается в том, что документация говорит вам, как добраться до Альфы Центавра, когда вы просто хотели прогуляться по кварталу. С другой стороны, некоторое время назад я хотел сделать то же самое на Python, и для этого не требовалось публикации в StackOverflow. - person timday; 14.04.2012
comment
не заставляйте меня начинать с моего первого опыта работы с «posix time» boost и о том, как легко я думал, что будет получить отметку времени POSIX, и как я ошибался! с учетом сказанного, мы все пропали бы без Boost - person std''OrgnlDave; 14.04.2012
comment
То, что вы сделали, также будет очень неэффективным, если вы собираетесь печатать много раз. И это очень распространенная ошибка, которую я вижу. Создайте фасет и локаль один раз, сохраните их как статические, а затем начните с imbue(), когда у вас будет что-то для печати. - person CashCow; 08.02.2013

Хотя это не использует boost::date_time, это относительно легко с boost::locale, который более приспособлен для этой задачи. Поскольку вам нужно просто получить отформатированное время из текущей локали.

ИМХО boost::date_time следует использовать, когда вы имеете дело с такими программами, как вычисления Ганта/планирования, если у вас много арифметики date_time. Но просто для того, чтобы использовать время и выполнять некоторые арифметические действия, вы быстрее добьетесь успеха с boost::locale.

#include <iostream>
#include <boost/locale.hpp>

using namespace boost;

int main(int argc, char **argv) {
   locale::generator gen;
   std::locale::global(gen(""));

   locale::date_time now;
   std::cout.imbue(std::locale());       
   std::cout << locale::as::ftime("%H-%M-%S") << now << std::endl;

   return 0;
}

Прямо сейчас он должен вывести: 15-45-48. :)

person daminetreg    schedule 26.04.2013

Я не нашел других ответов, которые были бы достаточно удобными, поэтому вот пример, демонстрирующий, как получить местное или универсальное время с полным контролем единиц:

#include <boost/date_time/local_time/local_time.hpp>
#include <boost/format.hpp>

#include <iostream>

int main()
{
    auto const now = boost::posix_time::microsec_clock::local_time(); // or universal_time() for GMT+0
    if (now.is_special()) {
        // some error happened
        return 1;
    }

    // example timestamp (eg for logging)
    auto const t = now.time_of_day();
    boost::format formater("[%02d:%02d:%02d.%06d]");
    formater % t.hours() % t.minutes() % t.seconds() % (t.total_microseconds() % 1000000);
    std::cout << formater.str();
}

Примечание: структура time_of_day не имеет функций .microseconds() или .nanoseconds(), есть только .fractional_seconds(), которая возвращает целое число, кратное единице измерения, зависящей от конфигурации. .num_fractional_digits() можно использовать для получения информации о точности, где 10 ^ frac_digits — это число fractional_seconds, равное 1 секунде.

Чтобы получить независимые от конфигурации доли секунды, можно выполнить по модулю с функциями total_ milli/micro/nano _seconds() в качестве обходного пути.

person Xeverous    schedule 04.03.2020