boost初探-日期与时间

2023-05-16

文章目录

    • 一、前言
    • 二、boost基本概念
    • 三、日期与时间
      • 1.timer
      • 2.progress_timer
      • 3.data_time库
        • 3.1gregorian
        • 3.2date_period
      • 4.posix_time

一、前言

之前写了两篇关于在linux上安装boost和在Windows上使用boost的文章

  • 在Ubuntu上安装Boost的五种方法(全网最全,建议收藏)
  • boost库在visual studio、DevC++和vscode上的环境配置

下面就该开始使用boost了,boost包含的内容特别多,初学时我们肯定摸不着头脑,不知道从哪里开始学习比较好。

从我个人的看法,刚开始学习boost可以先找几个简单的模块用用,等熟悉了boost的一些基本概念和使用方法,后面就可以针对性的学习自己要用的模块。

二、boost基本概念

boost在安转完之后的目录结构如下图所示:

https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210815111850422.png
boost的模块都是以.hpp文件形式存在,即在一个文件中包括了函数变量的声明和定义,因此大部分boost模块我们可以直接包含使用,对于少部分模块我们需要编译成库文件使用。编译好的库文件存放在目录stage/lib里面

在这里插入图片描述

其余的.hpp文件都在boost目录下

image-20210815112235560

因此我们要使用boost,最重要的就是boost目录和stage/lib目录,分别存放在 .hpp文件和 .lib文件。

在linux上使用即把boost目录加入到头文件查找目录,把stage/lib加入到库文件查找目录。

在Windows下,即在IDE软件中加入boost头文件查找目录,加入stage/lib到库文件查找目录,这个在之前的博客中已经讲了怎么操作,不知道的可以看看上面的博客。

三、日期与时间

1.timer

timer可以测量时间的流逝,是一个小型的计时器,可提供毫秒级别的计时精度和操作函数,供程序员手工控制使用,它就像个秒表。

直接看源代码,再来讲解

//  boost timer.hpp header file  ---------------------------------------------//

//  Copyright Beman Dawes 1994-99.  Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/timer for documentation.

//  Revision History
//  01 Apr 01  Modified to use new <boost/limits.hpp> header. (JMaddock)
//  12 Jan 01  Change to inline implementation to allow use without library
//             builds. See docs for more rationale. (Beman Dawes) 
//  25 Sep 99  elapsed_max() and elapsed_min() added (John Maddock)
//  16 Jul 99  Second beta
//   6 Jul 99  Initial boost version

#ifndef BOOST_TIMER_HPP
#define BOOST_TIMER_HPP

#include <boost/config/header_deprecated.hpp>
BOOST_HEADER_DEPRECATED( "the facilities in <boost/timer/timer.hpp>" )

#include <boost/config.hpp>
#include <ctime>
#include <boost/limits.hpp>

# ifdef BOOST_NO_STDC_NAMESPACE
    namespace std { using ::clock_t; using ::clock; }
# endif


namespace boost {

//  timer  -------------------------------------------------------------------//

//  A timer object measures elapsed time.

//  It is recommended that implementations measure wall clock rather than CPU
//  time since the intended use is performance measurement on systems where
//  total elapsed time is more important than just process or CPU time.

//  Warnings: The maximum measurable elapsed time may well be only 596.5+ hours
//  due to implementation limitations.  The accuracy of timings depends on the
//  accuracy of timing information provided by the underlying platform, and
//  this varies a great deal from platform to platform.

class timer
{
 public:
         timer() { _start_time = std::clock(); } // postcondition: elapsed()==0
//         timer( const timer& src );      // post: elapsed()==src.elapsed()
//        ~timer(){}
//  timer& operator=( const timer& src );  // post: elapsed()==src.elapsed()
  void   restart() { _start_time = std::clock(); } // post: elapsed()==0
  double elapsed() const                  // return elapsed time in seconds
    { return  double(std::clock() - _start_time) / CLOCKS_PER_SEC; }

  double elapsed_max() const   // return estimated maximum value for elapsed()
  // Portability warning: elapsed_max() may return too high a value on systems
  // where std::clock_t overflows or resets at surprising values.
  {
    return (double((std::numeric_limits<std::clock_t>::max)())
       - double(_start_time)) / double(CLOCKS_PER_SEC); 
  }

  double elapsed_min() const            // return minimum value for elapsed()
   { return double(1)/double(CLOCKS_PER_SEC); }

 private:
  std::clock_t _start_time;
}; // timer

} // namespace boost

