如何自定义“时间戳” Boost.Log 的格式

发布于 2024-11-06 06:59:54 字数 132 浏览 3 评论 0原文

我想得到年-月-日时:分:秒.分数(2位数字),如果我使用“%Y-%m-%d %H:%M:%S.%f”,我几乎得到了什么我想要秒的小数部分(最后一部分)例外,它在我的 Windows XP 上显示 6 位数字,我不知道如何只获取 2 位数字,知道吗?

I want to get year-month-day hour:minute:second.fraction(2 digits), if I use "%Y-%m-%d %H:%M:%S.%f", I got almost what I want exception for the fraction( last part ) of seconds, it's showing 6 digits on my Windows XP, I don't know how to get 2 digits only, any idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

原野 2024-11-13 06:59:54

我们用这个类来解决这个问题:

    class TimeStamp : public boost::log::attributes::local_clock {
        public:
            typedef boost::log::attribute_value attribute_type;
            typedef boost::log::attributes::local_time_traits TimeTraitsT;
            typedef TimeTraitsT::time_type time_type;
            typedef boost::log::attributes::basic_attribute_value< std::string > result_value;

        public:
            boost::shared_ptr< attribute_type > get_value() {
                time_type posix_time = boost::date_time::microsec_clock< time_type >::universal_time();
                time_type::time_duration_type time = posix_time.time_of_day();
                time_type::date_type date = posix_time.date();
                std::stringstream formatter;

                formatter
                    << date.year() << "-"
                    << std::setfill('0') << std::setw(2) << int(date.month()) << "-"
                    << std::setfill('0') << std::setw(2) << date.day() << " "
                    << std::setfill('0') << std::setw(2) << boost::date_time::absolute_value(time.hours()) << ":"
                    << std::setfill('0') << std::setw(2) << boost::date_time::absolute_value(time.minutes()) << ":"
                    << std::setfill('0') << std::setw(2) << boost::date_time::absolute_value(time.seconds()) << ","
                    << std::setfill('0') << std::setw(2) << boost::date_time::absolute_value(time.fractional_seconds()) / 1000
                ;

                return boost::make_shared< result_value >(formatter.str());
            }
    };

初始化如下:

boost::log::core::get()->add_global_attribute("TimeStamp", boost::make_shared< TimeStamp >());

并使用如下:

