c++11 boost - date_time库 - 时间

2018-07-10 16:16:37

date_time 库可以提供微妙甚至纳秒级别的精度。

#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::posix_time;

date_duration 为时间长度类,默认为微妙级别,除非手动开启纳秒

#define BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG

ptime 为时间点类,表示某个特定时间。

time_period 为时间区间,用法跟 date_period 基本相同。

不同于日期迭代器,时间迭代器只有一个 time_iterator。

例子-1

// Copyright (c) 2015
// Author: Chrono Law
#include <iostream>
using namespace std;

//#define BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace boost::gregorian;
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::posix_time;

void case1()
{
    {
        time_duration td = duration_from_string("1:10:30:001");
        cout << td << endl;

        time_duration td1(1,10,30,1000);
        //2小时01分06.001秒
        time_duration td2(1,60,60,1000*1000* 6 + 1000);
    }

    hours h(1);     //1小时
    minutes m(10);  //10分钟
    seconds s(30);  //30秒
    millisec ms(1); //1毫秒

    time_duration td = h + m + s + ms;
    time_duration td2 = hours(2) + seconds(10);

    cout << td << td2 << endl;
}

//////////////////////////////////////////
void case2()
{
    time_duration td(1,10,30,1000);
    assert(td.hours() == 1 && td.minutes() == 10 && td.seconds() == 30);
    assert(td.total_seconds() == 1*3600+ 10*60 + 30);
    assert(td.total_milliseconds() == td.total_seconds()*1000 + 1);
    assert(td.fractional_seconds() == 1000);

    hours h(-10);
    assert(h.is_negative());

    time_duration h2 = h.invert_sign();
    assert(!h2.is_negative() && h2.hours() == 10);

    time_duration td1(not_a_date_time);
    assert(td1.is_special() && td1.is_not_a_date_time());

    time_duration td2(neg_infin);
    assert(td2.is_negative() && td2.is_neg_infinity());

}

//////////////////////////////////////////
void case3()
{
    time_duration td1 = hours(1);
    time_duration td2 = hours(2) + minutes(30);
    assert(td1 < td2);
    assert((td1+td2).hours() == 3);
    assert((td1-td2).is_negative());
    assert(td1 * 5 == td2 * 2);
    assert((td1/2).minutes() == td2.minutes());

    time_duration td(1,10,30,1000);
    cout << to_simple_string(td) << endl;
    cout << to_iso_string(td) << endl;

}

//////////////////////////////////////////
void case4()
{
//如果开启纳秒
#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
    time_duration td(1,10,30,1000);
    cout << td;
    assert(td.total_milliseconds() ==
            td.total_seconds()*1000);

    assert(td.fractional_seconds() ==1000);

    //此时单位是纳秒
    assert(time_duration::unit()*1000*1000*1000 == seconds(1));

    assert(td.resolution() == boost::date_time::nano);
    assert(td.num_fractional_digits() == 9); //纳秒为9位


#endif
}

//////////////////////////////////////////
void case5()
{    
    //该日期凌晨1点
    ptime p(date(2017,7,7), hours(1));
    ptime p1 = time_from_string("2017-7-7 01:00:00");
    ptime p2 = from_iso_string("20170707T010000");

    cout << p1 << endl << p2;
    {
        //秒精度当前时间
        ptime p1 = second_clock::local_time();
        ptime p2 = microsec_clock::universal_time(); //微妙精度
        cout << p1 << endl << p2;

    }
}

//////////////////////////////////////////
void case6()
{
    ptime p(date(2010,3,20), hours(12)+minutes(30));

    date d = p.date();
    time_duration td = p.time_of_day();
    assert(d.month() == 3 && d.day() == 20);
    assert(td.total_seconds() == 12*3600 + 30*60);

    ptime p1(date(2010,3,20), hours(12)+minutes(30));
    ptime p2 = p1 + hours(3);

    assert(p1 < p2);
    assert(p2 - p1 == hours(3));
    p2 += months(1);
    assert(p2.date().month() == 4);

    cout << endl;
    {
        ptime p(date(2017,2,14), hours(20));
        cout << to_simple_string(p) << endl;
        cout << to_iso_string(p) << endl;
        cout << to_iso_extended_string(p) << endl;
    }
}

//跟struct tm相互转换
void case7()
{
    ptime p(date(2017,5,20), hours(14));
    tm t = to_tm(p);
    assert(t.tm_year == 117 && t.tm_hour == 14);
    assert(ptime_from_tm(t) == p);

    ptime p2 = from_time_t(std::time(0));
    assert(p2.date() == day_clock::local_day());
    cout << to_time_t(p2) << endl;
}

//////////////////////////////////////////
void case8()
{
    ptime p(date(2017,1,1),hours(12)) ;
    time_period tp1(p, hours(8));
    time_period tp2(p + hours(8), hours(1));
    assert(tp1.end() == tp2.begin() && tp1.is_adjacent(tp2));
    assert(!tp1.intersects(tp2));

    tp1.shift(hours(1));
    assert(tp1.is_after(p));
    assert(tp1.intersects(tp2));

    tp2.expand(hours(10));
    assert(tp2.contains(p) && tp2.contains(tp1));
}

//////////////////////////////////////////
void case9()
{
    ptime p(date(2017,5,31),hours(10)) ;
    for (time_iterator t_iter(p, minutes(10));
            t_iter < p + hours(1); ++ t_iter)
    {
            cout << *t_iter << endl;
    }

}

