timer.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <ctime>
  5. #include <fmt/format.h>
  6. #include "common/common_types.h"
  7. #include "common/string_util.h"
  8. #include "common/timer.h"
  9. namespace Common {
  10. std::chrono::milliseconds Timer::GetTimeMs() {
  11. return std::chrono::duration_cast<std::chrono::milliseconds>(
  12. std::chrono::system_clock::now().time_since_epoch());
  13. }
  14. // --------------------------------------------
  15. // Initiate, Start, Stop, and Update the time
  16. // --------------------------------------------
  17. // Set initial values for the class
  18. Timer::Timer() : m_LastTime(0), m_StartTime(0), m_Running(false) {
  19. Update();
  20. }
  21. // Write the starting time
  22. void Timer::Start() {
  23. m_StartTime = GetTimeMs();
  24. m_Running = true;
  25. }
  26. // Stop the timer
  27. void Timer::Stop() {
  28. // Write the final time
  29. m_LastTime = GetTimeMs();
  30. m_Running = false;
  31. }
  32. // Update the last time variable
  33. void Timer::Update() {
  34. m_LastTime = GetTimeMs();
  35. // TODO(ector) - QPF
  36. }
  37. // -------------------------------------
  38. // Get time difference and elapsed time
  39. // -------------------------------------
  40. // Get the number of milliseconds since the last Update()
  41. std::chrono::milliseconds Timer::GetTimeDifference() {
  42. return GetTimeMs() - m_LastTime;
  43. }
  44. // Add the time difference since the last Update() to the starting time.
  45. // This is used to compensate for a paused game.
  46. void Timer::AddTimeDifference() {
  47. m_StartTime += GetTimeDifference();
  48. }
  49. // Get the time elapsed since the Start()
  50. std::chrono::milliseconds Timer::GetTimeElapsed() {
  51. // If we have not started yet, return 1 (because then I don't
  52. // have to change the FPS calculation in CoreRerecording.cpp .
  53. if (m_StartTime.count() == 0)
  54. return std::chrono::milliseconds(1);
  55. // Return the final timer time if the timer is stopped
  56. if (!m_Running)
  57. return (m_LastTime - m_StartTime);
  58. return (GetTimeMs() - m_StartTime);
  59. }
  60. // Get the formatted time elapsed since the Start()
  61. std::string Timer::GetTimeElapsedFormatted() const {
  62. // If we have not started yet, return zero
  63. if (m_StartTime.count() == 0)
  64. return "00:00:00:000";
  65. // The number of milliseconds since the start.
  66. // Use a different value if the timer is stopped.
  67. std::chrono::milliseconds Milliseconds;
  68. if (m_Running)
  69. Milliseconds = GetTimeMs() - m_StartTime;
  70. else
  71. Milliseconds = m_LastTime - m_StartTime;
  72. // Seconds
  73. std::chrono::seconds Seconds = std::chrono::duration_cast<std::chrono::seconds>(Milliseconds);
  74. // Minutes
  75. std::chrono::minutes Minutes = std::chrono::duration_cast<std::chrono::minutes>(Milliseconds);
  76. // Hours
  77. std::chrono::hours Hours = std::chrono::duration_cast<std::chrono::hours>(Milliseconds);
  78. std::string TmpStr = fmt::format("{:02}:{:02}:{:02}:{:03}", Hours.count(), Minutes.count() % 60,
  79. Seconds.count() % 60, Milliseconds.count() % 1000);
  80. return TmpStr;
  81. }
  82. // Get the number of seconds since January 1 1970
  83. std::chrono::seconds Timer::GetTimeSinceJan1970() {
  84. return std::chrono::duration_cast<std::chrono::seconds>(GetTimeMs());
  85. }
  86. std::chrono::seconds Timer::GetLocalTimeSinceJan1970() {
  87. time_t sysTime, tzDiff, tzDST;
  88. struct tm* gmTime;
  89. time(&sysTime);
  90. // Account for DST where needed
  91. gmTime = localtime(&sysTime);
  92. if (gmTime->tm_isdst == 1)
  93. tzDST = 3600;
  94. else
  95. tzDST = 0;
  96. // Lazy way to get local time in sec
  97. gmTime = gmtime(&sysTime);
  98. tzDiff = sysTime - mktime(gmTime);
  99. return std::chrono::seconds(sysTime + tzDiff + tzDST);
  100. }
  101. // Return the current time formatted as Minutes:Seconds:Milliseconds
  102. // in the form 00:00:000.
  103. std::string Timer::GetTimeFormatted() {
  104. time_t sysTime;
  105. struct tm* gmTime;
  106. char tmp[13];
  107. time(&sysTime);
  108. gmTime = localtime(&sysTime);
  109. strftime(tmp, 6, "%M:%S", gmTime);
  110. u64 milliseconds = static_cast<u64>(GetTimeMs().count()) % 1000;
  111. return fmt::format("{}:{:03}", tmp, milliseconds);
  112. }
  113. // Returns a timestamp with decimals for precise time comparisons
  114. // ----------------
  115. double Timer::GetDoubleTime() {
  116. // Get continuous timestamp
  117. u64 TmpSeconds = static_cast<u64>(Common::Timer::GetTimeSinceJan1970().count());
  118. double ms = static_cast<u64>(GetTimeMs().count()) % 1000;
  119. // Remove a few years. We only really want enough seconds to make
  120. // sure that we are detecting actual actions, perhaps 60 seconds is
  121. // enough really, but I leave a year of seconds anyway, in case the
  122. // user's clock is incorrect or something like that.
  123. TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60);
  124. // Make a smaller integer that fits in the double
  125. u32 Seconds = static_cast<u32>(TmpSeconds);
  126. double TmpTime = Seconds + ms;
  127. return TmpTime;
  128. }
  129. } // Namespace Common