3 #include "../conversion/stringconversion.h" 4 #include "../conversion/stringbuilder.h" 14 const int DateTime::m_daysPerYear = 365;
15 const int DateTime::m_daysPer4Years = 1461;
16 const int DateTime::m_daysPer100Years = 36524;
17 const int DateTime::m_daysPer400Years = 146097;
18 const int DateTime::m_daysTo1601 = 584388;
19 const int DateTime::m_daysTo1899 = 693593;
20 const int DateTime::m_daysTo10000 = 3652059;
21 const int DateTime::m_daysToMonth365[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
22 const int DateTime::m_daysToMonth366[13] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};
23 const int DateTime::m_daysInMonth365[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
24 const int DateTime::m_daysInMonth366[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
26 template<
typename num1,
typename num2,
typename num3>
29 return (val) >= (min) && (val) <= (max);
32 template<
typename num1,
typename num2,
typename num3>
35 return (val) >= (min) && (val) < (max);
54 DateTime DateTime::fromTimeStamp(time_t timeStamp)
57 struct tm *timeinfo = localtime(&timeStamp);
58 return DateTime::fromDateAndTime(timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday,
59 timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec < 60 ? timeinfo->tm_sec : 59, 0);
68 DateTime DateTime::fromTimeStampGmt(time_t timeStamp)
71 struct tm *timeinfo = gmtime(&timeStamp);
72 return DateTime::fromDateAndTime(timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday,
73 timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec < 60 ? timeinfo->tm_sec : 59, 0);
85 int *
const dayIndex = values + 2;
86 int *
const secondsIndex = values + 5;
87 int *valueIndex = values;
88 int *
const valuesEnd = values + 7;
89 double miliSecondsFact = 100.0, miliSeconds = 0.0;
90 for(
const char *strIndex = str; ; ++strIndex) {
91 const char c = *strIndex;
92 if(c <= '9' && c >=
'0') {
93 if(valueIndex > secondsIndex) {
94 miliSeconds += (c -
'0') * miliSecondsFact;
95 miliSecondsFact /= 10;
98 *valueIndex += c -
'0';
100 }
else if((c ==
'-' || c ==
':' || c ==
'/') || (c ==
'.' && (valueIndex == secondsIndex)) || (c ==
' ' && (valueIndex == dayIndex))) {
101 if(++valueIndex == valuesEnd) {
104 }
else if(c ==
'\0') {
110 return DateTime::fromDateAndTime(values[0], values[1], *dayIndex, values[3], values[4], *secondsIndex, miliSeconds);
120 std::pair<DateTime, TimeSpan> DateTime::fromIsoString(
const char *str)
123 int *
const dayIndex = values + 2;
124 int *
const hourIndex = values + 3;
125 int *
const secondsIndex = values + 5;
126 int *
const miliSecondsIndex = values + 6;
127 int *
const deltaHourIndex = values + 7;
128 int *valueIndex = values;
129 bool deltaNegative =
false;
130 double miliSecondsFact = 100.0, miliSeconds = 0.0;
131 for(
const char *strIndex = str; ; ++strIndex) {
132 const char c = *strIndex;
133 if(c <= '9' && c >=
'0') {
134 if(valueIndex == miliSecondsIndex) {
135 miliSeconds += (c -
'0') * miliSecondsFact;
136 miliSecondsFact /= 10;
139 *valueIndex += c -
'0';
141 }
else if(c ==
'T') {
142 if(++valueIndex != hourIndex) {
145 }
else if(c ==
'-') {
146 if(valueIndex < dayIndex) {
151 }
else if(c ==
'.') {
152 if(valueIndex != secondsIndex) {
157 }
else if(c ==
':') {
158 if(valueIndex < hourIndex) {
160 }
else if(valueIndex == secondsIndex) {
165 }
else if((c ==
'+') && (++valueIndex == deltaHourIndex)) {
166 deltaNegative =
false;
167 }
else if((c ==
'-') && (++valueIndex == deltaHourIndex)) {
168 deltaNegative =
true;
169 }
else if(c ==
'\0') {
175 deltaNegative && (*deltaHourIndex = -*deltaHourIndex);
176 return make_pair(DateTime::fromDateAndTime(values[0], values[1], *dayIndex, *hourIndex, values[4], *secondsIndex, miliSeconds), TimeSpan::fromMinutes(*deltaHourIndex * 60 + values[8]));
187 toString(result, format, noMilliseconds);
198 stringstream s(stringstream::in | stringstream::out);
200 if(format == DateTimeOutputFormat::DateTimeAndWeekday
201 || format == DateTimeOutputFormat::DateTimeAndShortWeekday)
202 s << printDayOfWeek(dayOfWeek(), format == DateTimeOutputFormat::DateTimeAndShortWeekday) <<
' ';
203 if(format == DateTimeOutputFormat::DateOnly
204 || format == DateTimeOutputFormat::DateAndTime
205 || format == DateTimeOutputFormat::DateTimeAndWeekday
206 || format == DateTimeOutputFormat::DateTimeAndShortWeekday)
207 s << setw(4) << year() <<
'-' << setw(2) << month() <<
'-' << setw(2) << day();
208 if(format == DateTimeOutputFormat::DateAndTime
209 || format == DateTimeOutputFormat::DateTimeAndWeekday
210 || format == DateTimeOutputFormat::DateTimeAndShortWeekday)
212 if(format == DateTimeOutputFormat::TimeOnly
213 || format == DateTimeOutputFormat::DateAndTime
214 || format == DateTimeOutputFormat::DateTimeAndWeekday
215 || format == DateTimeOutputFormat::DateTimeAndShortWeekday) {
216 s << setw(2) << hour() <<
':' << setw(2) << minute() <<
':' << setw(2) << second();
217 int ms = millisecond();
218 if(!noMilliseconds && ms > 0) {
219 s <<
'.' << setw(3) << ms;
229 string DateTime::toIsoString(
TimeSpan timeZoneDelta)
const 231 stringstream s(stringstream::in | stringstream::out);
233 s << setw(4) << year() <<
'-' << setw(2) << month() <<
'-' << setw(2) << day()
234 <<
'T' << setw(2) << hour() <<
':' << setw(2) << minute() <<
':' << setw(2) << second() <<
'.' << setw(3) << millisecond();
235 if(!timeZoneDelta.
isNull()) {
236 s << (timeZoneDelta.
isNegative() ?
'-' :
'+');
237 s << setw(2) << timeZoneDelta.
hours() <<
':' << setw(2) << timeZoneDelta.
minutes();
249 const char *DateTime::printDayOfWeek(
DayOfWeek dayOfWeek,
bool abbreviation)
253 case DayOfWeek::Monday:
255 case DayOfWeek::Tuesday:
257 case DayOfWeek::Wednesday:
259 case DayOfWeek::Thursday:
261 case DayOfWeek::Friday:
263 case DayOfWeek::Saturday:
265 case DayOfWeek::Sunday:
270 case DayOfWeek::Monday:
272 case DayOfWeek::Tuesday:
274 case DayOfWeek::Wednesday:
276 case DayOfWeek::Thursday:
278 case DayOfWeek::Friday:
280 case DayOfWeek::Saturday:
282 case DayOfWeek::Sunday:
292 uint64 DateTime::dateToTicks(
int year,
int month,
int day)
296 const int *daysToMonth = isLeapYear(year) ? m_daysToMonth366 : m_daysToMonth365;
297 int passedMonth = month - 1;
298 if(
inRangeInclMax(day, 1, daysToMonth[month] - daysToMonth[passedMonth])) {
299 int passedYears = year - 1;
300 int passedDays = day - 1;
301 return (passedYears * m_daysPerYear + passedYears / 4 - passedYears / 100 + passedYears / 400 + daysToMonth[passedMonth] + passedDays) * TimeSpan::ticksPerDay;
317 uint64 DateTime::timeToTicks(
int hour,
int minute,
int second,
double millisecond)
331 return (hour * TimeSpan::ticksPerHour) + (minute * TimeSpan::ticksPerMinute) + (second * TimeSpan::ticksPerSecond) + (
uint64)(millisecond * (
double)TimeSpan::ticksPerMillisecond);
338 int DateTime::getDatePart(
DatePart part)
const 340 int fullDays = m_ticks / TimeSpan::ticksPerDay;
341 int full400YearBlocks = fullDays / m_daysPer400Years;
342 int daysMinusFull400YearBlocks = fullDays - full400YearBlocks * m_daysPer400Years;
343 int full100YearBlocks = daysMinusFull400YearBlocks / m_daysPer100Years;
344 if(full100YearBlocks == 4) {
345 full100YearBlocks = 3;
347 int daysMinusFull100YearBlocks = daysMinusFull400YearBlocks - full100YearBlocks * m_daysPer100Years;
348 int full4YearBlocks = daysMinusFull100YearBlocks / m_daysPer4Years;
349 int daysMinusFull4YearBlocks = daysMinusFull100YearBlocks - full4YearBlocks * m_daysPer4Years;
350 int full1YearBlocks = daysMinusFull4YearBlocks / m_daysPerYear;
351 if(full1YearBlocks == 4) {
354 if(part == DatePart::Year) {
355 return full400YearBlocks * 400 + full100YearBlocks * 100 + full4YearBlocks * 4 + full1YearBlocks + 1;
357 int restDays = daysMinusFull4YearBlocks - full1YearBlocks * m_daysPerYear;
358 if(part == DatePart::DayOfYear) {
361 const int *daysToMonth = (full1YearBlocks == 3 && (full4YearBlocks != 24 || full100YearBlocks == 3)) ? m_daysToMonth366 : m_daysToMonth365;
363 while(restDays >= daysToMonth[month]) {
366 if(part == DatePart::Month) {
368 }
else if(part == DatePart::Day) {
369 return restDays - daysToMonth[month - 1] + 1;
constexpr bool isNegative() const
Returns ture if the time interval represented by the current TimeSpan class is negative.
Represents an instant in time, typically expressed as a date and time of day.
Contains classes providing a means for handling date and time information.
The ConversionException class is thrown by the various conversion functions of this library when a co...
Represents a time interval.
constexpr int hours() const
Gets the hours component of the time interval represented by the current TimeSpan class...
std::uint64_t uint64
unsigned 64-bit integer
constexpr bool isNull() const
Returns ture if the time interval represented by the current TimeSpan class is null.
constexpr int minutes() const
Gets the minutes component of the time interval represented by the current TimeSpan class...
DatePart
Specifies the date part.
Contains several functions providing conversions between different data types.
DateTimeOutputFormat
Specifies the output format.
bool inRangeExclMax(num1 val, num2 min, num3 max)
bool inRangeInclMax(num1 val, num2 min, num3 max)
DayOfWeek
Specifies the day of the week.