//////////////////////////////////////////
template<typename Clock = microsec_clock>
class basic_ptimer
{
    public:
        basic_ptimer()
        {   restart();}
        void restart()
        {   _start_time = Clock::local_time();  }
        void elapsed() const
        {   cout << Clock::local_time() - _start_time;  }
        ~basic_ptimer()
        {   elapsed();  }
    private:
        ptime _start_time;
};
typedef basic_ptimer<microsec_clock> ptimer;
typedef basic_ptimer<second_clock>   sptimer;

class work_time
{
public:
    typedef map<time_period, string> map_t;
private:
    map_t map_ts;
    void init()
    {
        ptime p(day_clock::local_day());

        map_ts[time_period(p, hours(9))] = "It's too early, just relax.\n";
        p += hours(9);
        map_ts[time_period(p, hours(3)+ minutes(30))] = "It's AM, please work hard.\n";
        p += hours(3)+ minutes(30);
        map_ts[time_period(p, hours(1))] = "It's lunch time, are you hungry?\n";
        p += hours(1);
        map_ts[time_period(p, hours(4)+minutes(30))] = "It's PM, ready to go home.\n";
        p += hours(4)+ minutes(30);
        map_ts[time_period(p, hours(6))] = "Are you still working? you do need a rest.\n";
    }
public:
    work_time()
    {   init(); }

    void greeting(const ptime& t)
    {
        for (auto& x : map_ts)
        {
            if (x.first.contains(t))
            {
                cout << x.second << endl;
                break;
            }
        }
    }
};

void case10()
{
    ptimer t;

    work_time wt;
    wt.greeting(second_clock::local_time());
}


//////////////////////////////////////////

int main()
{
    case1();
    case2();
    case3();
    case4();
    case5();
    case6();
    case7();
    case8();
    case9();
    case10();
}
[root@192 c++]# g++ -std=c++11 -lboost_date_time -L /usr/local/lib/boost_1_65_1/ main.cpp 
[root@192 c++]# ./a.out 
01:10:30.001000
01:10:30.00100002:00:10
01:10:30.001000
011030.001000
2017-Jul-07 01:00:00
2017-Jul-07 01:00:002018-Jul-10 15:39:21
2018-Jul-10 07:39:21.849165
2017-Feb-14 20:00:00
20170214T200000
2017-02-14T20:00:00
1531208361
2017-May-31 10:00:00
2017-May-31 10:10:00
2017-May-31 10:20:00
2017-May-31 10:30:00
2017-May-31 10:40:00
2017-May-31 10:50:00
It's PM, ready to go home.

例子-2

// Copyright (c) 2015
// Author: Chrono Law
#include <iostream>
using namespace std;

//#define BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace boost::gregorian;
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::posix_time;

//格式化时间
void case1()
{
    date d(2014,11,3);
    date_facet* dfacet = new date_facet("%Y年%m月%d日");
    cout.imbue(locale(cout.getloc(), dfacet));
    cout << d << endl;

    time_facet *tfacet = new time_facet("%Y年%m月%d日%H点%M分%S%F秒");
    cout.imbue(locale(cout.getloc(), tfacet));
    cout << ptime(d , hours(21) + minutes(50) + millisec(100)) << endl;

}

//c++11新增了自定义字面值
days operator"" _D(unsigned long long n)
{
    return days(n);
}

weeks operator"" _W(unsigned long long n)
{
    return weeks(n);
}

date operator"" _YMD(const char*  s, std::size_t )
{
    return from_string(s);
}

void case2()
{
    auto d = 100_D;  //等同于days(100);
    auto w = 1_W;

    assert(d.days() == 100);
    assert(w.days() == (7_D).days());

    auto today = "2014/11/3"_YMD;
    cout  << today << endl;
}

//////////////////////////////////////////
#include <boost/date_time/local_time/local_time.hpp>
using namespace boost::local_time;

//首先从boost源码目录复制过来时区数据库csv
//cp /root/boost_1_67_0/libs/date_time/data/date_time_zonespec.csv ./
void case3()
{
    tz_database tz_db;
    tz_db.load_from_file("./date_time_zonespec.csv");
    
    //获取上海时区
    time_zone_ptr shz =  tz_db.time_zone_from_region("Asia/Shanghai");

    //旧金山洛杉矶时区
    time_zone_ptr sfz =  tz_db.time_zone_from_region("America/Los_Angeles");

    cout << shz->has_dst() << endl;    //夏令时
    cout << shz->std_zone_name() << endl;  //时区名

    local_date_time dt_bj(date(2014,3,6),
            hours(16),
            shz,
            false);
    cout << dt_bj << endl;

    time_duration flight_time = hours(12);   //飞行12小时
    dt_bj += flight_time;                    //北京当地时间
    cout << dt_bj << endl;
    local_date_time dt_sf = dt_bj.local_time_in(sfz);  //旧金山当地时间
    cout << dt_sf;
}


//////////////////////////////////////////

int main()
{
    case1();
    case2();
    case3();
}


 备注

1.编译器版本gcc4.8.5,运行环境centos7 64位
2.本文只做简单记录用,详细用法请参考 Boost Library,或者是罗剑锋的 boost程序库完全开发指南 书本
3..原文地址http://www.freecls.com/a/2712/9c


©著作权归作者所有
收藏
推荐阅读
简介
天降大任于斯人也,必先苦其心志。