Euphoria
datetime.cc
Go to the documentation of this file.
1 #include "core/datetime.h"
2 
3 
4 #include <cstring>
5 
6 #include "assert/assert.h"
7 #include "base/cint.h"
8 
9 
10 #ifdef _WIN32
11 #define timegm _mkgmtime
12 #endif
13 
14 
15 namespace eu::core
16 {
17 
18  int
20  {
21  return static_cast<int>(month);
22  }
23 
24 
25  Month
27  {
29  return static_cast<Month>(m);
30  }
31 
32 
34 
35 
37  : time(atime)
38  {
39  }
40 
41 
44  {
45  struct tm tt = dt.time;
46  return TimetWrapper(mktime(&tt));
47  }
48 
49 
52  {
53  // http://stackoverflow.com/questions/283166/easy-way-to-convert-a-struct-tm-expressed-in-utc-to-time-t-type
54  struct tm tt = dt.time;
55  return TimetWrapper(timegm(&tt));
56  }
57 
60  {
61  return TimetWrapper(::time(nullptr));
62  }
63 
64 
65  double
67  {
68  return difftime(end.time, start.time);
69  }
70 
71 
74  {
75  return StructTmWrapper(*localtime(&time));
76  }
77 
78 
81  {
82  return StructTmWrapper(*gmtime(&time));
83  }
84 
85 
87 
88 
90  : time(t)
91  {
92  }
93 
94 
95  StructTmWrapper::StructTmWrapper(int year, Month month, int day)
96  : time()
97  {
98  std::memset(&time, 0, sizeof(struct tm));
99  set_year(year);
100  set_month(month);
101  set_day_of_moth(day);
102  set_hour(12);
103  set_minutes(0);
104  set_seconds(0);
105  }
106 
107 
108  StructTmWrapper::StructTmWrapper(int year, Month month, int day, int hour, int minute, int second, bool dst)
109  : time()
110  {
111  memset(&time, 0, sizeof(struct tm));
112  set_year(year);
113  set_month(month);
114  set_day_of_moth(day);
115  set_hour(hour);
116  set_minutes(minute);
117  set_seconds(second);
119  }
120 
121 
122  void
124  {
125  time.tm_sec = seconds;
126  }
127 
128 
129  void
131  {
132  time.tm_min = minutes;
133  }
134 
135 
136  void
138  {
139  time.tm_hour = hour;
140  }
141 
142 
143  void
145  {
146  time.tm_mday = day_of_moth;
147  }
148 
149 
150  void
152  {
153  time.tm_mon = c_month_to_int(month);
154  }
155 
156 
157  void
159  {
160  time.tm_year = year - 1900;
161  }
162 
163 
164  void
166  {
167  switch (dst)
168  {
169  case DstInfo::in_effect:
170  time.tm_isdst = 1;
171  return;
173  time.tm_isdst = 0;
174  return;
176  time.tm_isdst = -1;
177  return;
178  }
179 
180  DIE("unhandled dst value switch");
181  }
182 
183 
184  int
186  {
187  return time.tm_sec;
188  }
189 
190 
191  int
193  {
194  return time.tm_min;
195  }
196 
197 
199  {
200  return time.tm_hour;
201  }
202 
203 
204  int
206  {
207  return time.tm_mday;
208  }
209 
210 
211  Month
213  {
214  return c_int_to_month(time.tm_mon);
215  }
216 
217 
219  {
220  return time.tm_year + 1900;
221  }
222 
223 
224  DstInfo
226  {
227  if (time.tm_isdst == 0)
228  {
229  return DstInfo::not_in_effect;
230  }
231  else if (time.tm_isdst > 0)
232  {
233  return DstInfo::in_effect;
234  }
235  else
236  {
238  }
239  }
240 
241 
242  std::string
244  {
245  std::vector<char> ret;
246  const size_t base_size = 100;
247  // todo(Gustav): replace this weirdness with something without a loop
248  for (int try_index = 1; try_index < 100; ++try_index)
249  {
250  const size_t string_length = base_size * try_index;
251  ret.resize(string_length);
252 
253  constexpr const char* const format = "%Y-%m-%d %H:%M:%S";
254  const auto characters_written = strftime(ret.data(), string_length, format, &time);
255 
256  if (characters_written != 0)
257  {
258  return ret.data();
259  }
260  }
261 
262  return "";
263  }
264 
265 
266  /*
267  tm_sec int seconds after the minute 0 - 60
268  tm_min int minutes after the hour 0 - 59
269  tm_hour int hours since midnight 0 - 23
270  tm_mday int day of the month 1 - 31
271  tm_mon int months since January 0 - 11
272  tm_year int years since 1900+
273  tm_isdst int Daylight Saving Time flag
274 
275  The values of the members tm_wday and tm_yday of timeptr are ignored, and the values
276  of the other members are interpreted even if out of their valid ranges(see struct tm).
277 
278  tm_wday int days since Sunday 0 - 6
279  tm_yday int days since January 1 0 - 365
280  */
281 
283  {
284  const auto diff = TimetWrapper::get_difference
285  (
287  dt
288  );
289  return static_cast<U64>(diff);
290  }
291 
292 
294  {
295  const int actual_seconds = c_u64_to_int(total_seconds % 60);
296  const U64 total_minutes = (total_seconds - (total_seconds % 60)) / 60;
297  const U64 total_hours = (total_minutes - (total_minutes % 60)) / 60;
298  const int acutal_minutes = c_u64_to_int(total_minutes % 60);
299 
301  (
303  (
304  1970,
306  1,
307  c_u64_to_int(total_hours),
308  acutal_minutes,
309  actual_seconds
310  )
311  );
312  }
313 
314 
316 
317 
318  DateTime
319  DateTime::create_from_date(int year, core::Month month, int day, TimeZone timezone)
320  {
321  return {timezone, StructTmWrapper(year, month, day)};
322  }
323 
324 
325  DateTime
326  DateTime::create_from_date_and_time(int year, core::Month month, int day, int hour, int minute, int second, TimeZone timezone)
327  {
328  return {timezone, StructTmWrapper(year, month, day, hour, minute, second)};
329  }
330 
331 
332  DateTime
334  {
335  return {timezone, TimetWrapper::from_current_time()};
336  }
337 
338 
339  std::string
341  {
342  return as_struct().to_debug_string();
343  }
344 
345 
346  void
348  {
349  auto s = as_struct();
350  s.set_seconds(seconds);
351  update_time(s);
352  }
353 
354 
355  void
357  {
358  auto s = as_struct();
359  s.set_minutes(minutes);
360  update_time(s);
361  }
362 
363 
364  void
366  {
367  auto s = as_struct();
368  s.set_hour(hour);
369  update_time(s);
370  }
371 
372 
373  void
374  DateTime::set_day_of_moth(int day_of_moth)
375  {
376  auto s = as_struct();
377  s.set_day_of_moth(day_of_moth);
378  update_time(s);
379  }
380 
381 
382  void
384  {
385  auto s = as_struct();
386  s.set_month(month);
387  update_time(s);
388  }
389 
390 
391  void
393  {
394  auto s = as_struct();
395  s.set_year(year);
396  update_time(s);
397  }
398 
399 
400  void
402  {
403  auto s = as_struct();
404  s.set_dst(dst);
405  update_time(s);
406  }
407 
408 
409  int
411  {
412  return as_struct().get_seconds();
413  }
414 
415 
416  int
418  {
419  return as_struct().get_minutes();
420  }
421 
422 
423  int
425  {
426  return as_struct().get_hour();
427  }
428 
429 
430  int
432  {
433  return as_struct().get_day_of_moth();
434  }
435 
436 
437  Month
439  {
440  return as_struct().get_month();
441  }
442 
443 
444  int
446  {
447  return as_struct().get_year();
448  }
449 
450 
451  DstInfo
453  {
454  return as_struct().get_dst();
455  }
456 
457 
458  TimeZone
460  {
461  return timezone;
462  }
463 
464 
467  {
468  return time;
469  }
470 
471 
474  {
475  switch (timezone)
476  {
477  case TimeZone::gmt:
478  return TimetWrapper::from_gmt(s);
479  case TimeZone::local:
481  }
482 
483  DIE("Invalid timezone");
484  return TimetWrapper::from_gmt(s);
485  }
486 
487 
488  DateTime::DateTime(TimeZone atimezone, const StructTmWrapper& wrapped_time)
489  : timezone(atimezone)
490  , time(to_time_t_wrapper(wrapped_time, timezone))
491  {
492  }
493 
494 
495  DateTime::DateTime(TimeZone atimezone, const TimetWrapper& atime)
496  : timezone(atimezone)
497  , time(atime)
498  {
499  }
500 
501 
502  StructTmWrapper
503  DateTime::as_struct() const
504  {
505  switch (timezone)
506  {
507  case TimeZone::gmt:
508  return time.to_gmt();
509  case TimeZone::local:
510  return time.to_local_time();
511  }
512 
513  DIE("Invalid timezone");
514  return time.to_gmt();
515  }
516 
517 
518  void DateTime::update_time(const StructTmWrapper& s)
519  {
520  time = to_time_t_wrapper(s, timezone);
521  }
522 
523 
524 }
#define ASSERT(x)
Definition: assert.h:29
#define DIE(message)
Definition: assert.h:67
Month c_int_to_month(int m)
Definition: datetime.cc:26
TimetWrapper c_int64_to_date_time(U64 total_seconds)
Definition: datetime.cc:293
TimetWrapper to_time_t_wrapper(const StructTmWrapper &s, TimeZone timezone)
Definition: datetime.cc:473
U64 c_date_time_to_int64(const TimetWrapper &dt)
Definition: datetime.cc:282
int c_month_to_int(Month month)
Definition: datetime.cc:19
int c_u64_to_int(U64 u)
Definition: cint.cc:49
std::uint64_t U64
Definition: ints.h:12
TimetWrapper get_time() const
Definition: datetime.cc:466
void set_month(core::Month month)
Definition: datetime.cc:383
void set_hour(int hour)
Definition: datetime.cc:365
static DateTime create_from_date_and_time(int year, core::Month month, int day, int hour, int minute, int second, TimeZone timezone=TimeZone::local)
Definition: datetime.cc:326
int get_hour() const
Definition: datetime.cc:424
std::string to_debug_string() const
Definition: datetime.cc:340
void set_seconds(int seconds)
Definition: datetime.cc:347
int get_year() const
Definition: datetime.cc:445
void set_minutes(int minutes)
Definition: datetime.cc:356
static DateTime create_from_current_time(TimeZone timezone=TimeZone::local)
Definition: datetime.cc:333
void set_year(int year)
Definition: datetime.cc:392
int get_minutes() const
Definition: datetime.cc:417
static DateTime create_from_date(int year, core::Month month, int day, TimeZone timezone=TimeZone::local)
Definition: datetime.cc:319
void set_day_of_moth(int day_of_moth)
Definition: datetime.cc:374
DstInfo get_dst() const
Definition: datetime.cc:452
Month get_month() const
Definition: datetime.cc:438
void set_dst(DstInfo dst)
Definition: datetime.cc:401
int get_day_of_month() const
Definition: datetime.cc:431
int get_seconds() const
Definition: datetime.cc:410
TimeZone get_timezone() const
Definition: datetime.cc:459
DstInfo get_dst() const
Definition: datetime.cc:225
void set_seconds(int seconds)
Definition: datetime.cc:123
Month get_month() const
Definition: datetime.cc:212
void set_year(int year)
Definition: datetime.cc:158
void set_hour(int hour)
Definition: datetime.cc:137
void set_month(core::Month month)
Definition: datetime.cc:151
void set_day_of_moth(int day_of_moth)
Definition: datetime.cc:144
void set_dst(DstInfo dst)
Definition: datetime.cc:165
std::string to_debug_string() const
Definition: datetime.cc:243
void set_minutes(int minutes)
Definition: datetime.cc:130
StructTmWrapper(struct tm time)
Definition: datetime.cc:89
int get_day_of_moth() const
Definition: datetime.cc:205
StructTmWrapper to_local_time() const
Definition: datetime.cc:73
static TimetWrapper from_current_time()
Definition: datetime.cc:59
static TimetWrapper from_local_time(const StructTmWrapper &dt)
Definition: datetime.cc:43
static TimetWrapper from_gmt(const StructTmWrapper &dt)
Definition: datetime.cc:51
static double get_difference(const TimetWrapper &start, const TimetWrapper &end)
Definition: datetime.cc:66
TimetWrapper(time_t time)
Definition: datetime.cc:36
StructTmWrapper to_gmt() const
Definition: datetime.cc:80