你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

C/C++时间相关的那些函数

[复制链接]
gaosmile 发布时间:2020-10-6 22:04
大家平时工作,如果有计算函数耗时或者打印当前时间的需求,一定要来看看这篇文章!
8 f. I3 e7 d0 g' s  G: g& H3 \6 s
首先介绍下C++标准中的chrono库
chrono是一个关于时间的库,起源于boost,现在是C++的标准,话说现在的C++标准好多都是源于boost,要进标准的特性似乎都会先在boost试验一番。
首先看一下使用chrono简单计时的示例代码:5 b% y/ E5 m3 j" J  O* D, Z& V

  1. ' `3 Z6 f2 u, l! M9 L& [0 {
  2. void func() {  // 计时  `- J  {9 @" H
  3.    std::chrono::time_point<std::chrono::high_resolution_clock> begin = high_resolution_clock::now();
    # S  K; b$ M. c" m1 O. ^+ _0 N: p
  4.    std::this_thread::sleep_for(std::chrono::milliseconds(20));2 @! d: ?6 ~- U. A, b% a' ^
  5.    auto end = high_resolution_clock::now();
    + h* D- P3 q% }$ U, P
  6.    cout << "time " << duration_cast<milliseconds>(end - begin).count() << endl;
    8 b4 E4 Z+ t+ g
  7. }
复制代码
: R$ G2 f/ A* l/ P3 p1 `! S7 @- A
chrono中有三个概念duration、time_point、clock
duration:表示一段时间,三分钟、三秒等,它的定义如下:& c* x" b/ Q+ m6 G3 C0 ?! W; D  [
  • template <class _Rep, class _Period = ratio<1>> class duration;
    / z) `& S  l% l5 p
