Xclox
C++11 header-only cross-platform date and time library with an asynchronous NTP client
datetime.hpp
1 /*
2  * Copyright (c) 2024 Abdullatif Kalla.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE.txt file in the root directory of this source tree.
6  */
7 
8 #ifndef XCLOX_DATE_TIME_HPP
9 #define XCLOX_DATE_TIME_HPP
10 
11 #include "date.hpp"
12 #include "time.hpp"
13 
14 #include <cmath>
15 
16 namespace xclox {
17 
47 class DateTime {
48  using Duration = std::chrono::nanoseconds;
49 
50 public:
61  using Hours = Time::Hours;
62  using Days = Date::Days;
63  using Weeks = Date::Weeks;
64 
66 
73  using Month = Date::Month;
74 
76 
83  DateTime() = default;
84 
86  DateTime(const DateTime& other) = default;
87 
89  DateTime(DateTime&& other) = default;
90 
95  explicit DateTime(const Duration& duration)
96  {
97  const auto& subDay = duration % Days(1);
98  const auto& floatingDay = Days(duration.count() < 0 && subDay.count() != 0 ? 1 : 0);
99  m_date = Date(std::chrono::duration_cast<Days>(duration - floatingDay));
100  m_time = Time(subDay + floatingDay);
101  }
102 
104  explicit DateTime(const std::chrono::system_clock::time_point& timePoint)
105  : DateTime(timePoint.time_since_epoch())
106  {
107  }
108 
110  explicit DateTime(const Date& date)
111  : m_date(date)
112  , m_time(Nanoseconds::zero())
113  {
114  }
115 
117  explicit DateTime(const Date& date, const Time& time)
118  : m_date(date)
119  , m_time(time)
120  {
121  }
122 
124  ~DateTime() = default;
125 
127 
134  DateTime& operator=(const DateTime& other) = default;
135 
137  DateTime& operator=(DateTime&& other) = default;
138 
140 
147  bool operator<(const DateTime& other) const
148  {
149  return (this->m_date < other.m_date) || (this->m_date == other.m_date && this->m_time < other.m_time);
150  }
151 
153  bool operator<=(const DateTime& other) const
154  {
155  return (this->m_date <= other.m_date) || (this->m_date == other.m_date && this->m_time <= other.m_time);
156  }
157 
159  bool operator>(const DateTime& other) const
160  {
161  return (this->m_date > other.m_date) || (this->m_date == other.m_date && this->m_time > other.m_time);
162  }
163 
165  bool operator>=(const DateTime& other) const
166  {
167  return (this->m_date >= other.m_date) || (this->m_date == other.m_date && this->m_time >= other.m_time);
168  }
169 
171  bool operator==(const DateTime& other) const
172  {
173  return this->m_date == other.m_date && this->m_time == other.m_time;
174  }
175 
177  bool operator!=(const DateTime& other) const
178  {
179  return this->m_date != other.m_date || this->m_time != other.m_time;
180  }
181 
183 
190  Nanoseconds operator-(const DateTime& other) const
191  {
192  return this->toStdDurationSinceEpoch() - other.toStdDurationSinceEpoch();
193  }
194 
196  DateTime operator-(const Duration& duration) const
197  {
198  return subtractDuration(duration);
199  }
200 
202  DateTime operator+(const Duration& duration) const
203  {
204  return addDuration(duration);
205  }
207 
214  bool isValid() const
215  {
216  return m_date.isValid() && m_time.isValid();
217  }
218 
220  Date date() const
221  {
222  return m_date;
223  }
224 
226  Time time() const
227  {
228  return m_time;
229  }
230 
232  long nanosecond() const
233  {
234  return m_time.nanosecond();
235  }
236 
238  long microsecond() const
239  {
240  return m_time.microsecond();
241  }
242 
244  int millisecond() const
245  {
246  return m_time.millisecond();
247  }
248 
250  int second() const
251  {
252  return m_time.second();
253  }
254 
256  int minute() const
257  {
258  return m_time.minute();
259  }
260 
262  int hour() const
263  {
264  return m_time.hour();
265  }
266 
268  int day() const
269  {
270  return m_date.day();
271  }
272 
274  int month() const
275  {
276  return m_date.month();
277  }
278 
280  int year() const
281  {
282  return m_date.year();
283  }
284 
286  void getYearMonthDay(int* year, int* month, int* day) const
287  {
288  return m_date.getYearMonthDay(year, month, day);
289  }
290 
292  int dayOfWeek() const
293  {
294  return m_date.dayOfWeek();
295  }
296 
298  int dayOfYear() const
299  {
300  return m_date.dayOfYear();
301  }
302 
304  int daysInMonth() const
305  {
306  return m_date.daysInMonth();
307  }
308 
310  int daysInYear() const
311  {
312  return m_date.daysInYear();
313  }
314 
316  bool isLeapYear() const
317  {
318  return m_date.isLeapYear();
319  }
320 
330  int weekOfYear(int* weekYear = nullptr) const
331  {
332  return m_date.weekOfYear(weekYear);
333  }
334 
351  std::string dayOfWeekName(bool shortName = false) const
352  {
353  return m_date.dayOfWeekName(shortName);
354  }
355 
377  std::string monthName(bool shortName = false) const
378  {
379  return m_date.monthName(shortName);
380  }
381 
383 
390  DateTime addNanoseconds(int nanoseconds) const
391  {
392  return addDuration(Nanoseconds(nanoseconds));
393  }
394 
396  DateTime subtractNanoseconds(int nanoseconds) const
397  {
398  return subtractDuration(Nanoseconds(nanoseconds));
399  }
400 
402  DateTime addMicroseconds(int microseconds) const
403  {
404  return addDuration(Microseconds(microseconds));
405  }
406 
408  DateTime subtractMicroseconds(int microseconds) const
409  {
410  return subtractDuration(Microseconds(microseconds));
411  }
412 
414  DateTime addMilliseconds(int milliseconds) const
415  {
416  return addDuration(Milliseconds(milliseconds));
417  }
418 
420  DateTime subtractMilliseconds(int milliseconds) const
421  {
422  return subtractDuration(Milliseconds(milliseconds));
423  }
424 
426  DateTime addSeconds(int seconds) const
427  {
428  return addDuration(Seconds(seconds));
429  }
430 
432  DateTime subtractSeconds(int seconds) const
433  {
434  return subtractDuration(Seconds(seconds));
435  }
436 
438  DateTime addMinutes(int minutes) const
439  {
440  return addDuration(Minutes(minutes));
441  }
442 
444  DateTime subtractMinutes(int minutes) const
445  {
446  return subtractDuration(Minutes(minutes));
447  }
448 
450  DateTime addHours(int hours) const
451  {
452  return addDuration(Hours(hours));
453  }
454 
456  DateTime subtractHours(int hours) const
457  {
458  return subtractDuration(Hours(hours));
459  }
460 
462  DateTime addDays(int days) const
463  {
464  return DateTime(m_date.addDays(days), m_time);
465  }
466 
468  DateTime subtractDays(int days) const
469  {
470  return DateTime(m_date.subtractDays(days), m_time);
471  }
472 
474  DateTime addMonths(int months) const
475  {
476  return DateTime(m_date.subtractMonths(months), m_time);
477  }
478 
480  DateTime subtractMonths(int months) const
481  {
482  return DateTime(m_date.subtractMonths(months), m_time);
483  }
484 
486  DateTime addYears(int years) const
487  {
488  return DateTime(m_date.addYears(years), m_time);
489  }
490 
492  DateTime subtractYears(int years) const
493  {
494  return DateTime(m_date.subtractYears(years), m_time);
495  }
496 
498  DateTime addDuration(const Duration& duration) const
499  {
500  if (duration.count() < 0)
501  return subtractDuration(-duration);
502 
503  const Duration totalDuration = Nanoseconds(m_time.toNanosecondsSinceMidnight()) + duration;
504  return DateTime(m_date.addDays(std::chrono::duration_cast<Days>(totalDuration).count()), Time(totalDuration % Days(1)));
505  }
506 
508  DateTime subtractDuration(const Duration& duration) const
509  {
510  if (duration.count() < 0)
511  return addDuration(-duration);
512 
513  return DateTime(m_date.subtractDays(std::abs(std::chrono::duration_cast<Days>(Nanoseconds(m_time.toNanosecondsSinceMidnight()) - duration - Days(1)).count())), Time((Days(1) + Nanoseconds(m_time.toNanosecondsSinceMidnight()) - (duration % Days(1))) % Days(1)));
514  }
515 
517 
524  long long toNanosecondsSinceEpoch() const
525  {
526  return (std::chrono::duration_cast<Nanoseconds>(m_date.toStdDurationSinceEpoch() + m_time.toStdDurationSinceMidnight())).count();
527  }
528 
530  long long toMicrosecondsSinceEpoch() const
531  {
532  return (std::chrono::duration_cast<Microseconds>(m_date.toStdDurationSinceEpoch() + m_time.toStdDurationSinceMidnight())).count();
533  }
534 
536  long long toMillisecondsSinceEpoch() const
537  {
538  return (std::chrono::duration_cast<Milliseconds>(m_date.toStdDurationSinceEpoch() + m_time.toStdDurationSinceMidnight())).count();
539  }
540 
542  long long toSecondsSinceEpoch() const
543  {
544  return (std::chrono::duration_cast<Seconds>(m_date.toStdDurationSinceEpoch() + m_time.toStdDurationSinceMidnight())).count();
545  }
546 
548  long toMinutesSinceEpoch() const
549  {
550  return (std::chrono::duration_cast<Minutes>(m_date.toStdDurationSinceEpoch() + m_time.toStdDurationSinceMidnight())).count();
551  }
552 
554  long toHoursSinceEpoch() const
555  {
556  return (std::chrono::duration_cast<Hours>(m_date.toStdDurationSinceEpoch() + m_time.toStdDurationSinceMidnight())).count();
557  }
558 
560  long toDaysSinceEpoch() const
561  {
562  return m_date.toDaysSinceEpoch();
563  }
564 
567  {
568  return std::chrono::duration_cast<Microseconds>(m_date.toStdDurationSinceEpoch() + m_time.toStdDurationSinceMidnight());
569  }
570 
572  std::chrono::system_clock::time_point toStdTimePoint() const
573  {
574  return std::chrono::system_clock::time_point(toStdDurationSinceEpoch());
575  }
576 
578  std::tm toBrokenStdTime() const
579  {
580  int y, m, d;
581  getYearMonthDay(&y, &m, &d);
582  std::tm cTime = { 0 };
583  cTime.tm_year = y - 1970;
584  cTime.tm_year = m;
585  cTime.tm_year = d;
586  cTime.tm_hour = hour();
587  cTime.tm_min = minute();
588  cTime.tm_sec = second();
589 
590  return cTime;
591  }
592 
594  std::time_t toScalarStdTime() const
595  {
596  return std::time_t(toSecondsSinceEpoch());
597  }
598 
607  double toJulianDay() const
608  {
609  return m_date.toDaysSinceEpoch() + 2440587.5 + static_cast<double>(m_time.toNanosecondsSinceMidnight()) / static_cast<double>(Nanoseconds(Days(1)).count());
610  }
611 
655  std::string toString(const std::string& format = "yyyy-MM-dd hh:mm:ss") const
656  {
657  if (!isValid() || format.empty())
658  return std::string();
659  std::stringstream output;
660  for (size_t pos = 0; pos < format.size(); ++pos) {
661  const auto count = internal::countIdenticalCharsFrom(pos, format);
662  output << (internal::isPattern(format.at(pos), count) ? stringify(format.at(pos), count) : format.substr(pos, count));
663  pos += count - 1;
664  }
665  return output.str();
666  }
667 
669 
674  static DateTime current()
675  {
676  return DateTime(std::chrono::system_clock::now());
677  }
678 
680  static DateTime epoch()
681  {
682  return DateTime(Date::epoch(), Time::midnight());
683  }
684 
689  static DateTime fromString(const std::string& datetime, const std::string& format = "yyyy-MM-dd hh:mm:ss")
690  {
691  int sign = 1;
692  int y = 0;
693  int M = 1;
694  int d = 1;
695  int h = 0;
696  int m = 0;
697  int s = 0;
698  int f = 0;
699  size_t dtPos = 0;
700  for (size_t fmtPos = 0; fmtPos < format.size(); ++fmtPos) {
701  const auto count = internal::countIdenticalCharsFrom(fmtPos, format);
702  if (internal::isPattern(format[fmtPos])) {
703  if (!internal::isPattern(format[fmtPos], count)) {
704  return DateTime();
705  }
706  }
707  if (format[fmtPos] == 'y') {
708  y = parse(format[fmtPos], count, datetime, dtPos);
709  } else if (format[fmtPos] == '#' || format[fmtPos] == 'E') {
710  sign = parse(format[fmtPos], count, datetime, dtPos);
711  } else if (format[fmtPos] == 'M') {
712  M = parse(format[fmtPos], count, datetime, dtPos);
713  } else if (format[fmtPos] == 'd') {
714  if (count == 3) {
715  parse(format[fmtPos], count, datetime, dtPos);
716  } else {
717  d = parse(format[fmtPos], count, datetime, dtPos);
718  }
719  } else if (format[fmtPos] == 'h' || format[fmtPos] == 'H') {
720  h = parse(format[fmtPos], count, datetime, dtPos);
721  } else if (format[fmtPos] == 'a' || format[fmtPos] == 'A') {
722  int clock = parse(format[fmtPos], count, datetime, dtPos);
723  h += clock == -12 && h >= 12 || clock == 12 && h < 12 ? clock : 0;
724  } else if (format[fmtPos] == 'm') {
725  m = parse(format[fmtPos], count, datetime, dtPos);
726  } else if (format[fmtPos] == 's') {
727  s = parse(format[fmtPos], count, datetime, dtPos);
728  } else if (format[fmtPos] == 'f') {
729  f = parse(format[fmtPos], count, datetime, dtPos) * std::pow(10, 9 - count);
730  } else {
731  dtPos += count;
732  }
733  if (dtPos == std::string::npos) {
734  return DateTime();
735  }
736  fmtPos += count - 1;
737  }
738  return DateTime(Date(sign * y, M, d), Time(h, m, s, Nanoseconds(f)));
739  }
740 
742  static DateTime fromJulianDay(double julianDay)
743  {
744  const long integer = static_cast<long>(julianDay);
745  const double fraction = julianDay - integer;
746  const long millisecondCount = static_cast<long>(static_cast<double>(Milliseconds(Days(1)).count()) * fraction);
747  return DateTime(Date(Days(integer - 2440587))).subtractHours(12).addDuration(Milliseconds(millisecondCount));
748  }
749 
757  static long long nanosecondsBetween(const DateTime& from, const DateTime& to)
758  {
759  return std::abs(std::chrono::duration_cast<Nanoseconds>((from.m_date.toStdDurationSinceEpoch() + from.m_time.toStdDurationSinceMidnight()) - (to.m_date.toStdDurationSinceEpoch() + to.m_time.toStdDurationSinceMidnight())).count());
760  }
761 
763  static long long microsecondsBetween(const DateTime& from, const DateTime& to)
764  {
765  return std::abs(std::chrono::duration_cast<Microseconds>(from.toStdDurationSinceEpoch() - to.toStdDurationSinceEpoch()).count());
766  }
767 
769  static long long millisecondsBetween(const DateTime& from, const DateTime& to)
770  {
771  return std::abs(std::chrono::duration_cast<Milliseconds>(from.toStdDurationSinceEpoch() - to.toStdDurationSinceEpoch()).count());
772  }
773 
775  static long long secondsBetween(const DateTime& from, const DateTime& to)
776  {
777  return std::abs(std::chrono::duration_cast<Seconds>(from.toStdDurationSinceEpoch() - to.toStdDurationSinceEpoch()).count());
778  }
779 
781  static long minutesBetween(const DateTime& from, const DateTime& to)
782  {
783  return std::abs(std::chrono::duration_cast<Minutes>(from.toStdDurationSinceEpoch() - to.toStdDurationSinceEpoch()).count());
784  }
785 
787  static long hoursBetween(const DateTime& from, const DateTime& to)
788  {
789  return std::abs(std::chrono::duration_cast<Hours>(from.toStdDurationSinceEpoch() - to.toStdDurationSinceEpoch()).count());
790  }
791 
793  static long daysBetween(const DateTime& from, const DateTime& to)
794  {
795  return std::abs(std::chrono::duration_cast<Days>(from.toStdDurationSinceEpoch() - to.toStdDurationSinceEpoch()).count());
796  }
797 
799  static long weeksBetween(const DateTime& from, const DateTime& to)
800  {
801  return std::abs(std::chrono::duration_cast<Weeks>(from.toStdDurationSinceEpoch() - to.toStdDurationSinceEpoch()).count());
802  }
803 
805 
806 private:
807  std::string stringify(char flag, size_t count) const
808  {
809  std::stringstream output;
810  output << std::setfill('0') << std::setw(count);
811  if (flag == '#') {
812  output << (year() < 0 ? "-" : "+");
813  } else if (flag == 'E') {
814  output << (year() < 0 ? "BCE" : "CE");
815  } else if (flag == 'y') {
816  const int y = std::abs(year());
817  if (count == 1) {
818  output << y;
819  } else if (count == 2) {
820  output << y - (y / 100 * 100);
821  } else if (count == 4) {
822  output << y - (y / 10000 * 10000);
823  }
824  } else if (flag == 'M') {
825  if (count == 1 || count == 2) {
826  output << month();
827  } else if (count == 3) {
828  output << internal::getShortMonthName(month());
829  } else if (count == 4) {
830  output << internal::getLongMonthName(month());
831  }
832  } else if (flag == 'd') {
833  if (count == 1 || count == 2) {
834  output << day();
835  } else if (count == 3) {
836  output << internal::getShortWeekdayName(dayOfWeek());
837  } else if (count == 4) {
838  output << internal::getLongWeekdayName(dayOfWeek());
839  }
840  } else if (flag == 'h') {
841  output << hour();
842  } else if (flag == 'H') {
843  int h = hour();
844  output << (h == 0 ? 12 : h > 12 ? h - 12
845  : h);
846  } else if (flag == 'm') {
847  output << minute();
848  } else if (flag == 's') {
849  output << second();
850  } else if (flag == 'f') {
851  output << nanosecond() / static_cast<long>(std::pow(10, 9 - count));
852  } else if (flag == 'a') {
853  output << (hour() < 12 ? "am" : "pm");
854  } else if (flag == 'A') {
855  output << (hour() < 12 ? "AM" : "PM");
856  }
857  return output.str();
858  }
859 
860  static int parse(char flag, size_t count, std::string input, size_t& pos)
861  {
862  if (flag == 'y' || (flag == 'M' || flag == 'd' || flag == 'h' || flag == 'H' || flag == 'm' || flag == 's') && count <= 2 || flag == 'f') {
863  if (pos < input.size() && std::isdigit(input[pos])) {
864  return internal::readIntAndAdvancePos(input, pos, flag == 'f' ? count : (flag == 'y' && count == 1 || count == 4 ? 4 : 2));
865  }
866  } else if (flag == '#') {
867  if (pos < input.size() && (input[pos] == '-' || input[pos] == '+')) {
868  return (input[pos++] == '-' ? -1 : 1);
869  }
870  } else if (flag == 'E') {
871  if (pos + 2 < input.size() && input.substr(pos, 3) == "BCE") {
872  pos += 3;
873  return -1;
874  } else if (pos + 1 < input.size() && input.substr(pos, 2) == "CE") {
875  pos += 2;
876  return 1;
877  }
878  } else if ((flag == 'M' || flag == 'd') && count <= 4 && pos + 2 < input.size()) {
879  const auto& line = count == 3 ? input.substr(pos, 3) : input.substr(pos);
880  if (flag == 'M') {
881  const auto& monthNameArray = count == 3 ? internal::getShortMonthNameArray() : internal::getLongMonthNameArray();
882  size_t index = internal::search(monthNameArray, line);
883  if (index < monthNameArray.size()) {
884  pos += monthNameArray[index].size();
885  return index + 1;
886  }
887  } else {
888  const auto& weekdayNameArray = count == 3 ? internal::getShortWeekdayNameArray() : internal::getLongWeekdayNameArray();
889  size_t index = internal::search(weekdayNameArray, line);
890  if (index < weekdayNameArray.size()) {
891  pos += weekdayNameArray[index].size();
892  return index + 1;
893  }
894  }
895  } else if ((flag == 'a' || flag == 'A') && pos + 1 < input.size()) {
896  if (flag == 'a' && input.substr(pos, 2) == "am" || input.substr(pos, 2) == "AM") {
897  return -12;
898  } else if (flag == 'a' && input.substr(pos, 2) == "pm" || input.substr(pos, 2) == "PM") {
899  return 12;
900  }
901  }
902  pos = std::string::npos;
903  return std::numeric_limits<int>::min();
904  }
905 
906  Date m_date;
907  Time m_time;
908 };
909 
917 std::ostream& operator<<(std::ostream& os, const DateTime& dt)
918 {
919  os << dt.toString("yyyy-MM-ddThh:mm:ss.fff");
920 
921  return os;
922 }
923 
925 std::istream& operator>>(std::istream& is, DateTime& dt)
926 {
927  const int DateTimeFormatWidth = 23;
928  char result[DateTimeFormatWidth];
929  is.read(result, DateTimeFormatWidth);
930  dt = DateTime::fromString(std::string(result, DateTimeFormatWidth), "yyyy-MM-ddThh:mm:ss.fff");
931 
932  return is;
933 }
934 
936 
937 }
938 
939 #endif // XCLOX_DATE_TIME_HPP
DateTime is an immutable class representing a datetime without a time zone in the ISO-8601 calendar s...
Definition: datetime.hpp:47
DateTime subtractMicroseconds(int microseconds) const
Returns a new DateTime object representing this datetime with microseconds subtracted from it.
Definition: datetime.hpp:408
DateTime subtractDuration(const Duration &duration) const
Returns a new DateTime object representing this datetime with duration subtracted from it.
Definition: datetime.hpp:508
DateTime operator+(const Duration &duration) const
Returns the result of adding duration to this datetime as a new DateTime object.
Definition: datetime.hpp:202
bool operator<(const DateTime &other) const
Returns whether this datetime is earlier than other.
Definition: datetime.hpp:147
DateTime operator-(const Duration &duration) const
Returns the result of subtracting duration from this datetime as a new DateTime object.
Definition: datetime.hpp:196
DateTime subtractHours(int hours) const
Returns a new DateTime object representing this datetime with hours subtracted from it.
Definition: datetime.hpp:456
Date date() const
Returns the date part of this datetime.
Definition: datetime.hpp:220
Time::Seconds Seconds
Second duration.
Definition: datetime.hpp:59
static long long secondsBetween(const DateTime &from, const DateTime &to)
Returns the number of seconds between from and to.
Definition: datetime.hpp:775
DateTime addNanoseconds(int nanoseconds) const
Returns a new DateTime object representing this datetime with nanoseconds added to it.
Definition: datetime.hpp:390
Microseconds toStdDurationSinceEpoch() const
Returns a std::chrono::microseconds duration since "1970-01-01 00:00:00.000 UTC", not counting leap s...
Definition: datetime.hpp:566
std::time_t toScalarStdTime() const
Returns a std::time_t representation of this datetime.
Definition: datetime.hpp:594
static long hoursBetween(const DateTime &from, const DateTime &to)
Returns the number of hours between from and to.
Definition: datetime.hpp:787
DateTime()=default
Constructs an invalid DateTime object with every field set to zero.
int year() const
Returns the year as a number. There is no year 0. Negative numbers indicate years before 1 CE; that i...
Definition: datetime.hpp:280
long microsecond() const
Returns the microsecond of second (0, 999999).
Definition: datetime.hpp:238
std::tm toBrokenStdTime() const
Returns a std::tm representation of this datetime.
Definition: datetime.hpp:578
static DateTime fromJulianDay(double julianDay)
Returns a DateTime object corresponding to the Julian day julianDay. See toJulianDay() for informatio...
Definition: datetime.hpp:742
DateTime addMinutes(int minutes) const
Returns a new DateTime object representing this datetime with minutes added to it.
Definition: datetime.hpp:438
void getYearMonthDay(int *year, int *month, int *day) const
Set the year, month, and day in the parameters year, month, and day, respectively.
Definition: datetime.hpp:286
std::string dayOfWeekName(bool shortName=false) const
Returns the name of the weekday of this datetime.
Definition: datetime.hpp:351
std::istream & operator>>(std::istream &is, DateTime &dt)
Reads a datetime in ISO-8601 date and time format "yyyy-MM-ddThh:mm:ss.fff" from stream is and stores...
Definition: datetime.hpp:925
long nanosecond() const
Returns the nanosecond of second (0, 999999999).
Definition: datetime.hpp:232
int day() const
Returns the day of month (1, 31).
Definition: datetime.hpp:268
std::string toString(const std::string &format="yyyy-MM-dd hh:mm:ss") const
Returns the datetime as a string formatted according to the format string format.
Definition: datetime.hpp:655
bool operator==(const DateTime &other) const
Returns whether this datetime is equal to other.
Definition: datetime.hpp:171
Nanoseconds operator-(const DateTime &other) const
Returns the result of subtracting other from this datetime as Nanoseconds duration.
Definition: datetime.hpp:190
int dayOfWeek() const
Returns the weekday as a number between 1 and 7, which corresponds to the enumeration Weekday.
Definition: datetime.hpp:292
double toJulianDay() const
Returns the corresponding Julian Day Number (JDN) of this datetime as a double, where the integral pa...
Definition: datetime.hpp:607
DateTime addMicroseconds(int microseconds) const
Returns a new DateTime object representing this datetime with microseconds added to it.
Definition: datetime.hpp:402
static DateTime epoch()
Returns a DateTime object set to the epoch "1970-1-1T00:00:00".
Definition: datetime.hpp:680
static DateTime fromString(const std::string &datetime, const std::string &format="yyyy-MM-dd hh:mm:ss")
Returns a DateTime object from the string datetime formatted according to the format string format.
Definition: datetime.hpp:689
bool operator!=(const DateTime &other) const
Returns whether this datetime is different from other.
Definition: datetime.hpp:177
std::ostream & operator<<(std::ostream &os, const DateTime &dt)
Writes dt to stream os in ISO-8601 date and time format "yyyy-MM-ddThh:mm:ss.fff"....
Definition: datetime.hpp:917
std::string monthName(bool shortName=false) const
Returns the name of the month of this datetime.
Definition: datetime.hpp:377
static long long millisecondsBetween(const DateTime &from, const DateTime &to)
Returns the number of milliseconds between from and to.
Definition: datetime.hpp:769
int minute() const
Returns the minute of hour (0, 59).
Definition: datetime.hpp:256
Time::Nanoseconds Nanoseconds
Nanosecond duration.
Definition: datetime.hpp:56
DateTime addYears(int years) const
Returns a new DateTime object representing this datetime with years added to it.
Definition: datetime.hpp:486
DateTime(const Date &date)
Constructs a DateTime object from date, leaving the time part at midnight ("00:00:00").
Definition: datetime.hpp:110
int daysInMonth() const
Returns the number of days in the current month. It ranges between 28 and 31.
Definition: datetime.hpp:304
DateTime addDuration(const Duration &duration) const
Returns a new DateTime object representing this datetime with duration added to it.
Definition: datetime.hpp:498
Time::Hours Hours
Hour duration.
Definition: datetime.hpp:61
Time::Minutes Minutes
Minute duration.
Definition: datetime.hpp:60
DateTime subtractYears(int years) const
Returns a new DateTime object representing this datetime with years subtracted from it.
Definition: datetime.hpp:492
DateTime addSeconds(int seconds) const
Returns a new DateTime object representing this datetime with seconds added to it.
Definition: datetime.hpp:426
DateTime addDays(int days) const
Returns a new DateTime object representing this datetime with days added to it.
Definition: datetime.hpp:462
DateTime(const std::chrono::system_clock::time_point &timePoint)
Constructs a DateTime object from the standard library's chrono time point, timePoint.
Definition: datetime.hpp:104
DateTime subtractDays(int days) const
Returns a new DateTime object representing this datetime with days subtracted from it.
Definition: datetime.hpp:468
DateTime addMonths(int months) const
Returns a new DateTime object representing this datetime with months added to it. See Date::addMonths...
Definition: datetime.hpp:474
DateTime(const Date &date, const Time &time)
Constructs a DateTime object from date and time.
Definition: datetime.hpp:117
long long toMillisecondsSinceEpoch() const
Returns the number of elapsed milliseconds since "1970-01-01 00:00:00.000 UTC", not counting leap sec...
Definition: datetime.hpp:536
DateTime subtractMilliseconds(int milliseconds) const
Returns a new DateTime object representing this datetime with milliseconds subtracted from it.
Definition: datetime.hpp:420
long long toNanosecondsSinceEpoch() const
Returns the number of elapsed nanoseconds since "1970-01-01 00:00:00.000 UTC", not counting leap seco...
Definition: datetime.hpp:524
long long toMicrosecondsSinceEpoch() const
Returns the number of elapsed microseconds since "1970-01-01 00:00:00.000 UTC", not counting leap sec...
Definition: datetime.hpp:530
int weekOfYear(int *weekYear=nullptr) const
Returns the week number of the year of this datetime, and optionally stores the year in weekYear.
Definition: datetime.hpp:330
bool isValid() const
Returns whether this datetime object represents a valid datetime. A DateTime object is valid if both ...
Definition: datetime.hpp:214
static long long microsecondsBetween(const DateTime &from, const DateTime &to)
Returns the number of microseconds between from and to.
Definition: datetime.hpp:763
DateTime subtractSeconds(int seconds) const
Returns a new DateTime object representing this datetime with seconds subtracted from it.
Definition: datetime.hpp:432
int millisecond() const
Returns the millisecond of second (0, 999).
Definition: datetime.hpp:244
~DateTime()=default
Default destructor.
static long minutesBetween(const DateTime &from, const DateTime &to)
Returns the number of minutes between from and to.
Definition: datetime.hpp:781
DateTime(const Duration &duration)
Constructs a DateTime object from duration since the epoch "1970-01-01 00:00:00 UTC".
Definition: datetime.hpp:95
DateTime & operator=(const DateTime &other)=default
Copy assignment operator.
Date::Days Days
Day duration.
Definition: datetime.hpp:62
DateTime addMilliseconds(int milliseconds) const
Returns a new DateTime object representing this datetime with milliseconds added to it.
Definition: datetime.hpp:414
static DateTime current()
Returns a DateTime object set to the current datetime obtained from the system clock.
Definition: datetime.hpp:674
DateTime addHours(int hours) const
Returns a new DateTime object representing this datetime with hours added to it.
Definition: datetime.hpp:450
static long long nanosecondsBetween(const DateTime &from, const DateTime &to)
Returns the number of nanoseconds between from and to.
Definition: datetime.hpp:757
long long toSecondsSinceEpoch() const
Returns the number of elapsed seconds since "1970-01-01 00:00:00.000 UTC, not counting leap seconds.
Definition: datetime.hpp:542
int second() const
Returns the second of minute (0, 59).
Definition: datetime.hpp:250
bool isLeapYear() const
Returns whether the year of this datetime is a leap year. For more information, see Date::isLeapYear(...
Definition: datetime.hpp:316
long toMinutesSinceEpoch() const
Returns the number of elapsed minutes since "1970-01-01 00:00:00.000 UTC, not counting leap seconds.
Definition: datetime.hpp:548
DateTime & operator=(DateTime &&other)=default
Move assignment operator.
DateTime subtractMonths(int months) const
Returns a new DateTime object representing this datetime with months subtracted from it....
Definition: datetime.hpp:480
static long daysBetween(const DateTime &from, const DateTime &to)
Returns the number of days between from and to.
Definition: datetime.hpp:793
DateTime subtractNanoseconds(int nanoseconds) const
Returns a new DateTime object representing this datetime with nanoseconds subtracted from it.
Definition: datetime.hpp:396
bool operator<=(const DateTime &other) const
Returns whether this datetime is earlier than other or equal to it.
Definition: datetime.hpp:153
long toDaysSinceEpoch() const
Returns the number of elapsed days since "1970-01-01 00:00:00.000 UTC", not counting leap seconds.
Definition: datetime.hpp:560
Time::Microseconds Microseconds
Microsecond duration.
Definition: datetime.hpp:57
DateTime(DateTime &&other)=default
Move-constructs a DateTime object from other.
Time::Milliseconds Milliseconds
Millisecond duration.
Definition: datetime.hpp:58
DateTime(const DateTime &other)=default
Copy-constructs a DateTime object from other.
int daysInYear() const
Returns the number of days in the current year. It is either 365 or 366.
Definition: datetime.hpp:310
int hour() const
Returns the hour of day (0, 23).
Definition: datetime.hpp:262
Date::Weeks Weeks
Week duration.
Definition: datetime.hpp:63
bool operator>=(const DateTime &other) const
Returns whether this datetime is later than other or equal to it.
Definition: datetime.hpp:165
Time time() const
Returns the time part of this datetime.
Definition: datetime.hpp:226
bool operator>(const DateTime &other) const
Returns whether this datetime is later than other.
Definition: datetime.hpp:159
static long weeksBetween(const DateTime &from, const DateTime &to)
Returns the number of weeks between from and to.
Definition: datetime.hpp:799
int month() const
Returns the month of year (1, 12), which corresponds to the enumeration Month.
Definition: datetime.hpp:274
DateTime subtractMinutes(int minutes) const
Returns a new DateTime object representing this datetime with minutes subtracted from it.
Definition: datetime.hpp:444
std::chrono::system_clock::time_point toStdTimePoint() const
Returns a std::chrono::system_clock::time_point representation of this datetime.
Definition: datetime.hpp:572
long toHoursSinceEpoch() const
Returns the number of elapsed hours since "1970-01-01 00:00:00.000 UTC, not counting leap seconds.
Definition: datetime.hpp:554
int dayOfYear() const
Returns the day of the year as a number between 1 and 365 (1 to 366 on leap years).
Definition: datetime.hpp:298
Date is an immutable class representing a date without a time zone in the ISO-8601 calendar system,...
Definition: date.hpp:84
std::string monthName(bool shortName=false) const
Returns the name of the month of this date.
Definition: date.hpp:393
Date subtractDays(int days) const
Returns the result of subtracting days from this date as a new Date object.
Definition: date.hpp:414
int dayOfWeek() const
Returns the weekday of this date as a number between 1 and 7, which corresponds to the enumeration We...
Definition: date.hpp:286
long toDaysSinceEpoch() const
Returns the number of elapsed days since the epoch "1970-01-01".
Definition: date.hpp:486
Month
Type of month.
Definition: date.hpp:119
int daysInYear() const
Returns the number of days in the year of this date. It is either 365 or 366.
Definition: date.hpp:304
bool isValid() const
Returns whether this date object represents a valid date.
Definition: date.hpp:248
internal::Days Days
Day duration.
Definition: date.hpp:91
void getYearMonthDay(int *year, int *month, int *day) const
Set the year, month, and day of this date in the parameters year, month, and day, respectively.
Definition: date.hpp:254
Date subtractYears(int years) const
Returns the result of subtracting years from this date as a new Date object.
Definition: date.hpp:472
int year() const
Returns the year of this date as a number.
Definition: date.hpp:280
std::chrono::duration< long, std::ratio_multiply< std::ratio< 7 >, Days::period > > Weeks
Week duration.
Definition: date.hpp:92
int daysInMonth() const
Returns the number of days in the month of this date. It ranges between 28 and 31.
Definition: date.hpp:298
Date addYears(int years) const
Returns the result of adding years to this date as a new Date object.
Definition: date.hpp:465
Date subtractMonths(int months) const
Returns the result of subtracting months from this date as a new Date object.
Definition: date.hpp:451
Weekday
Type of weekday.
Definition: date.hpp:105
Date addDays(int days) const
Returns the result of adding days to this date as a new Date object.
Definition: date.hpp:406
std::string dayOfWeekName(bool shortName=false) const
Returns the name of the weekday of this date.
Definition: date.hpp:367
int month() const
Returns the month of the year of this date as a number between 1 and 12, which corresponds to the enu...
Definition: date.hpp:271
static Date epoch()
Returns a Date object set to the epoch "1970-01-01".
Definition: date.hpp:603
int day() const
Returns the day of the month of this date as a number between 1 and 31.
Definition: date.hpp:265
Days toStdDurationSinceEpoch() const
Returns the elapsed time since the epoch "1970-01-01" as a Days duration.
Definition: date.hpp:492
int weekOfYear(int *weekYear=nullptr) const
Returns the week of the year of this date, and optionally stores the year in weekYear.
Definition: date.hpp:324
int dayOfYear() const
Returns the day of year of this date as a number between 1 and 365 (1 to 366 on leap years).
Definition: date.hpp:292
bool isLeapYear() const
Returns whether the year of this date is a leap year.
Definition: date.hpp:310
Time is an immutable time class representing a time without a time zone in the ISO-8601 calendar syst...
Definition: time.hpp:46
long nanosecond() const
Returns the nanosecond of second (0, 999999999).
Definition: time.hpp:263
int minute() const
Returns the minute of hour (0, 59).
Definition: time.hpp:287
int millisecond() const
Returns the millisecond of second (0, 999).
Definition: time.hpp:275
int hour() const
Returns the hour of day (0, 23).
Definition: time.hpp:293
std::chrono::milliseconds Milliseconds
Millisecond duration.
Definition: time.hpp:58
std::chrono::minutes Minutes
Minute duration.
Definition: time.hpp:60
long microsecond() const
Returns the microsecond of second (0, 999999).
Definition: time.hpp:269
std::chrono::microseconds Microseconds
Microsecond duration.
Definition: time.hpp:57
bool isValid() const
Returns whether this time object represents a valid time.
Definition: time.hpp:257
long long toNanosecondsSinceMidnight() const
Returns the elapsed nanoseconds since midnight.
Definition: time.hpp:397
std::chrono::nanoseconds Nanoseconds
Nanosecond duration.
Definition: time.hpp:56
Nanoseconds toStdDurationSinceMidnight() const
Returns the elapsed time since midnight as a Nanoseconds duration.
Definition: time.hpp:433
std::chrono::seconds Seconds
Second duration.
Definition: time.hpp:59
std::chrono::hours Hours
Hour duration.
Definition: time.hpp:61
static Time midnight()
Returns a Time object set to midnight (i.e., "00:00:00").
Definition: time.hpp:535
int second() const
Returns the second of minute (0, 59).
Definition: time.hpp:281