一、日期和时间
日期和时间的处理这个问题,你说是个小问题,确实不大;你说是个大问题,确实不小。计算机产生的年代虽然不算久远,但处理机制在不断的变化;同样,现实世界中对时间的处理也是五花八门,比如有本地时间,有绝对对时间,有相对时间,有夏令时等等。这一切,都导致程序在处理时,既要有一个标准的约定,在实际表现上,又要符合人们的实际感官。不同的地方的时差问题,都要认真考虑到。 时间精度的不一致导致的大型灾难型事故,可以在网上搜一下。早些年有记忆的人估计都听说过“千年虫”的问题,其实也是类似。上升到哲学高度,时间到底存在不存在?这是个问题。 还是要扯回来,在c++的STL库中是如何对时间进行处理的。总的来说,在c++11前,基本上c++使用的时间和日期相关API都是和C语言库通用的,但是在c++11后,还是有了变化,但是从更后期的发展来看,这个时间库的迭代仍然是非常缓慢,可能c++的大佬们觉得这个东西并不值得深入的研究和开发吧。
二、STL中的相关库
在c++11中提供了std::chrono ,同样,仍然继续支持老的“C-style date and time library”。这里重点介绍前者,后者有兴趣的可以查看一下相关资料,在std::chrono库中,主要分为以下几部分: 1、Clocks:时钟函数,“A clock consists of a starting point (or epoch) and a tick rate. For example, a clock may have an epoch of January 1, 1970 and tick every second. ” 2、Time point:时间点函数,“A time point is a duration of time that has passed since the epoch of a specific clock.” 3、Duration:间隔函数,“A duration consists of a span of time, defined as some number of ticks of some time unit. For example, “42 seconds” could be represented by a duration consisting of 42 ticks of a 1-second time unit.” 4、Time of day:一天中的时间计算函数,“hh_mm_ss splits a duration representing time elapsed since midnight into hours, minutes, seconds, and fractional seconds, as applicable. It is primarily a formatting tool.” 5、Calendar:日历函数,这个没啥说的。不这从此之下,都是c++20才提供的。 6、Time zone:时区函数,这个也是没啥说的。 7、chrono I/O:IO函数,这个就是通过流解析时间。
其它更多的相关日期和算法知识可参考https://en.cppreference.com/w/cpp/chrono。
三、实例
看一下几个相关的实例(cppreference.com):
#include <iostream>
#include <iomanip>
#include <vector>
#include <numeric>
#include <chrono>
#include <algorithm>
#include <ctime>
volatile int sink;
void clock_now()
{
std::cout << std::fixed << std::setprecision(9) << std::left;
for (auto size = 1ull; size < 1000'000'000ull; size *= 100) {
// record start time
auto start = std::chrono::steady_clock::now();
// do some work
std::vector<int> v(size, 42);
sink = std::accumulate(v.begin(), v.end(), 0u); // make sure it's a side effect
// record end time
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> diff = end-start;
std::cout << "Time to fill and iterate a vector of " << std::setw(9)
<< size << " ints : " << diff.count() << " s\n";
}
}
void slow_motion()
{
static int a[] {1,2,3,4,5,6,7,8,9,10,11,12};
while (std::ranges::next_permutation(a).found)
{ } // generates 12! permutations
}
void time_point()
{
using namespace std::literals; // enables the usage of 24h, 1ms, 1s instead of
// e.g. std::chrono::hours(24), accordingly
const std::chrono::time_point<std::chrono::system_clock> now =
std::chrono::system_clock::now();
const std::time_t t_c = std::chrono::system_clock::to_time_t(now - 24h);
std::cout << "24 hours ago, the time was "
<< std::put_time(std::localtime(&t_c), "%F %T.\n") << std::flush;
const std::chrono::time_point<std::chrono::steady_clock> start =
std::chrono::steady_clock::now();
slow_motion();
const auto end = std::chrono::steady_clock::now();
std::cout
<< "Slow calculations took "
<< std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() << "μs ≈ "
<< (end - start) / 1ms << "ms ≈ " // almost equivalent form of the above, but
<< (end - start) / 1s << "s.\n"; // using milliseconds and seconds accordingly
}
int main()
{
clock_now();
time_point();
return 0;
}
运行结果:
Time to fill and iterate a vector of 1 ints : 0.000006568 s
Time to fill and iterate a vector of 100 ints : 0.000002854 s
Time to fill and iterate a vector of 10000 ints : 0.000116290 s
Time to fill and iterate a vector of 1000000 ints : 0.011742752 s
Time to fill and iterate a vector of 100000000 ints : 0.505534949 s
24 hours ago, the time was 2021-02-15 18:28:52.
Slow calculations took 2090448μs ≈ 2090ms ≈ 2s.
例程有很多,基本上把这些API函数弄清楚,也就把这个库掌握的差不多了。更多的例程可以去: https://en.cppreference.com/w/cpp/chrono
四、总结
细节决定成败,小细节,大知识。凡事就怕认真两个字嘛。 努力吧,归来的少年!
|