EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
utils_time.cpp
Go to the documentation of this file.
1 /*
2  ------------------------------------------------------------------------------------
3  LICENSE:
4  ------------------------------------------------------------------------------------
5  This file is part of EVEmu: EVE Online Server Emulator
6  Copyright 2006 - 2021 The EVEmu Team
7  For the latest information visit https://evemu.dev
8  ------------------------------------------------------------------------------------
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License along with
19  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21  http://www.gnu.org/copyleft/lesser.txt.
22  ------------------------------------------------------------------------------------
23  Author: Zhur
24  Updates: Allan
25 */
26 
27 #include "eve-core.h"
28 // #include "date.h"
29 
30 #include "utils/utils_time.h"
31 
32 // Number of days in month in normal year
33 static const int daysOfMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
34 
35 static const int64 SECS_BETWEEN_EPOCHS = 11644473600LL;
36 static const int64 SECS_TO_100NS = 10000000L; // 10^7
37 
44 
45 int64 UnixTimeToWin32Time( time_t sec, uint32 nsec ) {
46  return(
48  + (nsec / 100)
49  );
50 }
51 
52 void Win32TimeToUnixTime( int64 win32t, time_t &unix_time, uint32 &nsec ) {
53  win32t -= (SECS_BETWEEN_EPOCHS * SECS_TO_100NS);
54  nsec = (win32t % SECS_TO_100NS) * 100;
55  win32t /= SECS_TO_100NS;
56  unix_time = win32t;
57 }
58 
59 std::string Win32TimeToString(int64 win32t) {
60  std::time_t unix_time;
61  uint32 nsec = 0;
62  Win32TimeToUnixTime(win32t, unix_time, nsec);
63 
64  char buf[256];
65  std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", std::localtime(&unix_time));
66 
67  return buf;
68 }
69 
71  // returns second resolution.
72  return UnixTimeToWin32Time(std::time(NULL), 0);
73 }
74 
75 int32 GetElapsedHours(int64 time) // -allan
76 {
77  double hours = GetFileTimeNow() -time;
78  hours /= SECS_TO_100NS;
79  hours -= SECS_BETWEEN_EPOCHS;
80  hours /= 3600;
81  return (int32)hours;
82 }
83 
84 double GetFileTimeNow() // -allan
85 {
86  // convert system time to filetime.
87  double time = GetTimeMSeconds();
88  time /= 1000; // to second
89  time += SECS_BETWEEN_EPOCHS; // offset
90  time *= EvE::Time::Second; // to 100 uSeconds
91  return time;
92 }
93 
94 // NOTE auto and std::chrono require C++11
95 int64 GetSteadyTime() { // -allan
96  // simulation of Windows GetTickCount()
97  // this returns milliseconds
98  using namespace std::chrono;
99  auto duration = system_clock::now().time_since_epoch(); // return in nanoseconds
100  //int64 time = duration_cast<microseconds>(steady_clock::now().time_since_epoch()).count();
101  return duration_cast<milliseconds>(duration).count();
102 }
103 
104 double GetTimeMSeconds() { // -allan
105  // this returns milliseconds in microsecond resolution
106  using namespace std::chrono;
107  /*
108  auto now = steady_clock::now();
109  duration_cast<microseconds>(steady_clock::now().time_since_epoch()).count();
110  */
111  auto duration = system_clock::now().time_since_epoch(); // return in nanoseconds
112  double time = duration_cast<microseconds>(duration).count();
113  return (time / 1000);
114 }
115 
116 double GetTimeUSeconds() { // -allan
117  // this returns microseconds in nanosecond resolution
118  using namespace std::chrono;
119  auto duration = system_clock::now().time_since_epoch(); // return in nanoseconds
120  double time = duration_cast<nanoseconds>(duration).count();
121  return (time / 1000);
122 }
123 
124 // Get current date/time, format is YYYY-MM-DD.HH:mm:ss
125 const std::string currentDateTime() {
126  time_t now = std::time(0);
127  struct tm tstruct;
128  char buf[80];
129  tstruct = *std::localtime(&now);
130  // Visit http://en.cppreference.com/w/cpp/chrono/c/strftime
131  // for more information about date/time format
132  std::strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct);
133 
134  return buf;
135 }
136 
137 std::string GetUTimeTillNow(double fromTime)
138 {
139  double elapsed = GetTimeUSeconds() - fromTime;
140  if (elapsed > 999999)
141  return sprintf("0.4fs",elapsed / 1000000);
142  else if (elapsed > 999)
143  return sprintf("0.4fms",elapsed / 1000);
144  else
145  return sprintf("0.4fus",elapsed);
146 }
147 
148 std::string GetMTimeTillNow(double fromTime)
149 {
150  double elapsed = GetTimeMSeconds() - fromTime;
151  if (elapsed > 999)
152  return sprintf("0.4fs",elapsed / 1000);
153  else
154  return sprintf("0.4fms",elapsed);
155 }
156 
158 {
159  // time sent as (windows)FILETIME; convert to unix time
160  double time(filetime /EvE::Time::Second);// to Seconds
161  time -= SECS_BETWEEN_EPOCHS; // epoc offset
162 
163  // Calculate total days
164  uint16 day = (time / 86400) +1;
165  uint16 seconds = fmod(time, 86400);
166 
167  // year loop
168  uint16 year = 1970;
169  while (day >= 365) {
170  if ((year % 400 == 0)
171  or ((year % 4 == 0) and (year % 100 != 0))) {
172  day -= 366;
173  } else {
174  day -= 365;
175  }
176  ++year;
177  }
178 
179  bool flag(false);
180  if ((year % 400 == 0)
181  or ((year % 4 == 0) and (year % 100 != 0)))
182  flag = true;
183 
184  // Calculating MONTH and DATE
185  uint8 month(0), index(0);
186  if (flag) {
187  while (true) {
188  if (index == 1) {
189  if (day - 29 < 0)
190  break;
191  ++month;
192  day -= 29;
193  } else {
194  if (day -daysOfMonth[index] < 0)
195  break;
196  ++month;
197  day -= daysOfMonth[index];
198  }
199  ++index;
200  }
201  } else {
202  while (true) {
203  if (day -daysOfMonth[index] < 0)
204  break;
205  day -= daysOfMonth[index];
206  ++month;
207  ++index;
208  }
209  }
210 
211  // Current Month
212  if (day > 0) {
213  ++month;
214  } else {
215  if (month == 2 && flag)
216  day = 29;
217  else {
218  day = daysOfMonth[month - 1];
219  }
220  }
221 
222  // use boost to get day of week and week of year
223  boost::gregorian::date d(year, month, day);
224 
226  data.year = year;
227  data.month = month;
228  data.day = day;
229  data.wn = d.week_number();
230  data.wd = d.day_of_week();
231  data.dy = d.day_of_year();
232  data.hour = seconds / 3600;
233  data.min = fmod(seconds, 3600) / 60;
234  data.sec = fmod(fmod(seconds, 3600), 60);
235  data.ms = fmod(time, 1000);
236 
237  return data;
238 }
239 
240 //FILETIME, a struct which stores the 64-bit number of 100-nanosecond intervals since midnight Jan 1, 1601.
241 
242 
243 /* this doesnt work....std::get_time() is unavailable
244 // Converts UTC time string to a time_t value.
245 std::time_t getEpochTime(const std::wstring& dateTime)
246 {
247  // Let's consider we are getting all the input in
248  // this format: '2014-07-25T20:17:22Z' (T denotes
249  // start of Time part, Z denotes UTC zone).
250  // A better approach would be to pass in the format as well.
251  static const std::wstring dateTimeFormat{ L"%Y-%m-%dT%H:%M:%SZ" };
252 
253  // Create a stream which we will use to parse the string,
254  // which we provide to constructor of stream to fill the buffer.
255  std::wstringstream ss{ dateTime };
256 
257  // Create a tm object to store the parsed date and time.
258  std::tm dt;
259 
260  // Now we read from buffer using get_time manipulator
261  // and formatting the input appropriately.
262  ss >> std::get_time(&dt, dateTimeFormat.c_str());
263 
264  // Convert the tm structure to time_t value and return.
265  return std::mktime(&dt);
266 }
267 */
unsigned __int8 uint8
Definition: eve-compat.h:46
const int64 Win32Time_Year
Definition: utils_time.cpp:43
std::string GetMTimeTillNow(double fromTime)
Definition: utils_time.cpp:148
int64 UnixTimeToWin32Time(time_t sec, uint32 nsec)
Definition: utils_time.cpp:45
std::string sprintf(const char *fmt,...)
sprintf for std::string.
Definition: eve-compat.cpp:106
int64 GetSteadyTime()
Definition: utils_time.cpp:95
signed __int32 int32
Definition: eve-compat.h:49
static const int daysOfMonth[]
Definition: utils_time.cpp:33
const int64 Win32Time_Day
Definition: utils_time.cpp:41
double GetTimeUSeconds()
Definition: utils_time.cpp:116
const int64 Win32Time_Month
Definition: utils_time.cpp:42
int32 GetElapsedHours(int64 time)
Definition: utils_time.cpp:75
const int64 Win32Time_Hour
Definition: utils_time.cpp:40
double GetTimeMSeconds()
Definition: utils_time.cpp:104
const std::string currentDateTime()
Definition: utils_time.cpp:125
static const int64 SECS_TO_100NS
Definition: utils_time.cpp:36
static const int64 SECS_BETWEEN_EPOCHS
Definition: utils_time.cpp:35
int64 Win32TimeNow()
Definition: utils_time.cpp:70
const int64 Win32Time_Second
Definition: utils_time.cpp:38
unsigned __int32 uint32
Definition: eve-compat.h:50
double GetFileTimeNow()
Definition: utils_time.cpp:84
signed __int64 int64
Definition: eve-compat.h:51
EvE::TimeParts GetTimeParts(int64 filetime)
Definition: utils_time.cpp:157
const int64 Win32Time_Minute
Definition: utils_time.cpp:39
std::string Win32TimeToString(int64 win32t)
Definition: utils_time.cpp:59
unsigned __int16 uint16
Definition: eve-compat.h:48
std::string GetUTimeTillNow(double fromTime)
Definition: utils_time.cpp:137
void Win32TimeToUnixTime(int64 win32t, time_t &unix_time, uint32 &nsec)
Definition: utils_time.cpp:52