Monday, December 21, 2015

Boost学习(1): 时间和日期


开篇算是一个小巧玲珑的boost::timer, design类似QTimer,但其实不是很好用,因为里面用的是busy spin, sleep的时候measure会有问题。 而且精度靠的POSIX的平台依赖的精度,所以不觉得有多好用。。。

两个API:
void restart() : 计时开始
double elpased(): 经过时间

还有其他的, 比如progresss_timer, display_timer之类的,也不算是有用。 有一个用的比较多,data_timer库,这个在新工作里面看见他们用来转换database时间,和写log用。但是看了下,反倒好长。。。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <boost/timer.hpp>
#include <iostream>
#include <boost/thread.hpp>
using namespace std;

/*
 * boost/timer testing block
 */

int main()
{
 boost::timer t;
 cout<<"Maximum time:"<<t.elapsed_max()<<endl;
 cout<<"Max resolution:"<<t.elapsed_min()<<endl;
 t.restart();
 boost::this_thread::sleep(boost::posix_time::seconds(5));
 cout<<"timer: "<<t.elapsed()<<endl;
 return 0;
}


date_time:
放一个简单的例子:





 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  #include "boost/date_time/gregorian/gregorian.hpp"
  #include <iostream>
  #include <string>

  int
  main()
  {

    using namespace boost::gregorian;
    date t1;
    date t2 = from_undelimited_string("20151221");
    date t3 = from_string("2015-12-21");
    date t4(max_date_time);
    std::cout<<t1<<std::endl;
    std::cout<<t2<<std::endl;
    std::cout<<t3<<std::endl;
    std::cout<<t4<<std::endl;

    std::cout<<"Year: "<<t2.year()<<" Month:"<<t2.month().as_enum()<<" Day:"<<t2.day()<<std::endl;
    std::cout<<"The day of the week: "<<t2.day_of_week().as_long_string()<<std::endl;
    std::cout<<"Format output:"<<to_simple_string(t2)<<std::endl;
    std::cout<<"Format output:"<<to_iso_string(t2)<<std::endl;
    std::cout<<"Format output:"<<to_iso_extended_string(t2)<<std::endl;
    if (t1.is_not_a_date())
     std::cout<<t1<<std::endl;
    if (t4.is_special())
     std::cout<<t4<<std::endl;
    return 0;
  }

输出为:
not-a-date-time
2015-Dec-21
2015-Dec-21
9999-Dec-31
Year: 2015 Month:12 Day:21
The day of the week: Monday
Format output:2015-Dec-21
Format output:20151221
Format output:2015-12-21
not-a-date-time

综合一下:
date 可以由工厂函数from_simple_string, from_string, from_undelimited_string,或者直接由constructor构造。
一些比较有用的API 为判断是否特殊,给出日月年,某月某日第几天等等。
输出可以直接由operator<<或者由工厂函数,to_simple_string, to_iso_string, to_iso_extended_string来输出。

此外还有一些数学运算等等。

下面这个例子来表示运算符以及一些其他的固定用法。









 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include "boost/date_time/gregorian/gregorian.hpp"
#include <iostream>
#include <string>

using namespace boost::gregorian;

class CreditCard{
public:
 CreditCard(const std::string& bankName, int recordDay)
   :bankName_(bankName),
    recordDay_(recordDay)
 {
 };
 int calc_free_days(date consume_day = day_clock::local_day()) const
 {
  date billDay(consume_day.year(),consume_day.month(), recordDay_);
  if (consume_day > billDay)
   billDay += months(1);
  return (billDay - consume_day).days() + 20;
 };

 friend bool operator<(const CreditCard& left, const CreditCard& right)
 {
  return left.calc_free_days()<right.calc_free_days();
 }
 std::string bankName_;
 int recordDay_;
};


int main() {
 CreditCard cardA("BOA", 5);
 CreditCard cardB("CapitalOne", 12);
 CreditCard toUse = std::max(cardA,cardB);
 std::cout<< cardA.bankName_ <<std::endl;
}

这个例子是计算信用卡免息日期,免息日期公式为还款日减去消费日期加20. 有两张卡,比较哪张可以用。 用到date_duration.days() 和 += operator等等。

对于精确到小时分钟秒毫秒的对象用time_duration,这个定义在posix_time里。






 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include "boost/date_time/gregorian/gregorian.hpp"
#include <iostream>
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>

int main() {
 using namespace boost::posix_time;
 boost::posix_time::time_duration dur(1,2,3,4);
 std::cout<<dur<<std::endl;
 std::cout<<"Hour:"<<dur.hours()<<" Min:"<<dur.minutes()
   <<" Second"<<dur.seconds()<<std::endl;
 hours hr(2);
 minutes m(3);
 seconds s(4);
 millisec ms(5);
 time_duration dur2 = hr+m+s+ms;
 std::cout<<dur2<<std::endl;
 std::cout<<dur2 - minutes(4)<<std::endl;
 
 return 0;
}

那么date和time_duration合起来就算是一个完整的时间点了。。。


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include "boost/date_time/gregorian/gregorian.hpp"
#include <iostream>
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>

int main() {
 using namespace boost::gregorian;
 boost::posix_time::ptime p = boost::posix_time::time_from_string("2015-12-21 02:33:25.1341");
 std::cout<<p<<std::endl;
 std::cout<<p.date()<<std::endl;
 std::cout<<p.time_of_day()<<std::endl;
 std::cout<<p+years(2)+boost::posix_time::minutes(25)<<std::endl;
 boost::posix_time::ptime p2 = boost::posix_time::microsec_clock::universal_time();
 std::cout<<p2<<std::endl;
 std::cout<<p2-p<<std::endl;
 return 0;
}

Boost 学习 (开篇)

新工作要用到太多的boost了,以前习惯拿QT里面的库来用,觉得也将就。 什么QHashTable --> boost::unordered_map, QVariant --> boost::any, QThread -->boost::thread这些都差不多的。 其实都是为了跨平台和封装。 新工作里面用到了大量的boost, 比如用boost的binidng和functor来模拟反射,所以很恶心,但是还是蛮实用。 以前自己工作中用到过boost.python这个模块,觉得很好用。后面我会挑自己喜欢的一些内容,做一下笔记。