Boost - форматирование времени с точностью до секунды с отметкой времени

Мне нужно получить хорошо отформатированную временную метку (слегка измененный ISO 8601) с точностью до миллисекунды.

И примерная дата будет выглядеть так: 2011-09-28 13:11:15.237-08:00
Форматирование также должно иметь возможность перезаписываться.

Я играл с boost::posix_time::microsec_clock::local_time() и boost::posix_time::time_facet, который отлично работает за исключением случаев, когда речь идет о временных метках.
Поскольку время posix не содержит информации о часовом поясе, это просто невозможно (я предполагаю)

Итак, есть ли что-нибудь еще, что я мог бы использовать с точностью до миллисекунды, которая содержит информацию о часовом поясе, или я могу заставить time_facet работать с часовыми поясами?

Может быть, мне всегда следует использовать UTC?

Спасибо


person Nicklas A.    schedule 28.09.2011    source источник


Ответы (1)


Взгляните на класс boost::local_time::local_date_time. Вы можете указать часовой пояс и использовать локальные микросекундные часы для его инициализации, например

boost::local_time::local_date_time  my_ldt(boost::local_time::local_microsec_clock::local_time(new boost::local_time::posix_time_zone("EST-5EDT,M4.1.0,M10.5.0")));

Затем вы сможете использовать фасеты для форматирования строки.

Изменить: полный пример:

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>

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

int main(void)
{
    boost::posix_time::ptime  now = boost::posix_time::second_clock::local_time();
    boost::posix_time::ptime  utc = boost::posix_time::second_clock::universal_time();

    boost::posix_time::time_duration tz_offset = (now - utc);

    std::stringstream   ss;
    boost::local_time::local_time_facet* output_facet = new boost::local_time::local_time_facet();
    ss.imbue(std::locale(std::locale::classic(), output_facet));

    output_facet->format("%H:%M:%S");
    ss.str("");
    ss << tz_offset;

    boost::local_time::time_zone_ptr    zone(new boost::local_time::posix_time_zone(ss.str().c_str()));
    boost::local_time::local_date_time  ldt = boost::local_time::local_microsec_clock::local_time(zone);
    boost::local_time::local_time_facet* output_facet = new boost::local_time::local_time_facet();
    ss.imbue(std::locale(std::locale::classic(), output_facet));
    output_facet->format("%Y-%m-%d %H:%M:%S%f%Q");
    ss.str("");
    ss << ldt;
    std::cout << ss.str() << std::endl; // "2004-02-29 12:34:56.000789-05:00"

    std::cout << "Press return to exit" << std::endl;
    std::string wait_for_line;
    std::getline(std::cin, wait_for_line);

    return (0);
}
person tinman    schedule 28.09.2011
comment
Но я не хочу сам указывать часовой пояс, я хочу, чтобы это был системный часовой пояс - person Nicklas A.; 29.09.2011
comment
@Nicklas A: Извините, пропустил это. Глядя на этот вопрос (stackoverflow.com/questions/2136970/) вам нужно выполнить некоторые специфичные для ОС вызовы, чтобы получить текущий часовой пояс, а затем внедрить его в пользовательский часовой пояс Boost. - person tinman; 29.09.2011
comment
Интересно, насколько эффективным было бы получение как универсального, так и местного времени и их сравнение. - person Nicklas A.; 29.09.2011
comment
@Nicklas A: я обновил свой код, чтобы показать, что это возможно, хотя вы получаете только текущее смещение, а не полную спецификацию часового пояса. - person tinman; 29.09.2011
comment
Хорошее простое решение. Я только что улучшил ваш код с помощью цикла, чтобы избежать случая, когда у вас есть разница в 1 секунду между текущим временем и utc, что дает смещение, такое как UTC + 01:59:59 - person Caduchon; 07.03.2016