In the C language, time.h defines structures and functions for date and time operations, but the so-called date type is not provided in the C++ standard library, but is inherited from the C language. There is an important concept in expressing time: time stamp, time stamp refers to the time from 00:00:00 on January 1, 1970, Greenwich Mean Time (08:00:00, January 1, 1970, Beijing time) The total number of seconds so far .
The following is an analysis and study of two important time libraries ctime and chrono in C/C++, and the connection between them is explained.
ctime
In C, the ctime header file contains function definitions for obtaining and manipulating dates and times . Next, it will introduce three aspects: how to represent time, conversion between different times, and time operation functions.
Time Data Structure
Four different time representation data structures are provided in ctime : clock_t, size_t, time_t, and struct tm.
- time_t
Indicates the number of seconds elapsed since 0:00 on January 1, 1970 in the UTC time zone. It is actually a long type and the unit is seconds.
- struct tm
struct tm is a structure that contains date and time information. The specific definition is as follows:
struct tm
{
int tm_sec; /* Seconds. [0-60] (1 leap second) */ 秒
int tm_min; /* Minutes. [0-59] */ 分
int tm_hour; /* Hours. [0-23] */ 时
int tm_mday; /* Day. [1-31] */ 天
int tm_mon; /* Month. [0-11] */ 月
int tm_year; /* Year - 1900. */ 距1900年的年数
int tm_wday; /* Day of week. [0-6] */ 星期几
int tm_yday; /* Days in year.[0-365] */ 一年中的第几天
int tm_isdst; /* DST. [-1/0/1]*/
}
When using struct tm to build time, you need to pay attention to the meaning of each variable and the starting number.
- clock_t
It is used for counting clock ticks and is actually of long type.
- size_t
Alias for unsigned int type.
time conversion function
The ctime header file provides 6 time conversion functions: asctime, ctime, gmtime, localtime, strftime, mktime.
- asctime
Convert the time data structure of struct tm to string string.
- ctime
Convert a time_t time data structure to a string string.
- gmtime
Convert time_t to struct tm data structure (UTC Time).
- localtime
Convert time_t to struct tm data structure (local Time).
- srftime
Generate formatted string content from struct tm data structure (commonly used function).
- mktime
Convert struct tm data structure to time_t data structure.
time manipulation function
Three kinds of time operation functions are provided in ctime: time, clock, and difftime.
- time
Returns the current time. The return value is of type time_t, indicating the time from January 1, 1970, 00:00:00 UTC GMT, in seconds
time_t now;
time(&now); /* get current time; same as: now = time(NULL) */
- clock
Get the constant ticks, return clock_t type.
- difftime
Get the time difference between two time_t data types in seconds.
double difftime (time_t end, time_t beginning);
for example
- Get the current time and convert it to struct tm type, then convert it to a string and print
#include <ctime>
#include <iostream>
int main()
{
time_t now = time(NULL); // 获取当前时间
std::cout << "The current local time is: " << ctime(&now) << std::endl;
struct tm* timeinfo = localtime(&now);
std::cout << "current Beijing (China) time and date: " << asctime(timeinfo) << std::endl;
struct tm* timeinfo2 = gmtime(&now);
std::cout << "current Reykjavik (Iceland) time and date: " << asctime(timeinfo2) << std::endl;
return 0;
}
- Construct struct tm time and convert to time_t type
int main()
{
struct tm timeinfo = {
0};
timeinfo.tm_year = 100; // 距离1900的100年, 即2000
timeinfo.tm_mon = 0; // 一月
timeinfo.tm_mday = 1; // 第一天
std::cout << "1/1/2000 represented by struct tm is: " << asctime(&timeinfo) << std::endl;
time_t tt = mktime(&timeinfo);
std::cout << "1/1/2000 represented by time_t is: " << asctime(&timeinfo) << std::endl;
return 0;
}
- formatted time
int main()
{
struct tm timeinfo = {
0};
timeinfo.tm_year = 100; // 距离1900的100年, 即2000
timeinfo.tm_mon = 0; // 一月
timeinfo.tm_mday = 1; // 第一天
// format time as string
char buf[80];
// format
// %Y : Year (2023)
// %m : Month (0-12)
// %d : Day of the month (0-31)
// %H : Hour in 24th format (00-23)
// %M : Minute (00-59)
// %S : Second (00-61)
strftime(buf, 80, "Now it's %Y-%m-%d-%H-%M-%S.", &timeinfo);
std::cout << "Format time and data: " << buf << std::endl;
return 0;
}
chrono
Chrono is a time library in C++11, providing timing, clock and other functions. The key is to understand concepts such as durations and time points.
time beat
Time beat refers to the basic unit of time counting , which is defined as follows:
template <intmax_t N, intmax_t D = 1> class ratio;
Among them, N represents the numerator, D represents the denominator, and the default time beat unit is seconds.
Common time ticks are defined as follows:
ratio <60, 1> minute; // 60/1 seconds
ratio <1, 1> second;
ratio <1, 1000> microsecond;
period
Duration represents a period of time, which is defined as follows:
template < class Rep, class Period = ratio<1>> class duration;
Among them, Rep represents the number of Periods, which can be int, float, double and other types. Period is a ratio type, used to represent the time beat (accuracy).
The value of Rep multiplied by the Period precision is equal to the size of a period of time.
The macros in chrono define many special durations: hours, miniutes, seconds, milliseconds and so on.
/// nanoseconds
typedef duration<int64_t, nano> nanoseconds;
/// microseconds
typedef duration<int64_t, micro> microseconds;
/// milliseconds
typedef duration<int64_t, milli> milliseconds;
/// seconds
typedef duration<int64_t> seconds;
/// minutes
typedef duration<int64_t, ratio< 60>> minutes;
/// hours
typedef duration<int64_t, ratio<3600>> hours;
Common time unit conversion knowledge:
second (second), time unit: s,
millisecond (millisecond), time unit: ms
microsecond (microsecond), time unit: μs
Time conversion:
1s [second] = 1000ms [millisecond]
1ms [millisecond ] = 1000μs【microsecond】
1μs【microsecond】 = 1000ns【nanosecond】
1ns 【nanosecond】= 1000ps【picosecond】
The member function count returns the quantity under unit precision, that is, the Rep value. The duration_cast function is used to convert the precision of the Period in the duration to obtain different Rep values.
#include <iostream>
#include <chrono>
int main()
{
// 使用chrono库中自定义的duration
typedef std::chrono::seconds seconds_type;
typedef std::chrono::minutes minutes_type;
typedef std::chrono::hours hours_type;
// template<class Rep2>
// constexpr explicit duration (const Rep2& n);
hours_type h_oneday(24); // 24h
std::cout << h_oneday.count() << "hours." << std::endl;
// 赋值构造函数
minutes_type ms_oneday = std::chrono::duration_cast<minutes_type>(h_oneday) ;
std::cout << ms_oneday.count() << "minutes." << std::endl;
// 赋值构造函数
seconds_type s_oneday = std::chrono::duration_cast<minutes_type>(h_oneday);
std::cout << s_oneday.count() << "seconds." << std::endl;
return 0;
}
point in time
time_point indicates a specific time, where Clock is used to specify the clocks to be used (system_clock, steady_clock and high_resolution_clock), and the second parameter duration type indicates the accuracy of the time point.
template< class Clock, class Duration = typename Clock::duration > class time_point;
Clock clock
Three clocks are provided in chrono: system_clock, steady_clock and high_resolution_clock. Each clock class has certain time_point, duration, Rep, Period types.
All three clock classes provide a static member function **now() ** for obtaining the current time, and the return value of this function is a time_point type.
- system_clock: system time, which can be adjusted manually. In addition to the now() function, system_clock also provides the to_time_t() static member function, which is used to convert the system time into the familiar std::time_t type, and the from_time_t() static member function, which is used to convert the time_t time type to time_point;
- steady_clock: It is a monotonous clock, similar to a stopwatch in the hands of a coach, suitable for recording the time spent in the program;
- high_resolution_clock: It is the highest-precision clock that the current system can provide, and it cannot be modified, which is equivalent to the high-precision version of steady_clock;
for example
- The time spent recording the program
int main()
{
using std::chrono::steady_clock;
typedef std::chrono::seconds seconds_type;
typedef std::chrono::milliseconds milliseconds_type;
typedef std::chrono::microseconds microseconds_type;
steady_clock::time_point start = steady_clock::now();
std::cout << "printing out 1000 stars...\n";
for (int i=0; i<1000; ++i) std::cout << "*";
std::cout << std::endl;
steady_clock::time_point end = steady_clock::now();
seconds_type s_span = std::chrono::duration_cast<seconds_type>(end - start);
std::cout << "It took me " << s_span.count() << " seconds." << std::endl;
milliseconds_type mill_span = std::chrono::duration_cast<milliseconds_type>(end - start);
std::cout << "It took me " << mill_span.count() << " milliseconds." << std::endl;
microseconds_type micro_span = std::chrono::duration_cast<microseconds_type>(end - start);
std::cout << "It took me " << micro_span.count() << " microseconds." << std::endl;
return 0;
}
- System_clock and time_t time types are interchangeable
int main()
{
using std::chrono::system_clock;
system_clock::time_point now_t = system_clock::now();
time_t tt;
tt = system_clock::to_time_t(now_t);
std::cout << "now is: " << ctime(&tt) << std::endl;
// 构建 struct tm转换为 time_t,然后将time_t转换为time_point
struct tm timeinfo = {
0};
timeinfo.tm_year = 100; // 距离1900的100年, 即2000
timeinfo.tm_mon = 0; // 一月
timeinfo.tm_mday = 1; // 第一天
time_t tt_2000 = mktime(&timeinfo);
std::cout << "1/1/2000 is: " << ctime(&tt) << std::endl;
system_clock::time_point tp = system_clock::from_time_t(tt_2000);
system_clock::duration d = system_clock::now() - tp;
// convert to number of days
typedef std::chrono::duration<int64_t, std::ratio<60*60*24>> days_type;
days_type ndays = std::chrono::duration_cast<days_type> (d);
// display result
std::cout << ndays.count() << "days have passed since 1/1/2000" << std::endl;
return 0;
}