C++11 中提供了一些非常方便的工具库,这些工具库有时间相关的类,也有字符转换类,在实际编码中,这些类可以帮助大家快速处理时间、日期以及字符串相关的操作。
1 处理日期和时间的chrono库
chrono库中包含了三个时间类型,分别是表示时间间隔的duration、时钟clocks和时间点time point。
1.1 时间间隔duration
duration的原型如下:
template <class Rep, class Period = ratio<1> >class duration;
上面的定义中,Rep表示数据类型,ration表示周期,是一个比例值,ration的定义如下:
template <intmax_t N, intmax_t D = 1> class ratio;
使用时表示的事N/D,D默认等于1。如果用ration表示一秒就可以按照如下来写:
std::ratio<1,1>
同理,如果是一个小时,一分钟就可以按照如下来写:
std::ratio<3600,1>;//一小时std::ratio(60,1);//一分钟
使用duration,可以很方便的定义一些时间间隔,如下面的代码:
int main (){//5毫秒std::chrono::milliseconds ms(5);//15000微妙std::chrono::microseconds us=3*ms;//获取CPU时钟间隔std::chrono::duration<double,std::ratio<1,30>> cpu_30(3.5);std::cout<<"5毫秒周期间隔"<<ms.count()<<std::endl;std::cout<<"15000微妙CPU周期间隔"<<us.count()<<std::endl;return 0;}
代码输出结果为:
5毫秒CPU时钟周期515000微妙CPU时钟周期15000
时间间隔函数还可以参与计算,如下面代码所示:
int main (){std::chrono::milliseconds foo (1000); // 1 secondfoo*=60;std::cout << "duration (in periods): ";std::cout << foo.count() << " milliseconds.\n";std::cout << "duration (in seconds): ";std::cout << foo.count() * std::chrono::milliseconds::period::num / std::chrono::milliseconds::period::den;std::cout << " seconds.\n";return 0;}
代码输出结果为:
duration (in periods): 60000 milliseconds.duration (in seconds): 60 seconds.
需要特别说明的是,在duration的计算过程中,如果两个duration的时钟周期不同,计算时会先转换成一致的时钟周期然后在进行运算,转换规则如下:
如果存在两个duration,第一个duration表示为:ratio(x1,y1),第二个表示为:ratio(x2,y2),如果x1,x2的最大公约数为A,y1,y2的最小公倍数为B,则转换成统一的时钟周期后可以标识为:ration(A,B).
示例如下:
int main (){std::chrono::duration<double,std::ratio<4,7>> d1(3);std::chrono::duration<double,std::ratio<2,9>> d2(1);auto d3 = d1-d2;std::cout << typeid(d3).name()<<std::endl;std::cout << d3.count() << std::endl;;return 0;}
d3.count()的输出结果为:47.
1.2 时间节点 time point
time_point表示的是一个时间节点,可以标识从纪元或者1970.1.1以来经历的时间,可以和ctime结合使用。在实际编码时,time_point使用clock计时。在time_point中可以使用time_from_eproch()来获取1970年以后经历的秒数。如下面的代码:
int main (){typedef std::chrono::duration<double,std::ratio<60*60*24>> day;std::chrono::time_point<std::chrono::system_clock,day> today =std::chrono::time_point_cast<day>(std::chrono::system_clock::now());std::cout << today.time_since_epoch().count()<<" day's since epoch"<<std::endl;return 0;}
代码运行结果如下:18906.1 day's since epoch
除此之外,time_point还支持算术运算,比如计算前一天或者后一天日期和时间。代码如下:
int main (){std::chrono::system_clock::time_point now = std::chrono::system_clock::now();std::time_t lastDay = std::chrono::system_clock::to_time_t(now - std::chrono::hours(24));std::time_t nextDay = std::chrono::system_clock::to_time_t(now + std::chrono::hours(24));std::cout <<"前一天日期时间是:"<< std::put_time(std::localtime(&lastDay),"%F %T")<<std::endl;std::cout <<"后一天日期时间是:"<< std::put_time(std::localtime(&nextDay),"%F %T")<<std::endl;return 0;}
PS:有些版本的编译器可能不支持put_time.需要进行更新。
1.3 获取系统时钟 clocks
clocks有三种时钟,分别是:
system_clock: xianshi现实的时钟,依赖操作系统时间
steady_clock: 不能被调整的
high_resolution_clock:高精度时钟,使用now或者时间点
获取的时钟中期可以参数算术运算,实例如下:
int main (){std::chrono::system_clock::time_point begin = std::chrono::system_clock::now();std::cout<<"hello world"<<std::endl;std::chrono::system_clock::time_point end = std::chrono::system_clock::now();std::cout <<"tick count:"<<(end - begin).count()<<std::endl;return 0;}
string to_string (int val);string to_string (long val);string to_string (long long val);string to_string (unsigned val);string to_string (unsigned long val);string to_string (unsigned long long val);string to_string (float val);string to_string (double val);string to_string (long double val);
int main (){std::string pi = "pi is " + std::to_string(3.1415926);std::string perfect = std::to_string(1+2+4+7+14) + " is a perfect number";std::cout << pi << '\n';std::cout << perfect << '\n';return 0;}
pi is 3.14159328 is a perfect number
atoi:数值型字符串转换为整型
atol:数值型字符串转换为long型
atoll:数值型字符串转换为long long型
atof:数值型字符串转换为浮点型
演示代码如下:
int main (){char buffer[256];printf ("Enter a long number: ");fgets (buffer, 256, stdin);long lNum = atol(buffer);int iNum = atoi(buffer);long long llNum = atoll(buffer);double fNum = atof(buffer);return 0;}
3 宽窄字符转换
C++11中增加了unicode字符的支持,使用时通过“L”定义宽字符,如:
std::wstring str = L"中国共产党万岁";
将宽字符转换为窄字符时需要使用codecvt库,该库提供了如下字符编码转转接口:
std::codecvt_utf8:封装了utf-8到ucs2和ucs4的转换
std::codecvt_utf16:封装了utf-16到ucs2和ucs4的转换
std::codecvt_utf8_utf16:封装了utf-8到utf-16的转换
代码示例如下:
std::wstring str = L"中国共产党万岁";std::wstring_convert<std::codecvt<wchar_t, char, std::mbstate_t>> converter(new std::codecvt<wchar_t, char, std::mbstate_t>("CHS"));std::string narrowStr = converter.to_bytes(str);//字符串转换为wstringstd::wstring wstr = converter.from_bytes(narrowStr);std::cout << narrowStr << std::endl;std::wcout.imbue(std::locale("chs"));
运行结果如下:

PS:代码在VS2019编译通过,如果编译不过的话需要升级编译器版本。
- EOF -


扫码关注
图文:龙小
排版:龙小