#endif  // BOOST_TIMER_HPP

  • timer模块需要依赖下面三个文件
#include <boost/config.hpp>
#include <ctime>
#include <boost/limits.hpp>
  • timer模块存在于命名空间namespace boost
  • timer模块的主类为timer,包含1个构造函数,4个成员函数,1个成员变量

可以看出timer模块是非常简单的,当然我们刚开始学习一些简单的模块可以帮助我们建立一些使用boost的基础,让我们更快的上手,不失为一个好的选择。

下面我们用一点代码来简单使用一下timer模块

#include <iostream>
using namespace std;

#include <boost/timer.hpp>
using namespace boost;

int main()
{
    timer t;   //定义一个timer对象,通过该对象进行时间的相应操作

    cout << CLOCKS_PER_SEC << endl;
    cout << "max timespan:"
        << t.elapsed_max() /3600 << "h" <<endl;
    cout << "min timespan:"
        << t.elapsed_min() << "s" << endl;
    cout << "now time elapsed:"
        << t.elapsed() <<"s" << endl;
}

2.progress_timer

progress_timer也是一个计时器,它派生自timer,会在析构时自动输出时间,省去了timer手动调用elapsed()的工作,是一个相当方便的自动计时的小工具。

progress_timer位于命名空间boost,需要包含的头文件如下

#include <boost/progress.hpp>
using namespace boost;

先看progress_timer的源码

//  boost progress.hpp header file  ------------------------------------------//

//  Copyright Beman Dawes 1994-99.  Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/timer for documentation.

//  Revision History
//   1 Dec 01  Add leading progress display strings (suggested by Toon Knapen)
//  20 May 01  Introduce several static_casts<> to eliminate warning messages
//             (Fixed by Beman, reported by Herve Bronnimann)
//  12 Jan 01  Change to inline implementation to allow use without library
//             builds. See docs for more rationale. (Beman Dawes) 
//  22 Jul 99  Name changed to .hpp
//  16 Jul 99  Second beta
//   6 Jul 99  Initial boost version

#ifndef BOOST_PROGRESS_HPP
#define BOOST_PROGRESS_HPP

#include <boost/config/header_deprecated.hpp>
BOOST_HEADER_DEPRECATED( "the facilities in <boost/timer/timer.hpp> or <boost/timer/progress_display.hpp>" )

#include <boost/timer.hpp>
#include <boost/noncopyable.hpp>
#include <boost/cstdint.hpp>  // for uintmax_t
#include <iostream>           // for ostream, cout, etc
#include <string>             // for string

namespace boost {

//  progress_timer  ----------------------------------------------------------//

//  A progress_timer behaves like a timer except that the destructor displays
//  an elapsed time message at an appropriate place in an appropriate form.

class progress_timer : public timer, private noncopyable
{
 public:
  explicit progress_timer( std::ostream & os = std::cout )
     // os is hint; implementation may ignore, particularly in embedded systems
     : timer(), noncopyable(), m_os(os) {}
  ~progress_timer()
  {
  //  A) Throwing an exception from a destructor is a Bad Thing.
  //  B) The progress_timer destructor does output which may throw.
  //  C) A progress_timer is usually not critical to the application.
  //  Therefore, wrap the I/O in a try block, catch and ignore all exceptions.
    try
    {
      // use istream instead of ios_base to workaround GNU problem (Greg Chicares)
      std::istream::fmtflags old_flags = m_os.setf( std::istream::fixed,
                                                   std::istream::floatfield );
      std::streamsize old_prec = m_os.precision( 2 );
      m_os << elapsed() << " s\n" // "s" is System International d'Unites std
                        << std::endl;
      m_os.flags( old_flags );
      m_os.precision( old_prec );
    }

    catch (...) {} // eat any exceptions
  } // ~progress_timer

 private:
  std::ostream & m_os;
};


//  progress_display  --------------------------------------------------------//

//  progress_display displays an appropriate indication of 
//  progress at an appropriate place in an appropriate form.

// NOTE: (Jan 12, 2001) Tried to change unsigned long to boost::uintmax_t, but
// found some compilers couldn't handle the required conversion to double.
// Reverted to unsigned long until the compilers catch up. 

class progress_display : private noncopyable
{
 public:
  explicit progress_display( unsigned long expected_count_,
                             std::ostream & os = std::cout,
                             const std::string & s1 = "\n", //leading strings
                             const std::string & s2 = "",
                             const std::string & s3 = "" )
   // os is hint; implementation may ignore, particularly in embedded systems
   : noncopyable(), m_os(os), m_s1(s1), m_s2(s2), m_s3(s3) { restart(expected_count_); }