ratio的定义如下:. |: h3 ]8 h& p) w6 l, e
  • template <intmax_t N, intmax_t D = 1> class ratio;
    0 O5 [( j6 W1 `, r' V
Rep表示数据类型,int,long等,Period表示时间单位,N是分子,D是分母,直接看例子吧:
% g1 U- t+ K' {* w& S4 S
  1. - K( a7 a7 i2 O( Y/ U$ n5 e
  2. using atto  = ratio<1, 1000000000000000000LL>;
    ( q, I( T9 y- Z2 U
  3. using femto = ratio<1, 1000000000000000LL>;
    ( p1 |+ u7 a, @( H5 {( S! J; E" b$ G( a
  4. using pico  = ratio<1, 1000000000000LL>;& o. r7 b' H) b( C* |5 n
  5. using nano  = ratio<1, 1000000000>;+ a+ |: F* ^: ~; a5 y
  6. using micro = ratio<1, 1000000>;  _3 a: K% |* r  b/ j
  7. using milli = ratio<1, 1000>;% c& r$ O4 j. d7 R
  8. using centi = ratio<1, 100>;8 M& i" a3 h5 z, G( M& c
  9. using deci  = ratio<1, 10>;
    & B# ~( [# a& ]  ]
  10. using deca  = ratio<10, 1>;
    9 @2 {; N' S1 M
  11. using hecto = ratio<100, 1>;( z3 ]. g3 E! ?7 W1 J
  12. using kilo  = ratio<1000, 1>;
    ( T: G9 S3 w7 E! g7 i  e  L' u
  13. using mega  = ratio<1000000, 1>;
    - Z4 E/ G- E0 l4 b( I( U6 A
  14. using giga  = ratio<1000000000, 1>;3 Y4 \# a9 L/ b% c* ]" k. s  K6 k
  15. using tera  = ratio<1000000000000LL, 1>;
    6 \4 q/ f; D3 D- A- R, \
  16. using peta  = ratio<1000000000000000LL, 1>;
    0 g5 Q, v' D" a% y8 K8 G/ i
  17. using exa   = ratio<1000000000000000000LL, 1>;
    ' o: ~- o) u6 p6 Q. ]( I% c

  18. / ~+ \+ e$ u4 ?8 ?( E+ S! z7 d
  19. using nanoseconds  = duration<long long, nano>;
    ' k, _% i  k1 B6 W2 O: G# I
  20. using microseconds = duration<long long, micro>;
    2 {& K  r: V, a( |7 [' N" i, Q  H$ A
  21. using milliseconds = duration<long long, milli>;
    ' i1 b$ b" o" a4 x, o& ~, k# A
  22. using seconds      = duration<long long>;
    ; q$ b' k' j% N4 D0 @9 |+ N
  23. using minutes      = duration<int, ratio<60>>;
    3 N3 u4 j4 F$ U0 u0 L7 }
  24. using hours        = duration<int, ratio<3600>>;* k# |8 p2 D* O5 P1 X8 i! x

  25. ; ~7 W) }* ?2 R' y7 S
  26. using hours2       = duration<int, ratio<3600, 1>>;8 a, E4 s& z' W% D3 }
  27. using hours2       = duration<int, ratio<7200, 2>>;
复制代码
8 |6 \2 f; p4 ^  G# s- z6 ^
详细看完上述例子您也明白了,ratio的默认的时间单位是1秒,以小时为例,一小时等于3600秒,3600 / 1 == 7200 / 2 == 3600,所以hours == hours2 == hours3。
标准库还提供了duration_cast用于转换各种duration。; K" x6 g% K. w5 X

  1. 4 b. z& p, }3 r1 [3 X: C$ @5 n9 J7 C: H8 C
  2. template <class _To, class _Rep, class _Period, enable_if_t<_Is_duration_v<_To>, int> = 0>
    3 s" ]' o; C6 P1 S% |0 L# j
  3.    constexpr _To duration_cast(const duration<_Rep, _Period>&) noexcept(
    4 T1 L' f$ }  e1 A7 V# G
  4.    is_arithmetic_v<_Rep>&& is_arithmetic_v<typename _To::rep>);
    % ]9 n$ _/ B! S- _5 G6 a  J9 r) g3 p

  5. 9 ]+ M3 P( T6 z' q6 G  F
  6. template <class _Ty>
    7 {8 y3 _5 h& ^* {* |# T
  7.    _INLINE_VAR constexpr bool _Is_duration_v = _Is_specialization_v<_Ty, duration>;! _+ [9 L/ f- a- K" z
  8. 1 a7 C" f4 }4 a6 m
  9. template <class _Ty>9 U. D& f4 y3 F+ u& R7 \& x% N( D; C
  10. _INLINE_VAR constexpr bool is_arithmetic_v = // determine whether _Ty is an arithmetic type
    , ^, U! L3 S! u8 j
  11.    is_integral_v<_Ty> || is_floating_point_v<_Ty>;
复制代码
2 Z! @, }1 C' z" k3 V1 i6 S: a% }" S
函数看着很繁琐,直接看看示例代码吧:
" y9 r- ~6 @% K6 r* |1 v' y  }

  1. ) B- {  U3 `) U# a1 i& J& }9 ^# i
  2. void func() {4 h* N- d" r! A6 N! S0 x# O. e
  3.    auto sec = std::chrono::seconds(10);0 V- n: I/ {1 `3 t* Y+ A: c
  4.    auto mill = std::chrono::duration_cast<std::chrono::milliseconds>(sec);- N, b, U: j1 @! B
  5.    cout << sec.count() << endl; // 返回多少s
    - c8 m" h; `2 {4 L  s
  6.    cout << mill.count() << endl; // 返回多少ms
    0 O+ |7 R0 Z& [& X' S2 B6 w% B! p
  7. }6 f3 B, r8 W" I8 F$ C0 |. ]" D: r8 B
  8. 输出:
    ; j6 [- D$ S! ~8 r
  9. 10
    ) b+ [6 O; |5 j8 s- B6 A
  10. 10000
复制代码

# _7 O  ~3 D$ ]7 k, \
time_point:用来表示某个具体时间点。
定义如下:' x  p: M$ Z, |  x) B
  1. 1 S: Q  E  m; A9 E4 K
  2. template <class _Clock, class _Duration = typename _Clock::duration>
    6 v# W4 n1 p5 K4 W) r8 @2 B  [. y
  3.    class time_point;
复制代码
1 l2 V0 H& q! g+ R3 z
使用方式如下:
9 }  ?# L3 u/ a& w+ g
  1. $ M. z0 h8 G* Q1 J: g
  2. void func() {
    ; ^4 g; [. w/ D* O2 {4 O6 c* `
  3.    std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp(std::chrono::seconds(12));) _7 Z0 g2 t3 Y' P; [) [
  4.    cout << tp.time_since_epoch().count() << endl;
    ) @7 N3 _# l$ ?$ X+ z: ]9 h
  5.    std::time_t t = system_clock::to_time_t(tp);
    % i( S" N' e& R+ @; u; T
  6.    cout << "time " << ctime(&t) << endl;1 w6 P* Q9 o! K$ `7 W; d3 b0 [
  7. }: a# y+ U6 r$ Q* u
  8. 输出:2 N7 z9 q$ n* Y1 P
  9. 12000
    4 U, x6 W/ h: R
  10. time Thu Jan  1 08:00:12 1970
复制代码
" A, Z3 n) d) I& ]- @1 f
这里有个函数time_since_epoch(),表示这个time_point距离元年也就是1970年1月1日所经过的duration。
time_point也有各种表示方式,类似于duration,也提供了转换函数time_point_cast()。( y8 S5 L) H. Y! @1 `  U; i* Y) Q
  1. % r9 K6 I: C) j( a/ D# |) B5 [+ w
  2. void func() {* q  u/ n7 P+ K1 W! o
  3.     time_point<system_clock, milliseconds> tp(seconds(12));
    3 h  i3 A6 p' ^  U! H! J
  4.     cout << tp.time_since_epoch().count() << endl;! |7 d" w0 y' e/ K% J- r$ q7 }
  5.     time_point<system_clock, seconds> tp2 = time_point_cast<seconds>(tp);
    ' [( i% w- ^) e
  6.     cout << tp2.time_since_epoch().count() << endl;% C4 y/ t+ y$ f: ?0 B
  7. }7 v4 k( u5 ]$ o* r- r
  8. 输出:
    , `$ ^) y$ E7 Q9 n
  9. 12000" P6 D- P2 W  X1 e" z3 E+ F, L
  10. 12
复制代码
4 t  F) R' M: n" z
Clocks:
这里的时钟大体有三种:
system_clock
steady_clock
high_resolution_clock
system_clock表示当前的系统时钟,有三个函数:) O* J# X. e2 B4 D* r7 r. U

  1. / t. N/ ^1 h, S3 e1 c
  2. now():表示当前时间的time_point
    2 D% d1 \7 E( D( C  o
  3. to_time_t():将time_point转换成time_t秒
    # V) d# {) [. H. X
  4. from_time_t():将time_t转换成time_point
复制代码
* \/ z2 L8 f# b( D2 ?( B2 \7 r
源码如下:
' y4 [. e" G9 f7 O; @' J

  1. 4 o2 R1 `1 v0 b  r" z& u( J5 y
  2. struct system_clock { // wraps GetSystemTimePreciseAsFileTime/GetSystemTimeAsFileTime) c: j' d# w- U7 m! o& |
  3.     using rep = long long;( ~8 C7 y3 R) u& {) p& c

  4. : y! n) x2 o/ r( ~+ n  m5 j
  5.     using period = ratio_multiply<ratio<_XTIME_NSECS_PER_TICK, 1>, nano>;
    0 m, I% x7 {: x% ^9 e- Y8 N  ^
  6. 9 d- o! l% @8 v6 l8 Z4 V
  7.     using duration                  = chrono::duration<rep, period>;& V* X( G" r6 [8 ^8 D% f* K
  8.     using time_point                = chrono::time_point<system_clock>;  ]* H4 u" I  I# E4 Z
  9.     static constexpr bool is_steady = false;
    3 T2 D& ~8 e8 w: n. f5 i; K+ h+ n

  10. 9 G  \# l- f9 x* x( y" p
  11.     _NODISCARD static time_point now() noexcept { // get current time
      f- H- P7 ^# E
  12.         return time_point(duration(_Xtime_get_ticks()));
    4 V' Q5 `/ A- A+ f. j
  13.     }
    3 M) D4 B( e& K! ]7 ]
  14. : \) q* p+ i# @9 T" o3 g
  15.     _NODISCARD static __time64_t to_time_t(const time_point& _Time) noexcept { // convert to __time64_t
    # d8 h. R* {8 f0 b
  16.         return static_cast<__time64_t>(_Time.time_since_epoch().count() / _XTIME_TICKS_PER_TIME_T);
    & S& ^; k9 J' }7 q3 @
  17.     }2 ?1 x/ S6 ~& v# I

  18. # w0 K: `: I6 V
  19.     _NODISCARD static time_point from_time_t(__time64_t _Tm) noexcept { // convert from __time64_t1 r3 ~) x4 z) _! B0 c, n3 f: L
  20.         return time_point(duration(_Tm * _XTIME_TICKS_PER_TIME_T));1 U0 v6 ^4 u% K+ u# G2 \5 `3 t
  21.     }
    & J3 Y/ N* l- D" ^8 T; Q& l8 k
  22. };
复制代码

1 X9 d" b' L6 x/ }' l
steady_clock表示稳定的时钟,它只有一个函数,就是now(),后一次调用now()肯定比上一次调用now()的返回值大,不受系统时间修改的影响。
源码如下:4 r5 A4 P0 M8 c

  1. 1 v2 ]) Y  p7 }
  2. struct steady_clock { // wraps QueryPerformanceCounter  b' x% s! a( _; ^3 b- K- O5 Y
  3.     using rep                       = long long;
    - R' h( j  Z  Z' r) I
  4.     using period                    = nano;
    2 I- W7 C  Y) {+ ~3 }! v; I( Q
  5.     using duration                  = nanoseconds;, `7 V0 B% ]6 j8 W7 F
  6.     using time_point                = chrono::time_point<steady_clock>;1 B+ Z! c4 j3 ?' Q" @) d7 k
  7.     static constexpr bool is_steady = true;2 A: A$ t8 w, a9 X: ?

  8. & w- x1 c. T8 ~5 E
  9.     _NODISCARD static time_point now() noexcept { // get current time' t, k2 f1 m- f. ~+ p, ^
  10.         const long long _Freq = _Query_perf_frequency(); // doesn't change after system boot
    : Q  v7 G: a% D  H. ^# Y2 H4 N( U
  11.         const long long _Ctr  = _Query_perf_counter();9 f4 Z, V- H( N% ?* A$ M
  12.         static_assert(period::num == 1, "This assumes period::num == 1.");
    , Q; w9 c/ e) e+ {7 M
  13.         const long long _Whole = (_Ctr / _Freq) * period::den;
    3 A( V  f1 b. w/ D* m
  14.         const long long _Part  = (_Ctr % _Freq) * period::den / _Freq;
      o: D( f: \. N+ m; v$ G1 x6 ]
  15.         return time_point(duration(_Whole + _Part));
    ' n# ?( \; [2 [9 y. ~, d
  16.     }
      f  k; s- z7 l, x: h( Q: J+ k+ [0 b$ n
  17. };
复制代码
' C" X) K+ k: \8 O  r. c) n9 g
使用方式和之前的都相同:
8 y3 j; s9 L4 u  M& O% y' ^, W8 c0 {
  1. * b1 h& f( A: W
  2. void func() {  // 计时/ W/ n% K7 @$ U2 r# S2 l
  3.     std::chrono::time_point<std::chrono::steady_clock> begin = steady_clock::now();& W" h( |8 y& e! U
  4.     std::this_thread::sleep_for(std::chrono::milliseconds(20));. q2 ~9 \9 {- p  Z9 g1 s
  5.     auto end = steady_clock::now();5 U$ _7 M: i9 @6 F! G8 I
  6.     cout << "time " << duration_cast<milliseconds>(end - begin).count() << endl;
    5 p) c) ^% _% E/ e4 u! f+ V8 {: K8 J
  7. }
复制代码
2 o* X+ M2 z  V9 \7 V& m
high_resolution_clock表示高精度时钟,是系统可用的最高精度的时钟,它其实就是system_clock或者steady_clock的别名:  F9 w, A/ _0 n( O/ S
  • using high_resolution_clock = steady_clock;7 q2 v/ R: I+ q8 N
介绍完了C++的chrono那下面再看下C语言的各种时间相关的API吧:
首先可以通过C语言的clock拿到程序执行时处理器所使用的时钟数来计时:
# M% k- b( X+ B5 [, ~6 T
  • clock_t clock(void);
    % S1 b" R3 \2 I1 Z# y
该函数返回程序执行起(一般为程序的开头),处理器时钟所使用的时间。也获取 CPU 所使用的秒数,除以 CLOCKS_PER_SEC即可,返回的clock_t其实就是long类型的重命名。
使用方式如下:
* {; y. L5 P9 `
  1. + r  L' v" s* @1 A
  2. void func() {
    5 V6 C( j  G0 I2 \* \
  3.     clock_t start_t = clock();
    ; M& f6 C5 P# X5 [5 I' R- x% E' L
  4.     cout << start_t << " 个时钟 \n";
    0 z$ D6 O6 d7 r+ s2 @
  5.     for (int i = 0; i < 100000000; i++) {  [" ^- t& ~% m- x4 M
  6.     }
    6 u! E5 K- V3 t1 U0 A
  7.     clock_t end_t = clock();! ?5 {7 s% B, `7 ^
  8.     cout << end_t << " 个时钟 \n";
    9 R* n6 O. Q. m) d5 Z9 a3 k7 Q8 a6 W
  9.     cout << "循环的秒数:" << (double)(end_t - start_t) / CLOCKS_PER_SEC << endl;
    % n% P& H3 h* `+ ~3 L
  10. }
复制代码
" N; s4 L+ H- @7 k# c
如何获取当前时间戳,单位为秒

  1. 6 S# ]8 D' L% y2 c! c
  2. void func() {  // 获取当前时间戳,单位为秒- k  a: f1 F# [" Z$ a
  3.     struct timeval time;
    0 {9 z' W4 q' l3 }
  4.     gettimeofday(&time, NULL);
    , ?1 J2 w3 r( ?% Q  O
  5.     cout << time.tv_sec << " s \n";; U' B) A3 @* G
  6. }
复制代码

5 O2 L, I: q5 O9 M' x+ K* M
也可以使用time函数:
2 }% }7 t6 O3 D+ d! U+ U3 h. n
  • time_t time(time_t *time);
    . t& Y: U4 F' U6 E, `+ M5 \# i7 v
该函数返回系统的当前日历时间,返回的是自1970年1月1日以来所经过的秒数。
time_t其实就是一个整数类型,是int64_t的重命名,该函数直接使用返回值就好,参数一般传空即可。
timer 存取结果的时间指针变量,类型为time_t,指针变量可以为null。
如果timer指针非null,则time()函数返回值变量与timer指针一样,都指向同一个内存地址;
否则如果timer指针为null,则time()函数返回一个time_t变量时间。$ W; s8 b4 E0 [5 L& \) f3 d) X0 M
  1. : S5 D- Q1 q# k
  2. void func() {  // 获取当前时间戳,单位为秒
    # q! h" f% r- U7 O! |
  3.     time_t now = time(NULL);
    ; ?% M( c) X9 @+ K2 f% X: f6 ^; c' `
  4.     cout << static_cast<int64_t>(now) << " s \n";- z2 g9 O0 y4 R  z3 r$ e9 f
  5. }
复制代码
  I  H! h  q+ S
如何获取当前时间戳?单位为毫秒
  1. ( L$ d! |: Z- S3 M" o: f/ s  f/ c
  2. void func() {  // 获取当前时间戳,单位为毫秒8 e. _$ ?; \* I3 ]' x( l/ R7 ?
  3.     struct timeval time;0 x& l2 n3 k0 |, @
  4.     gettimeofday(&time, NULL);3 f# e5 Q! y8 l" M1 @. @7 T
  5.     cout << time.tv_sec * 1000 + time.tv_usec / 1000 << " ms \n";
    4 ^- f/ N  t- o/ }! e
  6. }
复制代码
4 ~  J; b( i( [; F8 G
如何显示当前的系统时间呢?可以使用ctime显示当前时间:6 R/ K) A) i+ J( ^7 P7 Q
  • char* ctime(const time_t* time);
    . @$ T( U+ P- z, U8 K  D' V
该函数返回一个表示当地时间的字符串指针,输出内容格式如下:+ i% R6 {0 ^: q/ t
  • day month year hours:minutes:seconds year\n\0。' `; W* t8 b, g6 s/ ~
示例代码如下:! j  H% r7 K6 F: [
  1. % Y% \( I; d! x1 Z! V# \( E
  2. void func() {
    4 A9 m- s$ Y  d& Y" {
  3.     time_t now = time(NULL);2 y! C8 S' n+ {" j' s0 v" I
  4.     char* dt = ctime(&now);
    9 s% ]7 z4 A$ S& d. n# T. X* \; Q
  5.     cout << "cur time is: " << dt;
    3 X+ M; e1 z0 C! m/ T9 s: O9 r+ E
  6. }
    2 n6 [9 L* D& z! {$ y
  7. 输出:
    9 Q) s2 P+ \! V* d& I9 t
  8. Tue Sep 22 22:01:40 2020
复制代码
& f# m8 O5 T" f1 G2 P
可以使用tm结构自定义显示当前时间的格式:; x4 i* g+ x+ X& W7 B
  • struct tm * localtime(const time_t * timer);
    ( p, F# c* l5 y0 Y7 b) t, q  Z
将日历时间转换为本地时间,从1970年起始的时间戳转换为1900年起始的时间数据结构
另一个类似的函数是gmtime函数:
" Z4 i& h, Y) k1 d( a
  • struct tm *gmtime(const time_t *time);1 P2 q% H+ l4 a5 t4 Y
只是该函数返回的是UTC时间,协调世界时(UTC)也被称为格林尼治标准时间(GMT)。
tm结构如下:" M/ }2 R( {) ]  [
  1. 4 g9 X; g$ ^  x6 F6 W$ d+ v2 s
  2. struct tm {' S, d2 U( j) J: H, P' a2 K
  3.   int tm_sec;   // 秒,正常范围从 0 到 59,但允许至 61
    * i/ b  X: A# K- [6 @$ c8 z
  4.   int tm_min;   // 分,范围从 0 到 59" `2 f1 R9 j0 i  B. n3 \  F, L! u
  5.   int tm_hour;  // 小时,范围从 0 到 233 ?3 K7 s& U, C2 A" n. G5 |- h; ^
  6.   int tm_mday;  // 一月中的第几天,范围从 1 到 31/ G7 A; Y/ H2 R# W
  7.   int tm_mon;   // 月,范围从 0 到 11$ d* a& X0 O5 {" e! h$ m# T
  8.   int tm_year;  // 自 1900 年起的年数3 l7 t1 y: ]+ c: `8 m
  9.   int tm_wday;  // 一周中的第几天,范围从 0 到 6,从星期日算起5 [, r: m* |  n' a, [. N- F
  10.   int tm_yday;  // 一年中的第几天,范围从 0 到 365,从 1 月 1 日算起0 i1 U  Z8 O0 U: k0 ]
  11.   int tm_isdst; // 夏令时
      ^% |; h, i, P- Q
  12. };
复制代码
- X! _" ~( t: z3 o! c. x: l) j$ f
tm_sec 在C89的范围是[0-61],在C99更正为[0-60]。通常范围是[0-59],貌似有些系统会出现60秒的跳跃。
tm_mon 是从零开始的,所以一月份为0,十二月份为11。
tm_year是从1900年开始计算,所以显示年份的时候需要加上1900. T7 L+ j. n7 ?; ~3 _' }, `7 \6 w

  1. & a, x/ ^6 J% O4 G
  2. void func() {
    / `, J0 T; M) t% G
  3.     time_t rawtime = time(NULL);
    ! ]8 S" H+ [* V$ v. l$ @9 ?) o
  4.     struct tm* ptminfo = localtime(&rawtime);% l2 i5 X- \- k+ q0 U7 {- V+ _
  5.     printf("cur time is: %02d-%02d-%02d %02d:%02d:%02d\n", ptminfo->tm_year + 1900, ptminfo->tm_mon + 1,  T7 U! l4 T' f
  6.            ptminfo->tm_mday, ptminfo->tm_hour, ptminfo->tm_min, ptminfo->tm_sec);
    , v8 G  \. a/ c& G% |
  7.     ptminfo = gmtime(&rawtime);) p2 i- u' p* l- W
  8.     printf("cur time is: %02d-%02d-%02d %02d:%02d:%02d\n", ptminfo->tm_year + 1900, ptminfo->tm_mon + 1,! t8 t( b. B+ b6 w3 U, e
  9.            ptminfo->tm_mday, ptminfo->tm_hour, ptminfo->tm_min, ptminfo->tm_sec);
    7 w- K0 d9 W5 b8 C* Z; F3 v! k5 n/ s
  10. }6 i! G) _  j8 O/ Q+ ]6 S" s
  11. 输出:
    ) u: h# F, ^, O2 x' f# S
  12. cur time is: 2020-09-23 21:27:372 m1 |; x: D% M/ l" ]1 \8 j
  13. cur time is: 2020-09-23 13:27:37
复制代码

" Z' W1 }/ c8 n$ s$ v: u
可以通过asctime显示tm结构的时间:
6 z4 l. {4 h0 U0 A1 Y: E
  • char * asctime ( const struct tm * time );* ~: G  ^& H, h' {
和ctime类似,返回的都是一个固定时间格式的字符串,只是传入的参数不同。
9 X* ?( Y) ?: W9 D7 d

  1. ; u' M: a" c- n3 C
  2. void func() {! `( d3 r% V( t- ~# Q; O. C0 ~- @
  3.     time_t rawtime = time(NULL);
    7 g" p1 _( B) U6 T
  4.     struct tm* info1 = localtime(&rawtime);
    - |. F) z, a( x2 e; ?! J) t, F
  5.     cout << "正常 日期和时间:" << asctime(info1) << endl;
    % Y5 x+ `3 ~$ f7 c0 e" O$ w- o
  6.     info1 = gmtime(&rawtime);
    ( x0 X' {0 J8 p3 j  U
  7.     cout << "UTC 日期和时间:" << asctime(info1) << endl;
    9 w; V$ E; [$ _; A. {
  8. }
    * o+ S7 V% @/ ]" m' g' M
  9. 输出:" F" d" D$ m7 Y
  10. 正常 日期和时间:Wed Sep 23 21:47:44 2020
    2 W+ p8 ]! D& ]3 ?" x( w2 ^9 F* A
  11. UTC 日期和时间:Wed Sep 23 13:47:44 2020
复制代码

5 k0 i/ H2 w5 `0 x9 T
也可以使用strftime()函数,该函数可用于格式化日期和时间为指定的格式,如果产生的 C 字符串小于 size 个字符(包括空结束字符),则会返回复制到 str 中的字符总数(不包括空结束字符),否则返回零。5 E# N  X0 w3 ]7 r" _9 \
  1. - {7 K5 _" M; W+ N, w8 i6 u
  2. size_t strftime(0 M# c* e: E) \/ P7 B7 p- s
  3.     char *str, // 指向目标数组的指针,用来复制产生的C字符串
    9 N) h$ b+ G( T
  4.     size_t maxsize, // 最多传出字符数量
    0 @" O6 n' v  x- N, C( s
  5.     const char *format, // 格式化方式) |5 p9 T7 ~3 u9 U
  6.     const struct tm *timeptr // tm指针
    5 n# \& R; d; l9 U0 k# U
  7. );
复制代码
# N8 z( f" v% w* p( w! K+ r' ~
format格式如下:& P# T5 ~. X# |; J/ G/ A# _
  1. * I) O9 v" {% J
  2. %a 星期几的缩写  _" k. a. ?: N* W; T
  3. %A 星期几的全称
    & f+ B3 `/ [$ k5 k' [" c% L
  4. %b 月份的缩写* F- r2 `. k4 m, A
  5. %B 月份的全称
    5 R! L$ i6 a( [. T
  6. %c 标准的日期的时间串3 |) p( c) ]0 g3 T; S: F
  7. %C 年份的前两位数字
    / H. E# ?% s( g+ W+ v7 u" c8 O
  8. %d 十进制表示的每月的第几天(值从1到31)* p2 v' P& N4 i4 }" A6 ^4 m" g
  9. %D 月/天/年
    4 g* z0 ^3 ?" U3 B) E9 ]4 v
  10. %e 在两字符域中,十进制表示的每月的第几天
    ' @& P0 [4 F# E& S  |' ?
  11. %F 年-月-日  v; ~! F' B, S% d6 p- ~
  12. %g 年份的后两位数字,使用基于周的年
    * |! O+ j% C0 G1 g( [! q
  13. %G 年份,使用基于周的年
    7 P+ d8 A  T  ~1 \3 q- M* q7 k
  14. %h 简写的月份名2 ?- p$ @( N# h; ?
  15. %H 24小时制的小时(值从0到23)2 A! b) [8 y, f4 m5 Y$ h- z' F
  16. %I 12小时制的小时(值从1到12)
    8 j# @/ T' W0 e9 L. F
  17. %j 十进制表示的每年的第几天(值从1到366)
    ! X( W/ f3 m- s+ I; F+ `
  18. %m 十进制表示的月份(值从1到12)* I. e/ k# v5 E8 n' ~7 q2 y
  19. %M 十时制表示的分钟数(值从0到59)) t# Y4 a+ y8 ^* _
  20. %n 换行符. d. E' A" Q. u
  21. %p 本地的AM或PM的等价显示( `* N& A! s& Y* d3 Y; Y& D
  22. %r 12小时的时间
      N, L/ R7 L. ?  s* p8 B
  23. %R 显示小时和分钟:hh:mm
    6 E6 L3 ]/ j2 w) [" S
  24. %S 十进制的秒数(值从0到61)
    : N4 W3 P9 {# E$ Y4 s
  25. %t 水平制表符
    4 c6 w4 r6 R' Y! T' i& X' I
  26. %T 显示时分秒:hh:mm:ss$ P% v' ^1 I: [
  27. %u 每周的第几天,星期一为第一天 (值从1到7,星期一为1)8 k% O, I8 b8 P1 A& S
  28. %U 第年的第几周,把星期日作为第一天(值从0到53)
    ( C% |0 x  V" P! i, _" u
  29. %V 每年的第几周,使用基于周的年( T; a* {+ h! C/ e  `
  30. %w 十进制表示的星期几(值从0到6,星期天为0)
    % n( O' b) f+ |) I
  31. %W 每年的第几周,把星期一做为第一天(值从0到53)" M( w! n: U. O4 C$ |
  32. %x 标准的日期串. j: g4 g/ d& }: r- b
  33. %X 标准的时间串+ g3 z& Z2 J/ d+ Q
  34. %y 不带世纪的十进制年份(值从0到99)$ ~5 l( ~% T2 ]
  35. %Y 带世纪部分的十制年份
    5 U7 T0 {* Z0 C+ f, i
  36. %Z 时区名称,如果不能得到时区名称则返回空字符。/ Q8 \; s( f3 W) ^
  37. %% 一个%符号
复制代码

( L) S! t  W* o" y
使用代码如下:
6 d2 e! X0 i& w- l9 x* z

  1. - w5 y! O, X7 L# a" K! z
  2. void func() {
    " \+ h( P) E! _7 B
  3.     time_t rawtime = time(NULL);" b* O6 p* w+ M# R
  4.     char buf[256];1 a( L) r" |0 L$ v
  5.     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&rawtime));6 w9 Q& y* W+ }9 x: h
  6.     cout << buf << endl;
    ( @  t+ i+ A1 r- d& _
  7. }
复制代码

, n5 m& a4 H9 Y, |3 q7 u2 \
赞 收藏 评论0 发布时间:2020-10-6 22:04

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版