zoukankan      html  css  js  c++  java
  • Boost 时间处理

    //部分来自

    //https://www.cnblogs.com/yegoufromchongqing/archive/2013/01/11/2856168.html

    {

      自己进行了一定的补充

    }

    //https://www.cnblogs.com/yegoufromchongqing/archive/2013/01/11/2856168.html

    {

    [Boost]boost的时间和日期处理-(1)日期的操作

    <开篇>

    Boost.DateTime库提供了时间日期相关的计算、格式化、转换、输入输出等等功能,为C++的编程提供了便利。不过它有如下特点:

    1. Boost.DateTime 只支持1400年以后的任何Gregorian日历日期。如果你需要计算再早的日期,则需要寻求其他库来支持。

    日期和时间是编程过程中常用的操作。在C标准库中,<time.h>提供了time_t类型、和tm结构类型的时间日期相关函数。Windows API也提供了FILETIME类型的相关函数。由于这里是介绍boost,就不比较这几种之间的优劣了,感兴趣的朋友可以深究一下,相信你会根据自己的需要进行选择。那么,下面我将根据不同情形大概介绍一下Boost.DateTime中的主要功能。如果你需要严格的时间精度计算,请参看Boost.DateTime稳定度和精度的讨论

    *基本概念:

    时间点(Time Point)- 某一个时间,例如上午11点钟。

    时间段(Time Duration)- 一段时间,不特指起止时间,例如1小时。

    时间窗口(Time Interval、Time Period)- 一段时间,从某个时间点到另一时间点,例如下午2点到3点。

    时间系统(Time System)- 特定的时间表示、计算规则的体系。

    日历系统(Calendar System)- 以一天为基础的时间系统。Gregorian Calender是一个标准的日历系统。

    UTC时间(Coordinated Universal Time),支持闰秒的标准时间系统。类似的有格林威治时间GMT。

    DST时间(Daylight Savings Time - 夏令时冬令时)很多国家地区在夏天会调整本地时间。

    时区(Time Zone) - 使用特定DST规则和与标准时之间时间偏差规则的地区或国家。

    Epoch - 日期系统和时钟系统的起点。不同的时间系统起点不一样,通常UTC起点为1970年1月1号0点。

    TAI Time - 高精度的时间系统,使用原子时,这个太深奥了,没有具体研究过。

    注:下列关于Boost.DateTime输入输出的操作,请参看另一篇介绍:Boost.DateTime的IO操作。

    头文件:

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

    例1. 日期计算:打印今天日期;今年感恩节(11月的第4个星期四)的日期;如果还没有到今年感恩节,打印今天到感恩节还有多少天。

    using namespace boost::gregorian;
    typedef nth_day_of_the_week_in_month nth_dow;
    date today = day_clock::local_day(); //today
    std::cout << "today is: " << today << std::endl;
    nth_dow fourth_thur_in_nov(nth_dow::fourth,Thursday,Nov); // 4th thursday in Nov
    date thanksgiving = fourth_thur_in_nov.get_date(today.year()); // get the date this year
    std::cout << "Thanksgiving day this year is: " << thanksgiving << std::endl;
    if(today < thanksgiving)
    {
    date_duration dd = thanksgiving - today; //date duration
    std::cout << "has " << dd.days() << " days to thanksgiving."<< std::endl;
    }

    A. 对于date对象

    >> 要获取一个date对象,可以通过date的4种构造函数:

    1:  date d(2013,Jan,10);//constructor from grep y/m/d
    2:  date d1(d);//copy constructor
    3:  /*special date values*/
    4:  date d2(neg_infin);
    5:  date d3(pos_infin);
    6:  date d4(not_a_date_time);
    7:  date d5(max_date_time);
    8:  date d6(min_date_time);
    9:  date d7; //default constructor

     >> 也可以通过string字符串获得:

    1:      using namespace boost::gregorian;
    2:  date d(from_string("2002/1/25"));
    3:  date d1(from_string("2002-1-25"));
    4:  date d2(from_undelimited_string("20020125"));
    5:  

     >> 还可以从时钟获得:

    1:      using namespace boost::gregorian;
    2:  date d(day_clock::local_day()); //获取本地日期
    3:  date d1(day_clock::universal_day());//获取GMT日期
    4:  

     >>要访问date对象,或进行一些日期判断,请参考下面代码:

     1:      using namespace boost::gregorian;
     2:  date today = day_clock::local_day();
     3:  std::cout << today.year() << std::endl; //打印年
     4:  std::cout << today.month() << std::endl; //打印月
     5:  std::cout << today.day() << std::endl; //打印日
     6:  std::cout << today.week_number() << std::endl;//今年的第几周
     7:  std::cout << today.day_of_week() << std::endl; //打印星期几
     8:  std::cout << today.day_of_year() << std::endl; //打印一年中的第几天
     9:  std::cout << today.end_of_month() << std::endl; //打印本月的最后一天是,闰月的2月,可以试试
    10:  std::cout << today.modjulian_day() << std::endl;
    11:  std::cout << today.julian_day() << std::endl;
    12:  
    13:      if(today.is_infinity())
    14:  // today.is_neg_infinity();today.is_pos_infinity();today.is_not_a_date();
    15:      // today.is_special();
    16:      // today.as_special();
    17:  {
    18:  std::cout << "True" << std::endl;
    19:  }
    20:  else
    21:  {
    22:  std::cout << "False" << std::endl;
    23:  }
    24:  

    >>我们经常还需要将时间转换为string类型,请参考:

    1:  using namespace boost::gregorian;
    2:  date today = day_clock::local_day();
    3:  std::string str1(to_simple_string(today));//YYYY-MMM-DD, 2013-Jan-11
    4:  std::string str2(to_iso_string(today));//YYYYMMDD, 20130111
    5:  std::string str3(to_iso_extended_string(today));//YYYY-MM-DD, 2013-01-11
    6:  std::cout << str1 << std::endl << str2 << std::endl << str3 << std::endl;

    >>date对象还能够和tm互相转换: 

    1:  using namespace boost::gregorian;
    2:  date today = day_clock::local_day();
    3:  tm d_tm = to_tm(today); // tm struct, year start from 1900, and Jan is 0, Sunday is 0
    4:  std::cout << d_tm.tm_year << std::endl << d_tm.tm_mon << std::endl << d_tm.tm_mday << std::endl;
    5:  std::cout << d_tm.tm_wday << std::endl;

     B. 对于date_duration对象

    date_duration可以由多种方式构造,操作符+/-可以计算date,date_duration等,具体如下。

     1:      using namespace boost::gregorian;
     2:  date leap_year_date(2004,Jan,31);
     3:  date norm_year_date(2005,Jan,31);
     4:  date_duration dd(3);
     5:  days dd1(10);
     6:  weeks ww(2);
     7:  months mm(1);
     8:  years yy(2);
     9:  
    10:  std::cout << (leap_year_date + dd) << std::endl;
    11:  std::cout << (leap_year_date + dd1) << std::endl;
    12:  std::cout << (leap_year_date + ww) << std::endl;
    13:  std::cout << (leap_year_date + mm) << std::endl;
    14:  std::cout << (leap_year_date + yy) << std::endl;
    15:  
    16:  std::cout << (norm_year_date + dd) << std::endl;
    17:  std::cout << (norm_year_date + dd1) << std::endl;
    18:  std::cout << (norm_year_date + ww) << std::endl;
    19:  std::cout << (norm_year_date + mm) << std::endl;
    20:  std::cout << (norm_year_date + yy) << std::endl;
    21:  

    另外,迭代器day_iterator,month_iterator,year_iterator也可以看做定长的date_duration工具,在此不细究。

      C. 对于date_period对象

    date_peroid作为一个日期窗口,可用于判断一个日期是否落在这个窗口之间。

    用两个date或一个date加上一个days可以创建date_period。改变一个date_period可以用平移shift、也可以用加宽expand,可以合并merge,还可以取一个包含这两个period的最小period,方法为span。不过使用的时候大家得注意约束条件,比如merge的时候,两个period应该相交,不然怎么合呢?

     1:  using namespace boost::gregorian;
     2:  date d_begin(2013,Jan,22);
     3:  date d_end(2013,Apr,1);
     4:  date_period dp(d_begin,d_end);//constructor
     5:  date_period dp1(d_begin,days(20));//constructor 2
     6:  
     7:  std::cout << dp << std::endl;
     8:  dp.shift(days(10));
     9:  std::cout << dp << std::endl;
    10:  dp.expand(days(10));
    11:  std::cout << dp << std::endl;

    到这里,关于boost的date基本方法都有介绍。不过细心的可能发现,11月的第4个星期四问题还没有细说。其实在boost::date_time里面,有多种方法可以得到答案。例子中使用的是nth_day_of_the_week_in_month。大家不妨试试从11月1号开始,用next_weekday找第1个星期四,然后再加3个weeks,之类。

    关于时间的处理,和日期非常类似,我也会在续篇中介绍,在此结贴鸟。

    <完结>

    }

    my

    {

    #include <iostream>
    //extern "C"
    //{
    //#include <libavutil/des.h>
    //}
    #include <openssl/des.h>
    #include <boost/timer.hpp>
    #include <boost/date_time/gregorian/gregorian.hpp>
    #include <boost/date_time/posix_time/ptime.hpp>
    #include <boost/date_time/time.hpp>
    #include <boost/date_time/posix_time/posix_time.hpp>
    
    //int en(void *datas, int size)
    //{
    //    unsigned char key[] = "FDS5F46F5631DSV61DS11F1DAF16FDS5F46S1DFDS541F5631DSV61DS1F1DAF16";
    //    int keylen = strlen((char*)key);
    //    unsigned char data[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    //    int datalen = strlen((char*)data);
    //
    //
    //    unsigned char buf_e[1024] = { 0 };
    //    unsigned char buf_d[1024] = { 0 };
    //
    //    auto des = av_des_alloc();
    //    auto ret = av_des_init(des, key, keylen, 0);
    //
    //    av_des_crypt(des, buf_e, (unsigned char*)data, datalen, nullptr, 0);
    //    ret = av_des_init(des, key, keylen, 1);
    //    av_des_crypt(des, buf_d, buf_e, 1, nullptr, 1);
    //
    //
    //
    //    return -1;
    //}
    //
    //int de(void *data, void *out)
    //{
    //    const char *keystring = "this is my key";
    //    DES_cblock key;
    //    DES_key_schedule key_schedule;
    //
    //    //生成一个 key  
    //    DES_string_to_key(keystring, &key);
    //    if (DES_set_key_checked(&key, &key_schedule) != 0) {
    //        printf("convert to key_schedule failed.
    ");
    //        return -1;
    //    }
    //
    //    //需要加密的字符串  
    //    unsigned char input[] = "this is a text being encrypted by openssl";
    //    size_t len = (sizeof(input) + 7) / 8 * 8;
    //    unsigned char *output = (unsigned char *)malloc(len + 1);
    //    //IV  
    //    DES_cblock ivec;
    //
    //    //IV设置为0x0000000000000000  
    //    memset((char*)&ivec, 0, sizeof(ivec));
    //
    //    //加密  
    //    DES_ncbc_encrypt(input, output, sizeof(input), &key_schedule, &ivec, DES_ENCRYPT);
    //
    //    //输出加密以后的内容  
    //    for (int i = 0; i < len; ++i)
    //        printf("%02x", output[i]);
    //    printf("
    ");
    //
    //    memset((char*)&ivec, 0, sizeof(ivec));
    //    unsigned char ii[256] = { 0 };
    //    //解密  
    //    DES_ncbc_encrypt(output, ii, len, &key_schedule, &ivec, 0);
    //
    //    printf("%s
    ", ii);
    //
    //    free(output);
    //    return -1;
    //}
    
    
    
    using namespace boost::gregorian;
    using namespace std;
    using namespace boost::posix_time;
    
    int main(int argc, char *argv[])
    {
    
    
        printf("=============
    ");
    
        date d(day_clock::local_day());
        auto d_0 = boost::gregorian::day_clock::local_day_ymd();
        
        auto d_1 = boost::gregorian::to_iso_extended_string(d);
        std::cout << d_1 << std::endl;
    
        
    
    
        std::string strDateTime = boost::posix_time::to_simple_string(boost::posix_time::microsec_clock::local_time());
    
        std::cout << strDateTime << std::endl;
    
        std::string strTime = boost::posix_time::to_iso_string(boost::posix_time::microsec_clock::local_time());
        strTime.insert(4, "-");
        strTime.insert(7, "-");
        int pos = strTime.find('T');
        strTime.replace(pos, 1, std::string(" "));
        strTime.insert(13, ":");
        strTime.insert(16, ":");
        
        std::cout << strTime << std::endl;
    
        auto t = boost::posix_time::microsec_clock::local_time();
    
    
    
    
    
        date leap_year_date(day_clock::local_day());
    
        date norm_year_date(2020, Jan, 31);
    
        date_duration dd(3);
    
        years yy(2);
        months mm(1);
        days dd1(10);
        weeks ww(2);
    
        //爽歪歪
        std::cout << (leap_year_date - days(365)) << std::endl;
        //爽歪歪
        std::cout << boost::gregorian::to_iso_extended_string((leap_year_date - days(365))) << std::endl;
    
        std::cout << (leap_year_date + dd) << std::endl;
    
        std::cout << (leap_year_date + dd1) << std::endl;
    
        std::cout << (leap_year_date + ww) << std::endl;
    
        std::cout << (leap_year_date + mm) << std::endl;
    
        std::cout << (leap_year_date + yy) << std::endl;
    
        
    
        std::cout << (norm_year_date + dd) << std::endl;
    
        std::cout << (norm_year_date + dd1) << std::endl;
    
        std::cout << (norm_year_date + ww) << std::endl;
    
        std::cout << (norm_year_date + mm) << std::endl;
    
        std::cout << (norm_year_date + yy) << std::endl;
    
    
    
    
    
    
    
    
    
    
    
    
    
    
        return 0;
    }

    }

    运行结果

    {

    }

  • 相关阅读:
    浮动广告
    jQuery给table添加行和删除行
    oracle优化方式和sql标准
    使用JavaScript中的ActiveXObject填充并设置Excel格
    打印相关的js
    利用js导出Excel
    Oracle左外连接和右外连接的写法
    天气预报抓取的方法和源代码(包括从IP获取)
    algorithm
    ungetc
  • 原文地址:https://www.cnblogs.com/YZFHKMS-X/p/14047439.html
Copyright © 2011-2022 走看看