Timestamp.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. //
  2. // Timestamp.cpp
  3. //
  4. // Library: Foundation
  5. // Package: DateTime
  6. // Module: Timestamp
  7. //
  8. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  9. // and Contributors.
  10. //
  11. // SPDX-License-Identifier: BSL-1.0
  12. //
  13. #include "Poco/Timestamp.h"
  14. #include "Poco/Timespan.h"
  15. #include "Poco/Exception.h"
  16. #include <algorithm>
  17. #undef min
  18. #undef max
  19. #include <limits>
  20. #if defined(POCO_OS_FAMILY_UNIX)
  21. #include <time.h>
  22. #include <unistd.h>
  23. #if defined(POCO_VXWORKS)
  24. #include <timers.h>
  25. #else
  26. #include <sys/time.h>
  27. #include <sys/times.h>
  28. #endif
  29. #elif defined(POCO_OS_FAMILY_WINDOWS)
  30. #include "Poco/UnWindows.h"
  31. #endif
  32. #ifndef POCO_HAVE_CLOCK_GETTIME
  33. #if (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) || defined(__QNX__)
  34. #ifndef __APPLE__ // See GitHub issue #1453 - not available before Mac OS 10.12/iOS 10
  35. #define POCO_HAVE_CLOCK_GETTIME
  36. #endif
  37. #endif
  38. #endif
  39. namespace Poco {
  40. const Timestamp::TimeVal Timestamp::TIMEVAL_MIN = std::numeric_limits<Timestamp::TimeVal>::min();
  41. const Timestamp::TimeVal Timestamp::TIMEVAL_MAX = std::numeric_limits<Timestamp::TimeVal>::max();
  42. Timestamp::Timestamp()
  43. {
  44. update();
  45. }
  46. Timestamp::Timestamp(TimeVal tv)
  47. {
  48. _ts = tv;
  49. }
  50. Timestamp::Timestamp(const Timestamp& other)
  51. {
  52. _ts = other._ts;
  53. }
  54. Timestamp::~Timestamp()
  55. {
  56. }
  57. Timestamp& Timestamp::operator = (const Timestamp& other)
  58. {
  59. _ts = other._ts;
  60. return *this;
  61. }
  62. Timestamp& Timestamp::operator = (TimeVal tv)
  63. {
  64. _ts = tv;
  65. return *this;
  66. }
  67. void Timestamp::swap(Timestamp& timestamp) noexcept
  68. {
  69. std::swap(_ts, timestamp._ts);
  70. }
  71. Timestamp Timestamp::fromEpochTime(std::time_t t)
  72. {
  73. return Timestamp(TimeVal(t)*resolution());
  74. }
  75. Timestamp Timestamp::fromUtcTime(UtcTimeVal val)
  76. {
  77. val -= (TimeDiff(0x01b21dd2) << 32) + 0x13814000;
  78. val /= 10;
  79. return Timestamp(val);
  80. }
  81. void Timestamp::update()
  82. {
  83. #if defined(POCO_OS_FAMILY_WINDOWS)
  84. FILETIME ft;
  85. GetSystemTimeAsFileTime(&ft);
  86. ULARGE_INTEGER epoch; // UNIX epoch (1970-01-01 00:00:00) expressed in Windows NT FILETIME
  87. epoch.LowPart = 0xD53E8000;
  88. epoch.HighPart = 0x019DB1DE;
  89. ULARGE_INTEGER ts;
  90. ts.LowPart = ft.dwLowDateTime;
  91. ts.HighPart = ft.dwHighDateTime;
  92. ts.QuadPart -= epoch.QuadPart;
  93. _ts = ts.QuadPart/10;
  94. #elif defined(POCO_HAVE_CLOCK_GETTIME)
  95. struct timespec ts;
  96. if (clock_gettime(CLOCK_REALTIME, &ts))
  97. throw SystemException("cannot get time of day");
  98. _ts = TimeVal(ts.tv_sec)*resolution() + ts.tv_nsec/1000;
  99. #else
  100. struct timeval tv;
  101. if (gettimeofday(&tv, NULL))
  102. throw SystemException("cannot get time of day");
  103. _ts = TimeVal(tv.tv_sec)*resolution() + tv.tv_usec;
  104. #endif
  105. }
  106. Timestamp Timestamp::operator + (const Timespan& span) const
  107. {
  108. return *this + span.totalMicroseconds();
  109. }
  110. Timestamp Timestamp::operator - (const Timespan& span) const
  111. {
  112. return *this - span.totalMicroseconds();
  113. }
  114. Timestamp& Timestamp::operator += (const Timespan& span)
  115. {
  116. return *this += span.totalMicroseconds();
  117. }
  118. Timestamp& Timestamp::operator -= (const Timespan& span)
  119. {
  120. return *this -= span.totalMicroseconds();
  121. }
  122. #if defined(_WIN32)
  123. Timestamp Timestamp::fromFileTimeNP(UInt32 fileTimeLow, UInt32 fileTimeHigh)
  124. {
  125. ULARGE_INTEGER epoch; // UNIX epoch (1970-01-01 00:00:00) expressed in Windows NT FILETIME
  126. epoch.LowPart = 0xD53E8000;
  127. epoch.HighPart = 0x019DB1DE;
  128. ULARGE_INTEGER ts;
  129. ts.LowPart = fileTimeLow;
  130. ts.HighPart = fileTimeHigh;
  131. ts.QuadPart -= epoch.QuadPart;
  132. return Timestamp(ts.QuadPart/10);
  133. }
  134. void Timestamp::toFileTimeNP(UInt32& fileTimeLow, UInt32& fileTimeHigh) const
  135. {
  136. ULARGE_INTEGER epoch; // UNIX epoch (1970-01-01 00:00:00) expressed in Windows NT FILETIME
  137. epoch.LowPart = 0xD53E8000;
  138. epoch.HighPart = 0x019DB1DE;
  139. ULARGE_INTEGER ts;
  140. ts.QuadPart = _ts*10;
  141. ts.QuadPart += epoch.QuadPart;
  142. fileTimeLow = ts.LowPart;
  143. fileTimeHigh = ts.HighPart;
  144. }
  145. #endif
  146. } // namespace Poco