CppCommon  1.0.4.1
C++ Common Library
time.cpp
Go to the documentation of this file.
1 
9 #include "time/time.h"
10 
11 #include "string/format.h"
12 
13 #include <cassert>
14 
15 #include <time.h>
16 
17 namespace CppCommon {
18 
19 Time::Time(const Timestamp& timestamp)
20 {
21  struct tm result;
22  time_t seconds = timestamp.seconds();
23 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
24  if (gmtime_r(&seconds, &result) != &result)
25  throwex SystemException(format("Cannot convert the given timestamp ({}) to date & time structure!", timestamp.total()));
26 #elif defined(_WIN32) || defined(_WIN64)
27  if (gmtime_s(&result, &seconds))
28  throwex SystemException(format("Cannot convert the given timestamp ({}) to date & time structure!", timestamp.total()));
29 #endif
30  _year = result.tm_year + 1900;
31  _month = result.tm_mon + 1;
32  _weekday = result.tm_wday;
33  _day = result.tm_mday;
34  _hour = result.tm_hour;
35  _minute = result.tm_min;
36  _second = result.tm_sec % 60;
37  _millisecond = timestamp.milliseconds() % 1000;
38  _microsecond = timestamp.microseconds() % 1000;
39  _nanosecond = timestamp.nanoseconds() % 1000;
40 }
41 
42 Time::Time(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond)
43 {
44 #if defined(_MSC_VER)
45 #pragma warning(push)
46 #pragma warning(disable: 4127) // C4127: conditional expression is constant
47 #endif
48  if (sizeof(time_t) == 4)
49  {
50  assert(((year >= 1970) && (year <= 2038)) && "Year value is limited in range from 1970 to 2038!");
51  if ((year < 1970) || (year > 2038))
52  throwex ArgumentException("Year value is limited in range from 1970 to 2038!");
53  }
54  else
55  {
56  assert(((year >= 1970) && (year <= 3000)) && "Year value is limited in range from 1970 to 3000!");
57  if ((year < 1970) || (year > 3000))
58  throwex ArgumentException("Year value is limited in range from 1970 to 3000!");
59  }
60 #if defined(_MSC_VER)
61 #pragma warning(pop)
62 #endif
63  assert(((month >= 1) && (month <= 12)) && "Month value is limited in range from 1 to 12!");
64  if ((month < 1) || (month > 12))
65  throwex ArgumentException("Month value is limited in range from 1 to 12!");
66  assert(((day >= 1) && (day <= 31)) && "Day value is limited in range from 1 to 31!");
67  if ((day < 1) || (day > 31))
68  throwex ArgumentException("Day value is limited in range from 1 to 31!");
69  assert(((hour >= 0) && (hour <= 23)) && "Hour value is limited in range from 0 to 23!");
70  if ((hour < 0) || (hour > 23))
71  throwex ArgumentException("Hour value is limited in range from 0 to 23!");
72  assert(((minute >= 0) && (minute <= 59)) && "Minute value is limited in range from 0 to 59!");
73  if ((minute < 0) || (minute > 59))
74  throwex ArgumentException("Minute value is limited in range from 0 to 59!");
75  assert(((second >= 0) && (second <= 59)) && "Second value is limited in range from 0 to 59!");
76  if ((second < 0) || (second > 59))
77  throwex ArgumentException("Second value is limited in range from 0 to 59!");
78  assert(((millisecond >= 0) && (millisecond <= 999)) && "Millisecond value is limited in range from 0 to 999!");
79  if ((millisecond < 0) || (millisecond > 999))
80  throwex ArgumentException("Millisecond value is limited in range from 0 to 999!");
81  assert(((microsecond >= 0) && (microsecond <= 999)) && "Microsecond value is limited in range from 0 to 999!");
82  if ((microsecond < 0) || (microsecond > 999))
83  throwex ArgumentException("Microsecond value is limited in range from 0 to 999!");
84  assert(((nanosecond >= 0) && (nanosecond <= 999)) && "Nanosecond value is limited in range from 0 to 999!");
85  if ((nanosecond < 0) || (nanosecond > 999))
86  throwex ArgumentException("Nanosecond value is limited in range from 0 to 999!");
87 
88  _year = year;
89  _month = month;
90  _weekday = 0;
91  _day = day;
92  _hour = hour;
93  _minute = minute;
94  _second = second;
98 }
99 
101 {
102  struct tm result;
103  result.tm_year = _year - 1900;
104  result.tm_mon = _month - 1;
105  result.tm_mday = _day;
106  result.tm_hour = _hour;
107  result.tm_min = _minute;
108  result.tm_sec = _second;
109  result.tm_isdst = -1;
110 
111 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
112  time_t seconds = timegm(&result);
113 #elif defined(_WIN32) || defined(_WIN64)
114  time_t seconds = _mkgmtime(&result);
115 #endif
116  if (seconds == -1)
117  throwex SystemException("Cannot convert date & time to UTC timestamp!");
118 
119  return UtcTimestamp(seconds * 1000000000ull + _millisecond * 1000000ull + _microsecond * 1000ull + _nanosecond);
120 }
121 
123 {
124  struct tm result;
125  result.tm_year = _year - 1900;
126  result.tm_mon = _month - 1;
127  result.tm_mday = _day;
128  result.tm_hour = _hour;
129  result.tm_min = _minute;
130  result.tm_sec = _second;
131  result.tm_isdst = -1;
132 
133  time_t seconds = mktime(&result);
134  if (seconds == -1)
135  throwex SystemException("Cannot convert date & time to local timestamp!");
136 
137  return LocalTimestamp(seconds * 1000000000ull + _millisecond * 1000000ull + _microsecond * 1000ull + _nanosecond);
138 }
139 
140 UtcTime::UtcTime(const Timestamp& timestamp)
141 {
142  struct tm result;
143  time_t seconds = timestamp.seconds();
144 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
145  if (gmtime_r(&seconds, &result) != &result)
146  throwex SystemException(format("Cannot convert the given timestamp ({}) to UTC date & time structure!", timestamp.total()));
147 #elif defined(_WIN32) || defined(_WIN64)
148  if (gmtime_s(&result, &seconds))
149  throwex SystemException(format("Cannot convert the given timestamp ({}) to UTC date & time structure!", timestamp.total()));
150 #endif
151  _year = result.tm_year + 1900;
152  _month = result.tm_mon + 1;
153  _weekday = result.tm_wday;
154  _day = result.tm_mday;
155  _hour = result.tm_hour;
156  _minute = result.tm_min;
157  _second = result.tm_sec % 60;
158  _millisecond = timestamp.milliseconds() % 1000;
159  _microsecond = timestamp.microseconds() % 1000;
160  _nanosecond = timestamp.nanoseconds() % 1000;
161 }
162 
164 {
165  struct tm result;
166  time_t seconds = timestamp.seconds();
167 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
168  if (localtime_r(&seconds, &result) != &result)
169  throwex SystemException(format("Cannot convert the given timestamp ({}) to local date & time structure!", timestamp.total()));
170 #elif defined(_WIN32) || defined(_WIN64)
171  if (localtime_s(&result, &seconds))
172  throwex SystemException(format("Cannot convert the given timestamp ({}) to local date & time structure!", timestamp.total()));
173 #endif
174  _year = result.tm_year + 1900;
175  _month = result.tm_mon + 1;
176  _weekday = result.tm_wday;
177  _day = result.tm_mday;
178  _hour = result.tm_hour;
179  _minute = result.tm_min;
180  _second = result.tm_sec % 60;
181  _millisecond = timestamp.milliseconds() % 1000;
182  _microsecond = timestamp.microseconds() % 1000;
183  _nanosecond = timestamp.nanoseconds() % 1000;
184 }
185 
186 } // namespace CppCommon
Argument exception.
Definition: exceptions.h:79
LocalTime()
Initialize local time with a current value.
Definition: time.h:241
Local timestamp.
Definition: timestamp.h:260
System exception.
Definition: exceptions.h:107
Time() noexcept
Initialize time with an epoch time.
Definition: time.inl:44
int month() const noexcept
Get month value (1-12)
Definition: time.h:138
LocalTimestamp localstamp() const
Get local timestamp from the current date & time value.
Definition: time.cpp:122
int year() const noexcept
Get year value (1970-2038 for 32-bit or 1970-3000 for 64-bit)
Definition: time.h:136
int millisecond() const noexcept
Get millisecond value (0-999)
Definition: time.h:150
int _month
Month value.
Definition: time.h:178
int _minute
Minute value.
Definition: time.h:186
int _hour
Hour value.
Definition: time.h:184
int _year
Year value.
Definition: time.h:176
int day() const noexcept
Get day value (1-31)
Definition: time.h:142
int minute() const noexcept
Get minute value (0-59)
Definition: time.h:146
int second() const noexcept
Get second value (0-59)
Definition: time.h:148
int hour() const noexcept
Get hour value (0-23)
Definition: time.h:144
int _weekday
Weekday value.
Definition: time.h:180
int _millisecond
Millisecond value.
Definition: time.h:190
UtcTimestamp utcstamp() const
Get UTC timestamp from the current date & time value.
Definition: time.cpp:100
int microsecond() const noexcept
Get microsecond value (0-999)
Definition: time.h:152
int _day
Day value.
Definition: time.h:182
int _nanosecond
Nanosecond value.
Definition: time.h:194
int nanosecond() const noexcept
Get nanosecond value (0-999)
Definition: time.h:154
int _microsecond
Microsecond value.
Definition: time.h:192
int _second
Second value.
Definition: time.h:188
uint64_t milliseconds() const noexcept
Get total milliseconds of the current timestamp.
Definition: timestamp.h:146
uint64_t microseconds() const noexcept
Get total microseconds of the current timestamp.
Definition: timestamp.h:149
uint64_t seconds() const noexcept
Get total seconds of the current timestamp.
Definition: timestamp.h:143
uint64_t total() const noexcept
Get total value of the current timestamp (total nanoseconds)
Definition: timestamp.h:156
uint64_t nanoseconds() const noexcept
Get total nanoseconds of the current timestamp.
Definition: timestamp.h:152
UtcTime()
Initialize UTC time with a current value.
Definition: time.h:215
UTC timestamp.
Definition: timestamp.h:248
#define throwex
Throw extended exception macro.
Definition: exceptions.h:23
Format string definition.
C++ Common project definitions.
Definition: token_bucket.h:15
std::string format(fmt::format_string< T... > pattern, T &&... args)
Format string.
Definition: format.inl:12
Time definition.