  void           restart( unsigned long expected_count_ )
  //  Effects: display appropriate scale
  //  Postconditions: count()==0, expected_count()==expected_count_
  {
    _count = _next_tic_count = _tic = 0;
    _expected_count = expected_count_;

    m_os << m_s1 << "0%   10   20   30   40   50   60   70   80   90   100%\n"
         << m_s2 << "|----|----|----|----|----|----|----|----|----|----|"
         << std::endl  // endl implies flush, which ensures display
         << m_s3;
    if ( !_expected_count ) _expected_count = 1;  // prevent divide by zero
  } // restart

  unsigned long  operator+=( unsigned long increment )
  //  Effects: Display appropriate progress tic if needed.
  //  Postconditions: count()== original count() + increment
  //  Returns: count().
  {
    if ( (_count += increment) >= _next_tic_count ) { display_tic(); }
    return _count;
  }

  unsigned long  operator++()           { return operator+=( 1 ); }
  unsigned long  count() const          { return _count; }
  unsigned long  expected_count() const { return _expected_count; }

  private:
  std::ostream &     m_os;  // may not be present in all imps
  const std::string  m_s1;  // string is more general, safer than 
  const std::string  m_s2;  //  const char *, and efficiency or size are
  const std::string  m_s3;  //  not issues

  unsigned long _count, _expected_count, _next_tic_count;
  unsigned int  _tic;
  void display_tic()
  {
    // use of floating point ensures that both large and small counts
    // work correctly.  static_cast<>() is also used several places
    // to suppress spurious compiler warnings. 
    unsigned int tics_needed = static_cast<unsigned int>((static_cast<double>(_count)
        / static_cast<double>(_expected_count)) * 50.0);
    do { m_os << '*' << std::flush; } while ( ++_tic < tics_needed );
    _next_tic_count = 
      static_cast<unsigned long>((_tic/50.0) * static_cast<double>(_expected_count));
    if ( _count == _expected_count ) {
      if ( _tic < 51 ) m_os << '*';
      m_os << std::endl;
      }
  } // display_tic
};

} // namespace boost

#endif  // BOOST_PROGRESS_HPP

3.data_time库

data_time库需要编译才能使用,data_time库包括两个部分,处理日期的gregorian,处理时间的posix_time,它们各自需要包含的头文件如下:

//处理日期的组件
#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

3.1gregorian

用下面一段代码来测试一下这个模块

#include <iostream>
using namespace std;

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

//

void case1()
{
    date d1;
    date d2(2010,1,1);
    date d3(2000, Jan , 1);
    date d4(d2);

    assert(d1 == date(not_a_date_time));
    assert(d2 == d4);
    assert(d3 <  d4);
}

//

void case2()
{
    date d1 = from_string("1999-12-31");
    date d2 ( from_string("2015/1/1") );
    date d3 = from_undelimited_string("20011118") ;

    cout << d1 << d2 << d3 << endl;

    cout << day_clock::local_day()    << endl;
    cout << day_clock::universal_day() << endl;

}

//
void case3()
{
    date d1(neg_infin);
    date d2(pos_infin);
    date d3(not_a_date_time);
    date d4(max_date_time);
    date d5(min_date_time);

    cout << d1 << d2 << d3 << d4 << d5 << endl;

    try
    {
        //date d1(1399,12,1);
        //date d2(10000,1,1);
        date d3(2017,2,29);
    }
    catch(std::exception& e)
    {
        cout << e.what() << endl;
    }
}

//
void case4()
{
    date d(2017,6,1);
    assert(d.year()  == 2017);
    assert(d.month() == 6);
    assert(d.day()   == 1);

    date::ymd_type ymd =  d.year_month_day();
    assert(ymd.year    == 2017);
    assert(ymd.month   == 6);
    assert(ymd.day     == 1);

    cout << d.day_of_week() << endl;
    cout << d.day_of_year() << endl;
    assert(d.end_of_month() == date(2017,6,30));

    cout << date(2015,1,10).week_number() << endl;
    cout << date(2016,1,10).week_number()  << endl;
    cout << date(2017,1,10).week_number()  << endl;

    assert(date(pos_infin).is_infinity()  );
    assert(date(pos_infin).is_pos_infinity() );
    assert(date(neg_infin).is_neg_infinity() );
    assert(date(not_a_date_time).is_not_a_date() );
    assert(date(not_a_date_time).is_special() );
    assert(!date(2017,5,31).is_special() );


}

