Console Library 8.0.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
time.h
Go to the documentation of this file.
1
11
12/*
13Copyright (c) 2026 MrXie1109
14
15Permission is hereby granted, free of charge, to any person obtaining a copy
16of this software and associated documentation files (the "Software"), to deal
17in the Software without restriction, including without limitation the rights
18to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19copies of the Software, and to permit persons to whom the Software is
20furnished to do so, subject to the following conditions:
21
22The above copyright notice and this permission notice shall be included in all
23copies or substantial portions of the Software.
24
25THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31SOFTWARE.
32*/
33
34#pragma once
35#include <chrono>
36#include <cstdint>
37#include <ctime>
38#include <iomanip>
39#include <iostream>
40#include <sstream>
41#include <string>
42#include <thread>
43#include <utility>
44
45#include "../core/csexc.h"
46#include "../io/kb.h"
47
48namespace console {
57 class Time {
58 intmax_t ns_;
59
60 public:
65 Time(long long ns = 0) : ns_(ns) {}
66
68 intmax_t count() const { return ns_; }
69
71 operator intmax_t() const { return ns_; }
72
74 double ns() const { return ns_; }
76 double us() const { return ns_ / 1e3; }
78 double ms() const { return ns_ / 1e6; }
80 double s() const { return ns_ / 1e9; }
82 double min() const { return ns_ / 6e10; }
84 double hr() const { return ns_ / 36e11; }
85
92 friend std::ostream &operator<<(std::ostream &os, const Time t) {
93 if (t.ns_ >= 3600000000000LL) return os << t.hr() << "hr";
94 if (t.ns_ >= 60000000000LL) return os << t.min() << "min";
95 if (t.ns_ >= 1000000000LL) return os << t.s() << "s";
96 if (t.ns_ >= 1000000LL) return os << t.ms() << "ms";
97 if (t.ns_ >= 1000LL) return os << t.us() << "μs";
98 return os << t.ns() << "ns";
99 }
100
105 std::string str() const {
106 std::ostringstream os;
107 os << *this;
108 return os.str();
109 }
110
113 friend Time operator+(Time t1, Time t2) { return t1.ns_ + t2.ns_; }
114 friend Time operator-(Time t1, Time t2) { return t1.ns_ - t2.ns_; }
115 Time operator*(double d) const { return ns_ * d; }
116 Time operator/(double d) const { return ns_ / d; }
118
121 friend bool operator==(Time t1, Time t2) { return t1.ns_ == t2.ns_; }
122 friend bool operator!=(Time t1, Time t2) { return t1.ns_ != t2.ns_; }
123 friend bool operator<(Time t1, Time t2) { return t1.ns_ < t2.ns_; }
124 friend bool operator>(Time t1, Time t2) { return t1.ns_ > t2.ns_; }
125 friend bool operator<=(Time t1, Time t2) { return t1.ns_ <= t2.ns_; }
126 friend bool operator>=(Time t1, Time t2) { return t1.ns_ >= t2.ns_; }
128
129 template <class Rep, class Period>
130 friend Time operator+(Time t, std::chrono::duration<Rep, Period> d) {
131 return t
132 + Time(
133 std::chrono::duration_cast<std::chrono::nanoseconds>(d)
134 .count());
135 }
136
137 template <class Rep, class Period>
138 friend Time operator-(Time t, std::chrono::duration<Rep, Period> d) {
139 return t
140 - Time(
141 std::chrono::duration_cast<std::chrono::nanoseconds>(d)
142 .count());
143 }
144 };
145
151 inline Time nanoseconds(double n) {
152 return Time(n);
153 }
154
160 inline Time microseconds(double n) {
161 return Time(n * 1e3);
162 }
163
169 inline Time milliseconds(double n) {
170 return Time(n * 1e6);
171 }
172
178 inline Time seconds(double n) {
179 return Time(n * 1e9);
180 }
181
187 inline Time minutes(double n) {
188 return Time(n * 6e10);
189 }
190
196 inline Time hours(double n) {
197 return Time(n * 3.6e12);
198 }
199
204 inline Time now() {
205 return Time( //
206 std::chrono::duration_cast<std::chrono::nanoseconds>(
207 std::chrono::system_clock::now().time_since_epoch())
208 .count());
209 }
210
216 inline Time operator""_ns(unsigned long long ns) {
217 return Time(ns);
218 }
219
225 inline Time operator""_us(unsigned long long us) {
226 return Time(us * 1e3);
227 }
228
234 inline Time operator""_ms(unsigned long long ms) {
235 return Time(ms * 1e6);
236 }
237
243 inline Time operator""_s(unsigned long long s) {
244 return Time(s * 1e9);
245 }
246
252 inline Time operator""_min(unsigned long long min) {
253 return Time(min * 6e10);
254 }
255
261 inline Time operator""_hr(unsigned long long hr) {
262 return Time(hr * 3.6e12);
263 }
264
270 inline Time operator""_ns(long double ns) {
271 return Time(ns);
272 }
273
279 inline Time operator""_us(long double us) {
280 return Time(us * 1e3);
281 }
282
288 inline Time operator""_ms(long double ms) {
289 return Time(ms * 1e6);
290 }
291
297 inline Time operator""_s(long double s) {
298 return Time(s * 1e9);
299 }
300
306 inline Time operator""_min(long double min) {
307 return Time(min * 6e10);
308 }
309
315 inline Time operator""_hr(long double hr) {
316 return Time(hr * 3.6e12);
317 }
318
327 template <class F, class... Args>
328 inline Time timer(F &&f, Args &&...args) {
329 Time start = now();
330 f(args...);
331 return now() - start;
332 }
333
338 inline void sleep(const Time &tr) {
339 std::this_thread::sleep_for(std::chrono::duration<long double>(tr.s()));
340 }
341
348 inline std::string datetime(const std::string &fmt = "%Y-%m-%d %H:%M:%S") {
349 std::stringstream ss;
350 auto now = std::chrono::system_clock::now();
351 auto time = std::chrono::system_clock::to_time_t(now);
352 std::tm tm_buffer;
353#ifdef _WIN32
354 localtime_s(&tm_buffer, &time);
355#else
356 localtime_r(&time, &tm_buffer);
357#endif
358 ss << std::put_time(&tm_buffer, fmt.c_str());
359 return ss.str();
360 }
361
367 inline double fps(double target) {
368 using namespace std::chrono;
369 thread_local auto last = steady_clock::now(); //于首次调用时初始化
370 std::this_thread::sleep_until(last + duration<double>(1.0 / target));
371 double actual
372 = 1.0 / duration<double>(steady_clock::now() - last).count();
373 last = steady_clock::now();
374 return actual;
375 }
376
377 class DateTime {
378 std::tm tm_{};
379
380 void normalize() {
381 auto time = std::mktime(&tm_);
382 if (time != (std::time_t)-1) {
383#ifdef _WIN32
384 localtime_s(&tm_, &time);
385#else
386 localtime_r(&time, &tm_);
387#endif
388 }
389 }
390
391 public:
393 auto now = std::chrono::system_clock::now();
394 std::time_t time = std::chrono::system_clock::to_time_t(now);
395#ifdef _WIN32
396 localtime_s(&tm_, &time);
397#else
398 localtime_r(&time, &tm_);
399#endif
400 }
401
403 int month,
404 int day,
405 int hour = 0,
406 int minute = 0,
407 int second = 0) {
408 tm_.tm_year = year - 1900;
409 tm_.tm_mon = month - 1;
410 tm_.tm_mday = day;
411 tm_.tm_hour = hour;
412 tm_.tm_min = minute;
413 tm_.tm_sec = second;
414 tm_.tm_isdst = -1;
415 normalize();
416 }
417
418 DateTime(const std::string &str,
419 const std::string &fmt = "%Y-%m-%d %H:%M:%S") {
420 std::istringstream ss(str);
421 ss >> std::get_time(&tm_, fmt.c_str());
422 if (ss.fail()) throw BadFormat("Failed to parse DateTime");
423 }
424
425 DateTime(const std::wstring &str,
426 const std::wstring &fmt = L"%Y-%m-%d %H:%M:%S") {
427 std::wistringstream ss(str);
428 ss >> std::get_time(&tm_, fmt.c_str());
429 if (ss.fail()) throw BadFormat("Failed to parse DateTime");
430 }
431
432 int year() const { return tm_.tm_year + 1900; }
433 int month() const { return tm_.tm_mon + 1; }
434 int day() const { return tm_.tm_mday; }
435 int hour() const { return tm_.tm_hour; }
436 int minute() const { return tm_.tm_min; }
437 int second() const { return tm_.tm_sec; }
438 int weekday() const { return tm_.tm_wday; }
439 int yearday() const { return tm_.tm_yday; }
440 bool isdst() const { return tm_.tm_isdst > 0; }
441
447 static bool is_leap(int y) {
448 return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
449 }
450
451 bool is_leap() const { return is_leap(year()); }
452
459 static int days_in_month(int y, int m) {
460 static const int d[]
461 = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
462 if (m == 2 && is_leap(y)) return 29;
463 return d[m - 1];
464 }
465 int days_in_month() const { return days_in_month(year(), month()); }
466
470 int iso_weekday() const {
471 int w = tm_.tm_wday;
472 return w == 0 ? 7 : w;
473 }
474
479 int iso_week() const {
480 // 取当年 1 月 4 日所在的周一为准
481 DateTime jan4(year(), 1, 4);
482 int dow = jan4.iso_weekday();
483 int week_num = (yearday() - jan4.yearday() + dow + 6) / 7;
484 if (week_num < 1)
485 week_num = DateTime(year() - 1, 12, 31).iso_week();
486 if (week_num > 52 && days_in_month() == 31 && month() == 12
487 && iso_weekday() <= 3)
488 week_num = 1;
489 return week_num;
490 }
491
495 DateTime begin_of_month() const { return DateTime(year(), month(), 1); }
496
501 return DateTime(year(), month(), days_in_month(), 23, 59, 59);
502 }
503
508 return DateTime(year(), month(), day());
509 }
510
515 return DateTime(year(), month(), day(), 23, 59, 59);
516 }
517
521 bool is_weekend() const { return tm_.tm_wday == 0 || tm_.tm_wday == 6; }
522
526 int day_of_year() const { return tm_.tm_yday + 1; }
527
533 std::string str(const std::string &fmt = "%Y-%m-%d %H:%M:%S") const {
534 std::ostringstream ss;
535 ss << std::put_time(&tm_, fmt.c_str());
536 return ss.str();
537 }
538
544 std::wstring
545 wstr(const std::wstring &fmt = L"%Y-%m-%d %H:%M:%S") const {
546 std::wostringstream ss;
547 ss << std::put_time(&tm_, fmt.c_str());
548 return ss.str();
549 }
550
552 std::time_t to_time_t() const {
553 return std::mktime(const_cast<std::tm *>(&tm_));
554 }
555
558
563 std::time_t sec = static_cast<std::time_t>(t.s());
564 auto tt = to_time_t() + sec;
565#ifdef _WIN32
566 localtime_s(&tm_, &tt);
567#else
568 localtime_r(&tt, &tm_);
569#endif
570 return *this;
571 }
572
576 DateTime &operator-=(Time t) { return *this += Time(-t.s() * 1e9); }
577
578 friend DateTime operator+(DateTime dt, Time t) { return dt += t; }
579
580 friend DateTime operator-(DateTime dt, Time t) { return dt -= t; }
581
585 friend Time operator-(const DateTime &lhs, const DateTime &rhs) {
586 return Time(static_cast<long long>(
587 std::difftime(lhs.to_time_t(), rhs.to_time_t()) * 1e9));
588 }
589
591
594 friend bool operator==(const DateTime &lhs, const DateTime &rhs) {
595 return std::difftime(lhs.to_time_t(), rhs.to_time_t()) == 0;
596 }
597 friend bool operator!=(const DateTime &lhs, const DateTime &rhs) {
598 return !(lhs == rhs);
599 }
600 friend bool operator<(const DateTime &lhs, const DateTime &rhs) {
601 return std::difftime(lhs.to_time_t(), rhs.to_time_t()) < 0;
602 }
603 friend bool operator>(const DateTime &lhs, const DateTime &rhs) {
604 return rhs < lhs;
605 }
606 friend bool operator<=(const DateTime &lhs, const DateTime &rhs) {
607 return !(lhs > rhs);
608 }
609 friend bool operator>=(const DateTime &lhs, const DateTime &rhs) {
610 return !(lhs < rhs);
611 }
612
613
617 friend std::ostream &operator<<(std::ostream &os, const DateTime &dt) {
618 return os << dt.str();
619 }
620
624 friend std::wostream &
625 operator<<(std::wostream &os, const DateTime &dt) {
626 return os << dt.wstr();
627 }
628 };
629}
BadFormat(const std::string &msg)
构造 BadFormat。
Definition csexc.h:74
static bool is_leap(int y)
判断是否为闰年。
Definition time.h:447
DateTime end_of_month() const
获取当月最后一天的 DateTime。
Definition time.h:500
int hour() const
Definition time.h:435
int second() const
Definition time.h:437
bool is_weekend() const
判断是否为周末。
Definition time.h:521
bool is_leap() const
Definition time.h:451
DateTime begin_of_day() const
获取当天 00:00:00 的 DateTime。
Definition time.h:507
std::time_t to_time_t() const
转为 std::time_t。
Definition time.h:552
friend std::ostream & operator<<(std::ostream &os, const DateTime &dt)
输出日期时间到流,格式为 "%Y-%m-%d %H:%M:%S"。
Definition time.h:617
friend bool operator>=(const DateTime &lhs, const DateTime &rhs)
Definition time.h:609
DateTime end_of_day() const
获取当天 23:59:59 的 DateTime。
Definition time.h:514
int iso_weekday() const
获取本周第几天(周一=1, ..., 周日=7)。
Definition time.h:470
std::wstring wstr(const std::wstring &fmt=L"%Y-%m-%d %H:%M:%S") const
格式化为宽字符串。
Definition time.h:545
int minute() const
Definition time.h:436
friend DateTime operator-(DateTime dt, Time t)
Definition time.h:580
int day_of_year() const
获取该年中的第几天(1-based)。
Definition time.h:526
int month() const
Definition time.h:433
DateTime & operator-=(Time t)
减少指定秒数。
Definition time.h:576
void normalize()
Definition time.h:380
int yearday() const
Definition time.h:439
static int days_in_month(int y, int m)
获取指定月份的天数。
Definition time.h:459
friend bool operator<=(const DateTime &lhs, const DateTime &rhs)
Definition time.h:606
DateTime begin_of_month() const
获取当月第一天的 DateTime。
Definition time.h:495
DateTime(const std::string &str, const std::string &fmt="%Y-%m-%d %H:%M:%S")
Definition time.h:418
friend DateTime operator+(DateTime dt, Time t)
Definition time.h:578
friend bool operator>(const DateTime &lhs, const DateTime &rhs)
Definition time.h:603
DateTime(int year, int month, int day, int hour=0, int minute=0, int second=0)
Definition time.h:402
int weekday() const
Definition time.h:438
int year() const
Definition time.h:432
std::tm tm_
Definition time.h:378
int day() const
Definition time.h:434
friend bool operator!=(const DateTime &lhs, const DateTime &rhs)
Definition time.h:597
bool isdst() const
Definition time.h:440
std::string str(const std::string &fmt="%Y-%m-%d %H:%M:%S") const
格式化为字符串。
Definition time.h:533
DateTime()
Definition time.h:392
friend bool operator==(const DateTime &lhs, const DateTime &rhs)
Definition time.h:594
int iso_week() const
获取 ISO 8601 周数。
Definition time.h:479
DateTime & operator+=(Time t)
增加指定秒数。
Definition time.h:562
DateTime(const std::wstring &str, const std::wstring &fmt=L"%Y-%m-%d %H:%M:%S")
Definition time.h:425
friend Time operator-(const DateTime &lhs, const DateTime &rhs)
计算两个 DateTime 的时间差。
Definition time.h:585
friend bool operator<(const DateTime &lhs, const DateTime &rhs)
Definition time.h:600
int days_in_month() const
Definition time.h:465
表示以纳秒为单位的时间量,支持单位转换、算术运算和自动选择合适的输出单位。
Definition time.h:57
std::string str() const
将 Time 对象转换为字符串表示。
Definition time.h:105
intmax_t ns_
纳秒数
Definition time.h:58
friend Time operator+(Time t, std::chrono::duration< Rep, Period > d)
Definition time.h:130
friend bool operator>=(Time t1, Time t2)
Definition time.h:126
Time operator/(double d) const
Definition time.h:116
friend bool operator==(Time t1, Time t2)
Definition time.h:121
friend bool operator<(Time t1, Time t2)
Definition time.h:123
double min() const
返回分钟数。
Definition time.h:82
friend Time operator+(Time t1, Time t2)
Definition time.h:113
friend std::ostream & operator<<(std::ostream &os, const Time t)
输出 Time 对象到流,自动选择合适单位。
Definition time.h:92
Time operator*(double d) const
Definition time.h:115
friend bool operator<=(Time t1, Time t2)
Definition time.h:125
friend bool operator!=(Time t1, Time t2)
Definition time.h:122
intmax_t count() const
获取纳秒数。
Definition time.h:68
friend Time operator-(Time t, std::chrono::duration< Rep, Period > d)
Definition time.h:138
friend bool operator>(Time t1, Time t2)
Definition time.h:124
Time(long long ns=0)
构造一个 Time 对象。
Definition time.h:65
double s() const
返回秒数。
Definition time.h:80
double ms() const
返回毫秒数。
Definition time.h:78
double ns() const
返回纳秒数。
Definition time.h:74
friend Time operator-(Time t1, Time t2)
Definition time.h:114
double us() const
返回微秒数。
Definition time.h:76
double hr() const
返回小时数。
Definition time.h:84
定义 console 库使用的自定义异常类层次结构。
非阻塞的获取键盘的按键输入。
本库所有组件所在的顶层命名空间。
void sleep(const Time &tr)
休眠指定时间。
Definition time.h:338
Time nanoseconds(double n)
静态函数,构造纳秒。
Definition time.h:151
T min(const MultiArray< T, Dims... > &a)
求最小值。
Definition multiarray.h:1676
Time milliseconds(double n)
静态函数,构造毫秒。
Definition time.h:169
Time seconds(double n)
静态函数,构造秒。
Definition time.h:178
Time minutes(double n)
静态函数,构造分钟。
Definition time.h:187
Time hours(double n)
静态函数,构造小时。
Definition time.h:196
std::string datetime(const std::string &fmt="%Y-%m-%d %H:%M:%S")
获取当前日期时间字符串。
Definition time.h:348
Time timer(F &&f, Args &&...args)
测量函数调用的执行时间。
Definition time.h:328
Time now()
获取当前时间点(自纪元以来的纳秒数)。
Definition time.h:204
Time microseconds(double n)
静态函数,构造微秒。
Definition time.h:160
double fps(double target)
控制循环的帧率。
Definition time.h:367