backend_ptr->set_formatter(
    boost::log::formatters::stream
        << boost::log::formatters::attr< std::string >("TimeStamp")
        << boost::log::formatters::message();

显然,该类允许我们访问或格式化我们希望的日期的任何部分

We addressed it with this class:

    class TimeStamp : public boost::log::attributes::local_clock {
        public:
            typedef boost::log::attribute_value attribute_type;
            typedef boost::log::attributes::local_time_traits TimeTraitsT;
            typedef TimeTraitsT::time_type time_type;
            typedef boost::log::attributes::basic_attribute_value< std::string > result_value;

        public:
            boost::shared_ptr< attribute_type > get_value() {
                time_type posix_time = boost::date_time::microsec_clock< time_type >::universal_time();
                time_type::time_duration_type time = posix_time.time_of_day();
                time_type::date_type date = posix_time.date();
                std::stringstream formatter;

                formatter
                    << date.year() << "-"
                    << std::setfill('0') << std::setw(2) << int(date.month()) << "-"
                    << std::setfill('0') << std::setw(2) << date.day() << " "
                    << std::setfill('0') << std::setw(2) << boost::date_time::absolute_value(time.hours()) << ":"
                    << std::setfill('0') << std::setw(2) << boost::date_time::absolute_value(time.minutes()) << ":"
                    << std::setfill('0') << std::setw(2) << boost::date_time::absolute_value(time.seconds()) << ","
                    << std::setfill('0') << std::setw(2) << boost::date_time::absolute_value(time.fractional_seconds()) / 1000
                ;

                return boost::make_shared< result_value >(formatter.str());
            }
    };

Initialized like this:

boost::log::core::get()->add_global_attribute("TimeStamp", boost::make_shared< TimeStamp >());

And used like this:

backend_ptr->set_formatter(
    boost::log::formatters::stream
        << boost::log::formatters::attr< std::string >("TimeStamp")
        << boost::log::formatters::message();

The class, obviously, lets us access or format any portion of the date we wish

↙厌世 2024-11-13 06:59:54

我正在使用这个

namespace boost
{
    BOOST_LOG_OPEN_NAMESPACE

    namespace attributes
    {
        template <typename date_time_type>
        void format_time_ms( std::ostringstream& formatter, const date_time_type& date_time)
        {
            auto time = date_time.time_of_day();
            using namespace std;
            formatter
                << setfill( '0') << setw( 2) << time.hours()   << ':'
                << setfill( '0') << setw( 2) << time.minutes() << ':'
                << setfill( '0') << setw( 2) << time.seconds() << ','
                << setfill( '0') << setw( 3) << time.fractional_seconds() / 1000;
        }

        template <typename date_time_type>
        std::string format_time_ms( const date_time_type& date_time)
        {
            std::ostringstream formatter;
            format_time_ms( formatter, date_time);
            auto time = date_time.time_of_day();
            return formatter.str();
        }

        template <typename date_time_type>
        std::string format_date_time_ms( const date_time_type& date_time, const char date_time_sep = ' ')
        {
            using namespace std;
            ostringstream formatter;
            auto date = date_time.date();
            formatter
                << date.year() << '-'
                << setfill( '0') << setw( 2) << int( date.month()) << '-'
                << setfill( '0') << setw( 2) << date.day() << date_time_sep;
            format_time_ms( formatter, date_time);
            return formatter.str();
        }

        template <typename date_time_type, const char date_time_sep = ' '>
        struct date_time_ms_formatter
        {           
            std::string operator () ( const date_time_type& date_time) { return format_date_time_ms( date_time, date_time_sep); }
        };

        struct time_ms_formatter
        {
            template <typename date_time_type>
            std::string operator () ( const date_time_type& date_time) { return format_time_ms( date_time); }
        };

        template <typename time_type>
        struct local_clock_source
        {
            time_type operator () () const
            {
                return date_time::microsec_clock<time_type>::local_time();
            }
        };

        template <typename time_type>
        struct universal_clock_source
        {
            time_type operator () () const
            {
                return date_time::microsec_clock<time_type>::universal_time();
            }
        };

        template <typename time_type, typename clock_source_type, typename formater_type>
        class custom_clock: public attribute
        {
        public:
            class impl: public attribute::impl
            {
            public:
                attribute_value get_value()
                {
                    auto str = formater_type()( clock_source_type()());
                    return make_attribute_value( str);
                }
            };

            custom_clock(): attribute( new impl()) {}

            explicit custom_clock( const cast_source& source): attribute( source.as<impl>()) {}
        };


        typedef custom_clock<boost::posix_time::ptime, local_clock_source<boost::posix_time::ptime>, date_time_ms_formatter<boost::posix_time::ptime, '\t'> >       local_date_time_ms_clock;
        typedef custom_clock<boost::posix_time::ptime, universal_clock_source<boost::posix_time::ptime>, date_time_ms_formatter<boost::posix_time::ptime, '\t'> >   universal_date_time_ms_clock;

        typedef custom_clock<boost::posix_time::ptime, local_clock_source<boost::posix_time::ptime>, time_ms_formatter>     local_time_ms_clock;
        typedef custom_clock<boost::posix_time::ptime, universal_clock_source<boost::posix_time::ptime>, time_ms_formatter> universal_time_ms_clock;
    }

    BOOST_LOG_CLOSE_NAMESPACE // namespace log
}

初始化为

BOOST_LOG_ATTRIBUTE_KEYWORD( dateTimeStamp,     "DateTime",     boost::posix_time::ptime)
BOOST_LOG_ATTRIBUTE_KEYWORD( timeStamp,         "Time",         boost::posix_time::ptime)

core->add_global_attribute( dateTimeStamp.get_name(),   attrs::local_date_time_ms_clock());
core->add_global_attribute( timeStamp.get_name(),       attrs::local_time_ms_clock());

并用作

expr::stream << expr::attr<std::string>( dateTimeStamp.get_name())
expr::stream << expr::attr<std::string>( timeStamp.get_name())

I'm using this

namespace boost
{
    BOOST_LOG_OPEN_NAMESPACE

    namespace attributes
    {
        template <typename date_time_type>
        void format_time_ms( std::ostringstream& formatter, const date_time_type& date_time)
        {
            auto time = date_time.time_of_day();
            using namespace std;
            formatter
                << setfill( '0') << setw( 2) << time.hours()   << ':'
                << setfill( '0') << setw( 2) << time.minutes() << ':'
                << setfill( '0') << setw( 2) << time.seconds() << ','
                << setfill( '0') << setw( 3) << time.fractional_seconds() / 1000;
        }

        template <typename date_time_type>
        std::string format_time_ms( const date_time_type& date_time)
        {
            std::ostringstream formatter;
            format_time_ms( formatter, date_time);
            auto time = date_time.time_of_day();
            return formatter.str();
        }

        template <typename date_time_type>
        std::string format_date_time_ms( const date_time_type& date_time, const char date_time_sep = ' ')
        {
            using namespace std;
            ostringstream formatter;
            auto date = date_time.date();
            formatter
                << date.year() << '-'
                << setfill( '0') << setw( 2) << int( date.month()) << '-'
                << setfill( '0') << setw( 2) << date.day() << date_time_sep;
            format_time_ms( formatter, date_time);
            return formatter.str();
        }

        template <typename date_time_type, const char date_time_sep = ' '>
        struct date_time_ms_formatter
        {           
            std::string operator () ( const date_time_type& date_time) { return format_date_time_ms( date_time, date_time_sep); }
        };

        struct time_ms_formatter
        {
            template <typename date_time_type>
            std::string operator () ( const date_time_type& date_time) { return format_time_ms( date_time); }
        };

        template <typename time_type>
        struct local_clock_source
        {
            time_type operator () () const
            {
                return date_time::microsec_clock<time_type>::local_time();
            }
        };

        template <typename time_type>
        struct universal_clock_source
        {
            time_type operator () () const
            {
                return date_time::microsec_clock<time_type>::universal_time();
            }
        };

        template <typename time_type, typename clock_source_type, typename formater_type>
        class custom_clock: public attribute
        {
        public:
            class impl: public attribute::impl
            {
            public:
                attribute_value get_value()
                {
                    auto str = formater_type()( clock_source_type()());
                    return make_attribute_value( str);
                }
            };

            custom_clock(): attribute( new impl()) {}

            explicit custom_clock( const cast_source& source): attribute( source.as<impl>()) {}
        };


        typedef custom_clock<boost::posix_time::ptime, local_clock_source<boost::posix_time::ptime>, date_time_ms_formatter<boost::posix_time::ptime, '\t'> >       local_date_time_ms_clock;
        typedef custom_clock<boost::posix_time::ptime, universal_clock_source<boost::posix_time::ptime>, date_time_ms_formatter<boost::posix_time::ptime, '\t'> >   universal_date_time_ms_clock;

        typedef custom_clock<boost::posix_time::ptime, local_clock_source<boost::posix_time::ptime>, time_ms_formatter>     local_time_ms_clock;
        typedef custom_clock<boost::posix_time::ptime, universal_clock_source<boost::posix_time::ptime>, time_ms_formatter> universal_time_ms_clock;
    }

    BOOST_LOG_CLOSE_NAMESPACE // namespace log
}

initialized as

BOOST_LOG_ATTRIBUTE_KEYWORD( dateTimeStamp,     "DateTime",     boost::posix_time::ptime)
BOOST_LOG_ATTRIBUTE_KEYWORD( timeStamp,         "Time",         boost::posix_time::ptime)

core->add_global_attribute( dateTimeStamp.get_name(),   attrs::local_date_time_ms_clock());
core->add_global_attribute( timeStamp.get_name(),       attrs::local_time_ms_clock());

and used as

expr::stream << expr::attr<std::string>( dateTimeStamp.get_name())
expr::stream << expr::attr<std::string>( timeStamp.get_name())
冷月断魂刀 2024-11-13 06:59:54

Boost.DateTime(Boost.Log 所依赖的)似乎不支持专门的小数秒格式,因此唯一的方法是编写自己的自定义属性格式化程序,或者(更简单但不太好的方法)稍微修改您的格式化代码。

而不是这样的事情:

backend->set_formatter
(
    fmt::stream <<
      fmt::date_time<boost::posix_time::ptime>
        ("TimeStamp", keywords::format = "%Y-%m-%d %H:%M:%S.%f"));

backend->set_formatter
(
    fmt::stream <<
    fmt::date_time<boost::posix_time::ptime>
        ("TimeStamp", keywords::format = %Y-%m-%d %H:%M:%S.") <<
    (fmt::format("%.2s") % fmt::date_time<boost::posix_time::ptime>("%f"))
);

我自己没有测试过它,但我相信它应该可以工作:第一个 fmt::date_time() 将返回不带小数秒的时间戳,而第二个 >fmt::date_time() 将仅返回秒的小数部分,该值将被 fmt::format() 削减为两位数。

Boost.DateTime (upon which Boost.Log relies) doesn't seem to support specialized fractional seconds formatting, so the only way to do that would be to write your own custom attribute formatter, or (the easier, but less nice way) to slightly modify your formatting code.

Instead of something like this:

backend->set_formatter
(
    fmt::stream <<
      fmt::date_time<boost::posix_time::ptime>
        ("TimeStamp", keywords::format = "%Y-%m-%d %H:%M:%S.%f"));

backend->set_formatter
(
    fmt::stream <<
    fmt::date_time<boost::posix_time::ptime>
        ("TimeStamp", keywords::format = %Y-%m-%d %H:%M:%S.") <<
    (fmt::format("%.2s") % fmt::date_time<boost::posix_time::ptime>("%f"))
);

I haven't tested it myself, but I believe it should work: the first fmt::date_time() will return the timestamp without the fractional seconds, while the second fmt::date_time() will return just the fractional seconds, which will be cut to two digits by the fmt::format().

执手闯天涯 2024-11-13 06:59:54

试试这个。它在 Linux 下对我有用。

sink->set_formatter(log_expr::format("%1%") % log_expr::max_size_decor<char>(22)[log_expr::stream << log_expr::format_date_time<boost::posix_time::ptime>("Timestamp", "%Y-%m-%d %H:%M:%S.%f")]);

Try this one. It works for me under Linux.

sink->set_formatter(log_expr::format("%1%") % log_expr::max_size_decor<char>(22)[log_expr::stream << log_expr::format_date_time<boost::posix_time::ptime>("Timestamp", "%Y-%m-%d %H:%M:%S.%f")]);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文