//
void case5()
{
    date d(2017,1,23);

    cout << to_simple_string(d) << endl;
    cout << to_iso_string(d) << endl;
    cout << to_iso_extended_string(d) << endl;
    cout << d << endl;

    //cout << "input date:";
    //cin >>d;
    //cout << d;

}

//
void case6()
{
    date d(2017,5,20);
    tm t = to_tm(d);
    assert(t.tm_hour == 0 && t.tm_min == 0);
    assert(t.tm_year == 117 && t.tm_mday == 20);

    date d2 = date_from_tm(t);
    assert(d == d2);

}

//
void case7()
{
    days dd1(10), dd2(-100), dd3(255);

    assert( dd1 > dd2 && dd1 < dd3);
    assert( dd1 + dd2 == days(-90));
    assert((dd1 + dd3).days() == 265);
    assert( dd3 / 5 == days(51));

    weeks w(3);
    assert(w.days() == 21);

    months m(5);
    years y(2);

    months m2 = y + m;
    assert(m2.number_of_months() == 29);
    assert((y * 2).number_of_years() == 4);

}

//
void case8()
{
    date d1(2000,1,1),d2(2017,11,18);
    cout << d2 - d1 << endl;
    assert(d1 + (d2 - d1) == d2);

    d1 += days(10);
    assert(d1.day() == 11);
    d1 += months(2);
    assert(d1.month() == 3 && d1.day() == 11);
    d1 -= weeks(1);
    assert(d1.day() == 4);

    d2 -= years(10);
    assert(d2.year() == d1.year() + 7);

    {
        date d1(2017,1,1);

        date d2 = d1 + days(pos_infin);
        assert(d2.is_pos_infinity());

        d2 = d1 + days(not_a_date_time);
        assert(d2.is_not_a_date());
        d2 = date(neg_infin);
        days dd = d1 - d2;
        assert(dd.is_special() && !dd.is_negative());
    }

    {
        date d(2017,3,30);
        d -= months(1);
        d -= months(1);
        d += months(2);
        assert(d.day() == 31);
    }
}

//
void case9()
{
    date_period dp1(date(2017,1,1), days(20));
    date_period dp2(date(2017,1,1), date(2016,1,1));
    date_period dp3(date(2017,3,1), days(-20));

    date_period dp(date(2017,1,1), days(20));

    assert(!dp.is_null());
    assert(dp.begin().day() == 1);
    assert(dp.last().day() == 20);
    assert(dp.end().day() == 21);
    assert(dp.length().days() == 20);

    {
        date_period dp1(date(2017,1,1), days(20));
        date_period dp2(date(2017,2,19), days(10));

        cout << dp1;                        //[2010-Jan-01/2010-Jan-20]
        assert(dp1 < dp2);
    }
}

//

int main()
{
    case1();
    case2();
    case3();
    case4();
    case5();
    case6();
    case7();
    case8();
    case9();
}

3.2date_period

data_time库使用date_period来表示日期区间的概念,它是时间轴上的一个左闭右开的区间,其端点是两个date对象。日期区间的左边界必须小于右边界,否则date_period将表示一个无效的日期区间。

date_period的类摘要如下:

class date_period 
{
public:
    period(date, date);
    period(date, days);
    
    date begin() const;
    date end() const;
    date last() const;
    days length() const;
    bool is_null() const;
    
    bool operator==(const period &) const;
    bool operator<(const period &) const;
    
    void shift(const days &);
    void expand(const days &);
    
    bool contains(const date &) const;
    bool contains(const period &) const;
    bool intersects(const period &) const;
    bool is_adjacent(const period &) const;
    bool is_before(const date &) const;
    bool is_after(const date  &) const;
    period intersection(const date &) const;
    period merge(const period &) const;
    period span(const period &) const;
    
};

用一段代码来测试一下

#include <iostream>
using namespace std;

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

//
void case1()
{
    date_period dp(date(2017,1,1), days(20));

    dp.shift(days(3));
    assert(dp.begin().day() == 4);
    assert(dp.length().days() == 20);

    dp.expand(days(3));
    assert(dp.begin().day() == 1);
    assert(dp.length().days() == 26);

}

//

