time_utils.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "common/time_utils.hpp"
  2. #include <iomanip>
  3. #include <sstream>
  4. #include <iostream>
  5. namespace smartbotic::common {
  6. int64_t TimeUtils::documentStamp(const nlohmann::json& document, const char* key) {
  7. if (!document.contains(key) || !document[key].is_number()) return 0;
  8. const int64_t value = document[key].get<int64_t>();
  9. if (value <= 0) return 0;
  10. constexpr int64_t kNanosecondThreshold = 100000000000000LL; // year 5138 in ms
  11. return value > kNanosecondThreshold ? value / 1000000 : value;
  12. }
  13. int64_t TimeUtils::nowMs() {
  14. return std::chrono::duration_cast<std::chrono::milliseconds>(
  15. Clock::now().time_since_epoch()
  16. ).count();
  17. }
  18. int64_t TimeUtils::nowSec() {
  19. return std::chrono::duration_cast<std::chrono::seconds>(
  20. Clock::now().time_since_epoch()
  21. ).count();
  22. }
  23. TimeUtils::TimePoint TimeUtils::now() {
  24. return Clock::now();
  25. }
  26. TimeUtils::TimePoint TimeUtils::fromMs(int64_t ms) {
  27. return TimePoint(std::chrono::milliseconds(ms));
  28. }
  29. int64_t TimeUtils::toMs(TimePoint tp) {
  30. return std::chrono::duration_cast<std::chrono::milliseconds>(
  31. tp.time_since_epoch()
  32. ).count();
  33. }
  34. std::string TimeUtils::toIso8601(int64_t ms) {
  35. return toIso8601(fromMs(ms));
  36. }
  37. std::string TimeUtils::toIso8601(TimePoint tp) {
  38. auto time = Clock::to_time_t(tp);
  39. auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
  40. tp.time_since_epoch()
  41. ).count() % 1000;
  42. std::tm tm{};
  43. gmtime_r(&time, &tm);
  44. std::ostringstream ss;
  45. ss << std::put_time(&tm, "%Y-%m-%dT%H:%M:%S")
  46. << '.' << std::setfill('0') << std::setw(3) << ms << 'Z';
  47. return ss.str();
  48. }
  49. int64_t TimeUtils::parseIso8601(const std::string& str) {
  50. std::tm tm{};
  51. int ms = 0;
  52. std::istringstream ss(str);
  53. ss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S");
  54. if (ss.peek() == '.') {
  55. ss.ignore();
  56. ss >> ms;
  57. }
  58. auto time = timegm(&tm);
  59. return static_cast<int64_t>(time) * 1000 + ms;
  60. }
  61. bool TimeUtils::isExpired(int64_t expiryMs) {
  62. return nowMs() > expiryMs;
  63. }
  64. bool TimeUtils::isExpired(TimePoint expiry) {
  65. return now() > expiry;
  66. }
  67. int64_t TimeUtils::addMs(int64_t timestampMs, int64_t durationMs) {
  68. return timestampMs + durationMs;
  69. }
  70. int64_t TimeUtils::addSec(int64_t timestampMs, int64_t durationSec) {
  71. return timestampMs + (durationSec * 1000);
  72. }
  73. // ScopedTimer implementation
  74. ScopedTimer::ScopedTimer(const std::string& name)
  75. : name_(name), start_(TimeUtils::now()) {}
  76. ScopedTimer::~ScopedTimer() {
  77. if (!name_.empty()) {
  78. std::cout << "[Timer] " << name_ << ": " << elapsedMs() << "ms" << std::endl;
  79. }
  80. }
  81. int64_t ScopedTimer::elapsedMs() const {
  82. return TimeUtils::toMs(TimeUtils::now()) - TimeUtils::toMs(start_);
  83. }
  84. void ScopedTimer::reset() {
  85. start_ = TimeUtils::now();
  86. }
  87. } // namespace smartbotic::common