void case2()
{
    date_period dp(date(2010,1,1), days(20));

    assert(dp.is_after(date(2009,12,1)));
    assert(dp.is_before(date(2010,2,1)));
    assert(dp.contains(date(2010,1,10)));

    date_period dp2(date(2010,1,5), days(10));
    assert(dp.contains(dp2));

    assert(dp.intersects(dp2));
    assert(dp.intersection(dp2) == dp2);

    date_period dp3(date(2010,1,21), days(5));
    assert(!dp3.intersects(dp2));
    assert(dp3.intersection(dp2).is_null());

    assert(dp.is_adjacent(dp3));
    assert(!dp.intersects(dp3));

}

//
void case3()
{
    date_period dp1(date(2010,1,1), days(20));
    date_period dp2(date(2010,1,5), days(10));
    date_period dp3(date(2010,2,1), days(5));
    date_period dp4(date(2010,1,15), days(10));

    assert( dp1.contains(dp2) && dp1.merge(dp2) == dp1);
    assert(!dp1.intersects(dp3) && dp1.merge(dp3).is_null());
    assert( dp1.intersects(dp2) && dp1.merge(dp4).end() == dp4.end());
    assert( dp1.span(dp3).end() == dp3.end());
}

//
void case4()
{
    date d(2007,9,28);
    day_iterator d_iter(d);

    assert(d_iter == d);
    ++d_iter;
    assert(d_iter == date(2007,9,29));

    year_iterator y_iter(*d_iter, 10);
    assert(y_iter == d + days(1));
    ++y_iter;
    assert(y_iter->year() == 2017);

    day_iterator iter(day_clock::local_day());
    ++iter;

    //iter += 5;
    //std::advance(iter, 5);
}

//
void case5()
{
    typedef gregorian_calendar gre_cal;
    cout << "Y2017 is "
        << (gre_cal::is_leap_year(2017)?"":"not")
        << " a leap year." << endl;
    assert(gre_cal::end_of_month_day(2017, 2) == 28);
}

//
void case6()
{
    date d(2017,1,23);

    date d_start(d.year(), d.month(), 1);
    date d_end = d.end_of_month();

    for(day_iterator d_iter(d_start);
        d_iter <= d_end; ++d_iter)
    {
            cout << *d_iter << " " <<
                    d_iter->day_of_week()<< endl;
    }

}

//
void case7()
{
    date d(2017,1,23);

    date d18years = d + years(18);
    cout << d18years << " is "
        << d18years.day_of_week()<< endl;

    int count = 0;
    for (day_iterator d_iter(date(d18years.year(),1,1));
            d_iter <= d18years.end_of_month(); ++d_iter)
    {
        if (d_iter->day_of_week() == Sunday)
        {
            ++count;
        }
    }
    cout << "total " << count << " Sundays." << endl;

    count = 0;
    for (month_iterator m_iter(date(d18years.year(),1,1));
            m_iter < date(d18years.year() + 1 ,1, 1); ++m_iter)
    {
        count += m_iter->end_of_month().day();
    }
    cout << "total " << count << " days of year." << endl;

}

//
class credit_card
{
public:
    string bank_name;
    int bill_day_no;

    credit_card(const char* bname, int no):
        bank_name(bname), bill_day_no(no){}

    int calc_free_days(date consume_day = day_clock::local_day()) const
    {
        date bill_day(consume_day.year(), consume_day.month(), bill_day_no);
        if (consume_day > bill_day)
        {
            bill_day += months(1);
        }

        return (bill_day - consume_day).days() + 20;
    }

    friend bool operator<(const credit_card& l, const credit_card& r)
    {

        return l.calc_free_days() < r.calc_free_days();
    }
};

void case8()
{
    credit_card a("A bank", 25);
    credit_card b("B bank", 12);

    credit_card tmp = std::max(a, b);
    cout << "You should use " << tmp.bank_name 
        << ", free days = " << tmp.calc_free_days() << endl;
}

int main()
{
    case1();
    case2();
    case3();
    case4();
    case5();
    case6();
    case7();
    case8();
}

4.posix_time

date_time库的时间功能位于命名空间boost::posix_time,需要包含的头文件如下

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

从概念上来说,时间是日期的进一步细化,相当于在日期”天“的量级之下增加了”时分秒“的概念

直接上测试代码

#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);
        time_duration td2(1,60,60,1000*1000* 6 + 1000);
    }

    hours h(1);
    minutes m(10);
    seconds s(30);
    millisec ms(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);

#ifndef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
    assert(td.total_milliseconds() == td.total_seconds()*1000 + 1);
    assert(td.fractional_seconds() == 1000);
#endif

    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);


#endif
}

//
void case5()
{
    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;
    }
}

//
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();
}

运行结果如下:

image-20210815155558867

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

boost初探-日期与时间 的相关文章

随机推荐