34#ifndef QORE_QORE_DATE_PRIVATE_H
35#define QORE_QORE_DATE_PRIVATE_H
42#define SECS_PER_MINUTE 60
44#define SECS_PER_HOUR (SECS_PER_MINUTE * 60)
46#define SECS_PER_DAY (SECS_PER_HOUR * 24)
48#define SECS_PER_YEAR (SECS_PER_DAY * 365ll)
50#define SECS_PER_LEAP_YEAR (SECS_PER_YEAR + SECS_PER_DAY)
52#define MICROSECS_PER_SEC 1000000ll
53#define MICROSECS_PER_MINUTE (MICROSECS_PER_SEC * 60)
54#define MICROSECS_PER_HOUR (MICROSECS_PER_MINUTE * 60)
56#define MICROSECS_PER_AVG_DAY (MICROSECS_PER_HOUR * 24)
58#define MICROSECS_PER_MAX_MONTH (MICROSECS_PER_HOUR * 24 * 31)
60#define MICROSECS_PER_AVG_YEAR (MICROSECS_PER_AVG_DAY * 365)
63#define SECS_TO_2K (SECS_PER_YEAR * 30 + SECS_PER_DAY * 7ll)
66#define SECS_TO_2KLD (SECS_PER_YEAR * 30 + SECS_PER_DAY * (7ll + 60ll))
69#define SECS_IN_400_YEARS (SECS_PER_YEAR * 400 + SECS_PER_DAY * 97ll)
71#define SECS_IN_100_YEARS (SECS_PER_YEAR * 100 + SECS_PER_DAY * 24ll)
73#define SECS_IN_4_YEARS (SECS_PER_YEAR * 4 + SECS_PER_DAY)
76#define LEAPDAY_OFFSET (SECS_PER_DAY * 59)
78#define SECS_AFTER_LD (SECS_PER_DAY * 306)
80template <
typename T1,
typename T2>
81DLLLOCAL
void normalize_units(T1& bigger, T2& smaller,
int ratio) {
82 if (smaller <= -ratio || smaller >= ratio) {
83 int64 units = smaller / ratio;
85 smaller -= (T2)(units * ratio);
94 }
else if (bigger < 0 && smaller > 0) {
101template <
typename T1,
typename T2>
102DLLLOCAL
void normalize_units2(T1& bigger, T2& smaller,
int ratio) {
103 if (smaller <= -ratio || smaller >= ratio) {
104 int64 units = smaller / ratio;
106 smaller -= (T2)(units * ratio);
117template <
typename T1>
118DLLLOCAL
void normalize_units3(T1& bigger,
unsigned& smaller,
unsigned ratio) {
119 if (smaller >= ratio) {
120 int64 units = smaller / ratio;
122 smaller -= (int)(units * ratio);
126hashdecl qore_date_info {
128 DLLLOCAL
static const int month_lengths[];
130 DLLLOCAL
static const int positive_months[];
131 DLLLOCAL
static const int negative_months[];
133 DLLLOCAL
static bool isLeapYear(
int year);
141 DLLLOCAL
static void get_epoch_year(
int64 &epoch,
int& year,
bool& ly) {
143 epoch -= SECS_TO_2KLD;
146 int64 mult = epoch / SECS_IN_400_YEARS;
148 epoch %= SECS_IN_400_YEARS;
152 epoch = LEAPDAY_OFFSET + SECS_PER_DAY;
153 year = (int)(mult * 400 + 2000);
161 epoch += SECS_IN_400_YEARS;
168 int64 d = epoch / SECS_IN_100_YEARS;
175 epoch -= d * SECS_IN_100_YEARS;
182 d = epoch / SECS_IN_4_YEARS;
184 epoch %= SECS_IN_4_YEARS;
191 ly = epoch < SECS_AFTER_LD || epoch >= (SECS_PER_YEAR * 4);
196 d = epoch / SECS_PER_YEAR;
201 epoch -= d * SECS_PER_YEAR;
205 year = (int)(mult * 400 + 2000 + yo);
211 if (epoch >= SECS_AFTER_LD) {
213 epoch -= SECS_AFTER_LD;
216 epoch += LEAPDAY_OFFSET;
218 epoch += SECS_PER_DAY;
225 DLLLOCAL
static int leap_days_from_epoch(
int year,
int month) {
226 assert(month > 0 && month < 13);
230 d = year/4 - year/100 + year/400 - 477;
231 if (month < 3 && isLeapYear(year))
235 d = year/4 - year/100 + year/400 - 477;
240 if (month > 2 && isLeapYear(year + 1))
247 DLLLOCAL
static int getLastDayOfMonth(
int month,
int year) {
248 assert(month > 0 && month < 13);
250 return qore_date_info::month_lengths[month];
251 return qore_date_info::isLeapYear(year) ? 29 : 28;
254 DLLLOCAL
static int getDayOfWeek(
int year,
int month,
int day) {
255 assert(month > 0 && month < 13);
256 int a = (14 - month) / 12;
258 int m = month + 12 * a - 2;
259 return (day + y + y / 4 - y / 100 + y / 400 + (31 * m / 12)) % 7;
263 DLLLOCAL
static int64 getEpochSeconds(
int year,
int month,
int day) {
273 int64 epoch = (year - 1970) * SECS_PER_YEAR + (positive_months[month - 1] + day - 1
274 + leap_days_from_epoch(year, month)) * SECS_PER_DAY;
282 DLLLOCAL
static int64 getEpochSeconds(
int year,
int month,
int day,
int hour,
int minute,
int second) {
283 int64 secs = getEpochSeconds(year, month, day);
291 DLLLOCAL
static int getDayNumber(
int year,
int month,
int day) {
292 return positive_months[(month < 13 ? month : 12) - 1] + day
293 + (month > 2 && qore_date_info::isLeapYear(year) ? 1 : 0);
298 DLLLOCAL
static int getMonthIxFromAbbr(
const char* abbr);
302DLLLOCAL
void normalize_dm(
int& year,
int& month,
int& day);
305DLLLOCAL
void normalize_day(
int& year,
int& month,
int& day);
307class qore_relative_time;
309DLLLOCAL
extern const char *STATIC_UTC;
311hashdecl qore_simple_tm {
323 DLLLOCAL
void zero() {
333 DLLLOCAL
void set(
int n_year,
int n_month,
int n_day,
int n_hour,
int n_minute,
int n_second,
int n_us) {
344 DLLLOCAL
void set(
int64 seconds,
unsigned my_us) {
345 normalize_units3<int64>(seconds, my_us, 1000000);
352 qore_date_info::get_epoch_year(seconds, year, ly);
357 day = (int)(seconds / SECS_PER_DAY);
358 seconds %= SECS_PER_DAY;
360 for (month = 1; month < 12; ++month) {
361 int ml = qore_date_info::month_lengths[month];
362 if (ly && month == 2)
373 second = (int)seconds;
374 hour = second / SECS_PER_HOUR;
375 second %= SECS_PER_HOUR;
376 minute = second / SECS_PER_MINUTE;
377 second %= SECS_PER_MINUTE;
382 DLLLOCAL
bool hasValue()
const {
383 return year || month || day || hour || minute || second || us;
388hashdecl qore_time_info :
public qore_simple_tm {
392 const AbstractQoreZoneInfo* zone;
394 DLLLOCAL
void set(
int64 epoch,
unsigned n_us,
int n_utcoffset,
bool n_isdst,
const char* n_zname,
395 const AbstractQoreZoneInfo* n_zone) {
396 zname = n_zname ? n_zname : STATIC_UTC;
397 utcoffset = n_utcoffset;
402 qore_simple_tm::set(epoch + utcoffset, n_us);
405 DLLLOCAL qore_time_info& operator=(
const qore_simple_tm& t) {
421 DLLLOCAL
void copyTo(
qore_tm& info) {
426 info.minute = minute;
427 info.second = second;
429 info.zone_name = zname;
430 info.utc_secs_east = utcoffset;
437hashdecl qore_simple_tm2 :
public qore_simple_tm {
438 DLLLOCAL qore_simple_tm2() {
440 DLLLOCAL qore_simple_tm2(
int n_year,
int n_month,
int n_day,
int n_hour,
int n_minute,
int n_second,
int n_us) {
441 set(year, month, day, hour, minute, second, us);
443 DLLLOCAL qore_simple_tm2(
int64 secs,
unsigned my_us) {
446 DLLLOCAL
void setLiteral(
int64 date,
int usecs) {
449 year = (int)(date / 10000000000ll);
450 date -= year* 10000000000ll;
451 month = (int)(date / 100000000ll);
452 date -= month * 100000000ll;
453 day = (int)(date / 1000000ll);
454 date -= day * 1000000ll;
455 hour = (int)(date / 10000ll);
456 date -= hour * 10000ll;
457 minute = (int)(date / 100ll);
458 second = (int)(date - minute* 100ll);
461 normalize_units2<int, int>(second, us, 1000000);
462 normalize_units2<int, int>(minute, second, 60);
463 normalize_units2<int, int>(hour, minute, 60);
464 normalize_units2<int, int>(day, hour, 24);
469 normalize_units2<int, int>(year, month, 12);
478 normalize_day(year, month, day);
483 DLLLOCAL
void getISOWeek(
int& yr,
int& week,
int& wday)
const;
486DLLLOCAL
void concatOffset(
int utcoffset,
QoreString& str);
488class qore_absolute_time {
489 friend class qore_relative_time;
493 const AbstractQoreZoneInfo* zone;
496 DLLLOCAL
void setLocalIntern(
int n_us) {
498 normalize_units2<int64, int>(epoch, n_us, 1000000);
502 int off = AbstractQoreZoneInfo::getUTCOffset(zone);
504 printd(5,
"qore_absolute_time::setLocalIntern() epoch: %lld -> %lld (std off: %d)\n", epoch, epoch - off, off);
508 int aoff = AbstractQoreZoneInfo::getUTCOffset(zone, epoch);
510 printd(5,
"qore_absolute_time::setLocalIntern() epoch: %lld -> %lld (aoff: %d diff: %d)\n", epoch,
511 epoch - (aoff - off), aoff, aoff - off);
512 epoch -= (aoff - off);
515 printd(5,
"qore_absolute_time::setLocalIntern() epoch: %lld zone: %s\n", epoch,
516 AbstractQoreZoneInfo::getRegionName(zone));
519 DLLLOCAL
void setTM(qore_simple_tm2& tm,
struct tm& tms,
bool dst =
false)
const {
520 tms.tm_year = tm.year - 1900;
521 tms.tm_mon = tm.month - 1;
522 tms.tm_mday = tm.day;
523 tms.tm_hour = tm.hour;
524 tms.tm_min = tm.minute;
525 tms.tm_sec = tm.second;
527 tms.tm_wday = qore_date_info::getDayOfWeek(tm.year, tm.month, tm.day);
528 tms.tm_yday = qore_date_info::getDayNumber(tm.year, tm.month, tm.day) - 1;
532 DLLLOCAL
void setNowIntern() {
537 DLLLOCAL
void set(
const AbstractQoreZoneInfo* n_zone,
const QoreValue v);
539 DLLLOCAL
void set(
const AbstractQoreZoneInfo* n_zone,
int64 n_epoch,
int n_us) {
542 normalize_units2<int64, int>(epoch, n_us, 1000000);
546 DLLLOCAL
void set(
double f,
const AbstractQoreZoneInfo* n_zone =
currentTZ()) {
549 us = (int)((f - (
float)((int)f)) * 1000000);
552 DLLLOCAL
void setLocal(
const AbstractQoreZoneInfo* n_zone,
int64 n_epoch,
int n_us) {
555 normalize_units2<int64, int>(epoch, n_us, 1000000);
556 setLocalIntern(n_us);
559 DLLLOCAL
void set(
const AbstractQoreZoneInfo* n_zone,
int year,
int month,
int day,
int hour,
int minute,
560 int second,
int n_us) {
562 epoch = qore_date_info::getEpochSeconds(year, month, day, hour, minute, second);
564 setLocalIntern(n_us);
570 DLLLOCAL
void set(
const AbstractQoreZoneInfo* n_zone,
int year,
int month,
int day,
int hour,
int minute,
574 epoch = qore_date_info::getEpochSeconds(year, month, day, hour, minute, second);
576 setLocalIntern(n_us);
579 if (month < 1 || month > 12) {
580 xsink->
raiseException(
"INVALID-DATE",
"invalid month value: %d; expecting 1 - 12 inclusive", month);
584 xsink->
raiseException(
"INVALID-DATE",
"invalid day value: %d; day must be > 0", day);
588 int dom = qore_date_info::getLastDayOfMonth(month, year);
590 xsink->
raiseException(
"INVALID-DATE",
"invalid day of the month: %d; %04d-%02 has %d days", day, year,
595 if (hour < 0 || hour > 23) {
596 xsink->
raiseException(
"INVALID-DATE",
"invalid hour value: %d; expecting 0 - 23 inclusive", hour);
599 if (minute < 0 || minute > 60) {
600 xsink->
raiseException(
"INVALID-DATE",
"invalid minute value: %d; expecting 0 - 60 inclusive", minute);
603 if (second < 0 || second > 60) {
604 xsink->
raiseException(
"INVALID-DATE",
"invalid second value: %d; expecting 0 - 60 inclusive", second);
607 if (n_us < 0 || n_us > 999999) {
608 xsink->
raiseException(
"INVALID-DATE",
"invalid microsecond value: %d; expecting 0 - 999999 inclusive", n_us);
616 DLLLOCAL
void set(
const qore_absolute_time& p) {
622 DLLLOCAL
void set(
const char* str,
const AbstractQoreZoneInfo* n_zone =
currentTZ(),
ExceptionSink* xsink = 0);
624 DLLLOCAL
void setZone(
const AbstractQoreZoneInfo* n_zone) {
628 DLLLOCAL
void setTime(
int h,
int m,
int s,
int usecs) {
629 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
633 normalize_units2<int, int>(s, usecs, 1000000);
634 normalize_units2<int, int>(m, s, 60);
635 normalize_units2<int, int>(h, m, 60);
642 epoch = qore_date_info::getEpochSeconds(tm.year, tm.month, tm.day, h, m, s);
643 setLocalIntern(usecs);
646 DLLLOCAL
void setLiteral(
int64 date,
int usecs = 0) {
652 tm.setLiteral(date, usecs);
655 epoch = qore_date_info::getEpochSeconds(tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);
658 setLocalIntern(usecs);
661 DLLLOCAL
void setNow() {
667 DLLLOCAL
void setNow(
const AbstractQoreZoneInfo* n_zone) {
672 DLLLOCAL
void getISOWeek(
int& yr,
int& week,
int& wday)
const {
673 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
674 tm.getISOWeek(yr, week, wday);
677 DLLLOCAL
void get(qore_time_info& info)
const {
680 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst, zname);
682 info.set(epoch, us, offset, isdst, zname, zone);
685 DLLLOCAL
void get(
const AbstractQoreZoneInfo* z, qore_time_info& info)
const {
688 int offset = AbstractQoreZoneInfo::getUTCOffset(z, epoch, isdst, zname);
689 info.set(epoch, us, offset, isdst, zname, zone);
692 DLLLOCAL
void getDate(qore_simple_tm& tm)
const {
693 int off = AbstractQoreZoneInfo::getUTCOffset(zone, epoch);
694 tm.set(epoch + off, us);
697 DLLLOCAL
short getYear()
const {
698 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
702 DLLLOCAL
int getMonth()
const {
703 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
707 DLLLOCAL
int getDay()
const {
708 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
712 DLLLOCAL
int getHour()
const {
714 return (
int)(((epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch)) % SECS_PER_DAY) / SECS_PER_HOUR);
719 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst, zname);
720 info.set(epoch, us, offset, isdst, zname, zone);
724 DLLLOCAL
int getMinute()
const {
726 return (
int)(((epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch)) % SECS_PER_HOUR) / SECS_PER_MINUTE);
731 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst, zname);
732 info.set(epoch, us, offset, isdst, zname, zone);
736 DLLLOCAL
int getSecond()
const {
738 return ((epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch)) % SECS_PER_MINUTE);
743 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst, zname);
744 info.set(epoch, us, offset, isdst, zname, zone);
748 DLLLOCAL
int getMillisecond()
const {
752 DLLLOCAL
int getMicrosecond()
const {
756 DLLLOCAL
int64 getRelativeSeconds()
const {
757 return getRelativeMicroseconds() / 1000000;
760 DLLLOCAL
int64 getRelativeMilliseconds()
const {
761 return getRelativeMicroseconds() / 1000;
764 DLLLOCAL
int64 getRelativeMicroseconds()
const;
766 DLLLOCAL
double getRelativeSecondsDouble()
const {
767 return ((
double)getRelativeMicroseconds()) / 1000000.0;
770 DLLLOCAL
void localtime(
struct tm& tms)
const {
772 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst);
773 qore_simple_tm2 tm(epoch + offset, us);
775 setTM(tm, tms, isdst);
778 DLLLOCAL
void gmtime(
struct tm& tms)
const {
779 qore_simple_tm2 tm(epoch, us);
780 setTM(tm, tms,
false);
783 DLLLOCAL
int compare(
const qore_absolute_time& r)
const {
795 DLLLOCAL
int getDayOfWeek()
const {
796 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
797 return qore_date_info::getDayOfWeek(tm.year, tm.month, tm.day);
800 DLLLOCAL
int getDayNumber()
const {
801 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
802 return qore_date_info::getDayNumber(tm.year, tm.month, tm.day);
805 DLLLOCAL
bool hasValue()
const {
806 return epoch || us ? true :
false;
809 DLLLOCAL
int64 getEpochSeconds()
const {
810 return epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch);
813 DLLLOCAL
int64 getEpochMilliseconds()
const {
814 return getEpochSeconds() * 1000 + (us / 1000);
817 DLLLOCAL
int64 getEpochMicroseconds()
const {
818 return getEpochSeconds() * 1000000 + us;
821 DLLLOCAL
int64 getEpochSecondsUTC()
const {
825 DLLLOCAL
int64 getEpochMicrosecondsUTC()
const {
826 return epoch * 1000000 + us;
829 DLLLOCAL
int64 getEpochMillisecondsUTC()
const {
830 return epoch * 1000 + (us / 1000);
833 DLLLOCAL qore_absolute_time& operator+=(
const qore_relative_time& dt);
834 DLLLOCAL qore_absolute_time& operator-=(
const qore_relative_time& dt);
836 DLLLOCAL
void getAsString(
QoreString& str)
const;
838 DLLLOCAL
void unaryMinus() {
843 DLLLOCAL
const AbstractQoreZoneInfo* getZone()
const {
847 DLLLOCAL
void addSecondsTo(
int64 secs,
int n_us = 0) {
848 set(zone, epoch + secs, us + n_us);
852class qore_relative_time :
public qore_simple_tm {
853friend class qore_absolute_time;
855 DLLLOCAL
void normalize(
bool for_comparison =
false) {
859 normalize_units<int, int>(second, us, 1000000);
862 normalize_units<int, int>(minute, second, 60);
865 normalize_units<int, int>(hour, minute, 60);
869 if (for_comparison) {
870 normalize_units<int, int>(day, hour, 24);
871 normalize_units<int, int>(year, day, 365);
872 normalize_units<int, int>(month, day, 31);
876 normalize_units<int, int>(year, month, 12);
879 DLLLOCAL
void setIso8601(
const char* str);
882 DLLLOCAL
void set(
int n_year,
int n_month,
int n_day,
int n_hour,
int n_minute,
int n_second,
int n_us) {
883 qore_simple_tm::set(n_year, n_month, n_day, n_hour, n_minute, n_second, n_us);
889 DLLLOCAL
void set(
const char* str);
891 DLLLOCAL
void set(
const qore_relative_time& p) {
902 DLLLOCAL
void setDifference(
int64 seconds,
int micros,
const qore_absolute_time& dt) {
903 int64 sec = seconds - dt.epoch;
906 year = month = day = hour = minute = 0;
909 normalize_units<int64, int>(sec, us, 1000000);
914 normalize_units<int, int64>(hour, sec, 3600);
917 normalize_units<int, int64>(minute, sec, 60);
922 DLLLOCAL
void setLiteral(
int64 date,
int usecs = 0) {
923 year = (int)(date / 10000000000ll);
924 date -= year* 10000000000ll;
925 month = (int)(date / 100000000ll);
926 date -= month * 100000000ll;
927 day = (int)(date / 1000000ll);
928 date -= day * 1000000ll;
929 hour = (int)(date / 10000ll);
930 date -= hour * 10000ll;
931 minute = (int)(date / 100ll);
932 second = (int)(date - minute* 100ll);
938 DLLLOCAL
void addFractionalYear(
double d) {
942 addFractionalDay(d - dy);
946 DLLLOCAL
void addFractionalMonth(
double d) {
950 addFractionalDay(d - dy);
953 DLLLOCAL
void addFractionalDay(
double d) {
957 addFractionalHour(d - h);
960 DLLLOCAL
void addFractionalHour(
double d) {
964 addFractionalMinute(d - m);
967 DLLLOCAL
void addFractionalMinute(
double d) {
971 addFractionalSecond(d - s);
974 DLLLOCAL
void addFractionalSecond(
double d) {
979 DLLLOCAL
void setSeconds(
int64 s,
int usecs = 0) {
993 DLLLOCAL
void setTime(
int h,
int m,
int s,
int usecs) {
1000 DLLLOCAL
short getYear()
const {
1004 DLLLOCAL
int getMonth()
const {
1008 DLLLOCAL
int getDay()
const {
1012 DLLLOCAL
int getHour()
const {
1016 DLLLOCAL
int getMinute()
const {
1020 DLLLOCAL
int getSecond()
const {
1024 DLLLOCAL
int getMillisecond()
const {
1028 DLLLOCAL
int getMicrosecond()
const {
1032 DLLLOCAL
int compare(
const qore_relative_time& rt)
const {
1034 qore_relative_time l;
1035 l.set(year, month, day, hour, minute, second, us);
1037 qore_relative_time r;
1038 r.set(rt.year, rt.month, rt.day, rt.hour, rt.minute, rt.second, rt.us);
1041 if (l.year > r.year)
1043 if (l.year < r.year)
1045 if (l.month > r.month)
1047 if (l.month < r.month)
1053 if (l.hour > r.hour)
1055 if (l.hour < r.hour)
1057 if (l.minute > r.minute)
1059 if (l.minute < r.minute)
1061 if (l.second > r.second)
1063 if (l.second < r.second)
1072 DLLLOCAL
void unaryMinus() {
1082 DLLLOCAL
int64 getRelativeSeconds()
const {
1083 return getRelativeMicroseconds() / 1000000;
1086 DLLLOCAL
int64 getRelativeMilliseconds()
const {
1087 return getRelativeMicroseconds() / 1000;
1090 DLLLOCAL
int64 getRelativeMicroseconds()
const {
1091 return (
int64)us + (
int64)second * MICROSECS_PER_SEC
1092 + (
int64)minute* MICROSECS_PER_MINUTE
1093 + (
int64)hour * MICROSECS_PER_HOUR
1094 + (
int64)day * MICROSECS_PER_AVG_DAY
1095 + (month ? (
int64)month * MICROSECS_PER_MAX_MONTH : 0ll)
1096 + (year ? (
int64)year * MICROSECS_PER_AVG_YEAR : 0ll);
1099 DLLLOCAL
double getRelativeSecondsDouble()
const {
1100 return ((
double)getRelativeMicroseconds()) / 1000000.0;
1103 DLLLOCAL qore_relative_time& operator+=(
const qore_relative_time& dt);
1104 DLLLOCAL qore_relative_time& operator-=(
const qore_relative_time& dt);
1105 DLLLOCAL qore_relative_time& operator-=(
const qore_absolute_time& dt);
1107 DLLLOCAL
void getAsString(
QoreString& str)
const {
1111#define PL(n) (n == 1 ? "" : "s")
1114 str.
sprintf(
" %d year%s", year, PL(year)), f++;
1116 str.
sprintf(
" %d month%s", month, PL(month)), f++;
1118 str.
sprintf(
" %d day%s", day, PL(day)), f++;
1120 str.
sprintf(
" %d hour%s", hour, PL(hour)), f++;
1122 str.
sprintf(
" %d minute%s", minute, PL(minute)), f++;
1123 if (second || (!f && !us))
1124 str.
sprintf(
" %d second%s", second, PL(second));
1128 if (ms * 1000 == us)
1129 str.
sprintf(
" %d millisecond%s", ms, PL(ms));
1131 str.
sprintf(
" %d microsecond%s", us, PL(us));
1139 DLLLOCAL
void getTM(
struct tm& tms)
const {
1144 tms.tm_min = minute;
1145 tms.tm_sec = second;
1151 DLLLOCAL
void get(qore_time_info& info)
const {
1160 DLLLOCAL
void zero() {
1161 qore_simple_tm::zero();
1164 DLLLOCAL
bool hasValue()
const {
1165 return qore_simple_tm::hasValue();
1168 DLLLOCAL
void addSecondsTo(
double secs) {
1169 addSecondsTo((
int64)secs, (
int)((secs - (
float)((
int)secs)) * 1000000));
1172 DLLLOCAL
void addSecondsTo(
int64 secs,
int n_us = 0) {
1173 int h = secs / 3600;
1187static inline void zero_tm(
struct tm& tms) {
1200class qore_date_private {
1201friend class qore_absolute_time;
1202friend class qore_relative_time;
1209 qore_absolute_time abs;
1210 qore_relative_time rel;
1215 DLLLOCAL qore_date_private(
bool r =
false) : relative(r) {
1222 DLLLOCAL qore_date_private(
const AbstractQoreZoneInfo* zone,
const QoreValue v) : relative(false) {
1226 DLLLOCAL qore_date_private(
const AbstractQoreZoneInfo* zone,
int64 seconds,
int us = 0) : relative(false) {
1227 d.abs.set(zone, seconds, us);
1230 DLLLOCAL qore_date_private(
const AbstractQoreZoneInfo* zone,
int y,
int mo,
int dy,
int h,
int mi,
int s,
int us) : relative(false) {
1231 d.abs.set(zone, y, mo, dy, h, mi, s, us);
1234 DLLLOCAL qore_date_private(
const AbstractQoreZoneInfo* zone,
int y,
int mo,
int dy,
int h,
int mi,
int s,
int us,
ExceptionSink* xsink) : relative(false) {
1235 d.abs.set(zone, y, mo, dy, h, mi, s, us, xsink);
1238 DLLLOCAL qore_date_private(
const QoreValue v) : relative(true) {
1243 DLLLOCAL qore_date_private(
int y,
int mo,
int dy,
int h,
int mi,
int s,
int us,
bool r) : relative(r) {
1245 d.rel.set(y, mo, dy, h, mi, s, us);
1247 d.abs.set(
currentTZ(), y, mo, dy, h, mi, s, us);
1250 DLLLOCAL
static int compare(
const qore_date_private& left,
const qore_date_private& right) {
1253 return right.relative ? left.d.rel.compare(right.d.rel) : -1;
1255 return right.relative ? 1 : left.d.abs.compare(right.d.abs);
1258 DLLLOCAL qore_date_private& operator=(
const qore_date_private& p) {
1264 relative = p.relative;
1268 DLLLOCAL
void setNow() {
1273 DLLLOCAL
void setNow(
const AbstractQoreZoneInfo* n_zone) {
1275 d.abs.setNow(n_zone);
1278 DLLLOCAL
void setDate(
const qore_date_private& p) {
1283 DLLLOCAL
void setDate(
const struct tm& tms,
int us) {
1286 d.abs.set(
currentTZ(), 1900 + tms.tm_year, tms.tm_mon + 1, tms.tm_mday, tms.tm_hour, tms.tm_min, tms.tm_sec, us);
1289 DLLLOCAL
void setAbsoluteDate(
const char* str,
const AbstractQoreZoneInfo* zone =
currentTZ(),
ExceptionSink* xsink = 0);
1290 DLLLOCAL
void setRelativeDate(
const char* str);
1292 DLLLOCAL
void setDate(
const char* str);
1293 DLLLOCAL
void setDate(
const char* str,
ExceptionSink* xsink);
1295 DLLLOCAL
bool isRelative()
const {
1299 DLLLOCAL
void setZone(
const AbstractQoreZoneInfo* n_zone) {
1301 d.abs.setZone(n_zone);
1304 DLLLOCAL
short getYear()
const {
1305 return relative ? d.rel.getYear() : d.abs.getYear();
1308 DLLLOCAL
int getMonth()
const {
1309 return relative ? d.rel.getMonth() : d.abs.getMonth();
1312 DLLLOCAL
int getDay()
const {
1313 return relative ? d.rel.getDay() : d.abs.getDay();
1316 DLLLOCAL
int getHour()
const {
1317 return relative ? d.rel.getHour() : d.abs.getHour();
1320 DLLLOCAL
int getMinute()
const {
1321 return relative ? d.rel.getMinute() : d.abs.getMinute();
1324 DLLLOCAL
int getSecond()
const {
1325 return relative ? d.rel.getSecond() : d.abs.getSecond();
1328 DLLLOCAL
int getMillisecond()
const {
1329 return relative ? d.rel.getMillisecond() : d.abs.getMillisecond();
1332 DLLLOCAL
int getMicrosecond()
const {
1333 return relative ? d.rel.getMicrosecond() : d.abs.getMicrosecond();
1336 DLLLOCAL
bool hasValue()
const {
1337 return relative ? d.rel.hasValue() : d.abs.hasValue();
1340 DLLLOCAL
int64 getEpochSeconds()
const {
1341 return relative ? d.rel.getRelativeSeconds() : d.abs.getEpochSeconds();
1344 DLLLOCAL
int64 getEpochSecondsUTC()
const {
1345 return relative ? d.rel.getRelativeSeconds() : d.abs.getEpochSecondsUTC();
1348 DLLLOCAL
int64 getEpochMillisecondsUTC()
const {
1349 return relative ? d.rel.getRelativeMilliseconds() : d.abs.getEpochMillisecondsUTC();
1352 DLLLOCAL
int64 getEpochMicrosecondsUTC()
const {
1353 return relative ? d.rel.getRelativeMicroseconds() : d.abs.getEpochMicrosecondsUTC();
1356 DLLLOCAL
int getDayNumber()
const {
1357 return relative ? 0 : d.abs.getDayNumber();
1361 DLLLOCAL
void add(
const qore_date_private& dt) {
1366 setDate(getEpochSecondsUTC() + dt.d.abs.getEpochSecondsUTC(), d.abs.getMicrosecond()
1367 + dt.d.abs.getMicrosecond());
1372 assert(dt.relative);
1376 DLLLOCAL
void unaryMinus() {
1384 DLLLOCAL
void subtractBy(
const qore_date_private& dt) {
1389 int64 secs = d.abs.getEpochSecondsUTC();
1390 int us = d.abs.getMicrosecond();
1392 d.rel.setDifference(secs, us, dt.d.abs);
1403 DLLLOCAL
void addSecondsTo(
int64 secs,
int us) {
1405 d.abs.addSecondsTo(secs, us);
1407 d.rel.addSecondsTo(secs, us);
1410 DLLLOCAL
void setTime(
int h,
int m,
int s,
int us) {
1412 d.rel.setTime(h, m, s, us);
1414 d.abs.setTime(h, m, s, us);
1417 DLLLOCAL
void setDate(
const AbstractQoreZoneInfo* n_zone,
int year,
int month,
int day,
int hour,
int minute,
1418 int second,
int n_us) {
1420 d.abs.set(n_zone, year, month, day, hour, minute, second, n_us);
1423 DLLLOCAL
void setDate(
const AbstractQoreZoneInfo* zone,
int64 seconds,
int us = 0) {
1425 d.abs.set(zone, seconds, us);
1428 DLLLOCAL
void setDate(
int64 seconds,
int us = 0) {
1433 DLLLOCAL
void setLocalDate(
int64 seconds,
int us) {
1435 d.abs.setLocal(
currentTZ(), seconds, us);
1438 DLLLOCAL
void setLocalDate(
const AbstractQoreZoneInfo* zone,
int64 seconds,
int us) {
1440 d.abs.setLocal(zone, seconds, us);
1443 DLLLOCAL
void setDateLiteral(
int64 date,
int us = 0) {
1445 d.abs.setLiteral(date, us);
1448 DLLLOCAL
void setRelativeDateLiteral(
int64 date,
int us = 0) {
1450 d.rel.setLiteral(date, us);
1453 DLLLOCAL
void setRelativeDateSeconds(
int64 s,
int us = 0) {
1455 d.rel.setSeconds(s, us);
1458 DLLLOCAL
int64 getRelativeSeconds()
const {
1459 return relative ? d.rel.getRelativeSeconds() : d.abs.getRelativeSeconds();
1462 DLLLOCAL
int64 getRelativeMilliseconds()
const {
1463 return relative ? d.rel.getRelativeMilliseconds() : d.abs.getRelativeMilliseconds();
1466 DLLLOCAL
int64 getRelativeMicroseconds()
const {
1467 return relative ? d.rel.getRelativeMicroseconds() : d.abs.getRelativeMicroseconds();
1470 DLLLOCAL
double getRelativeSecondsDouble()
const {
1471 return relative ? d.rel.getRelativeSecondsDouble() : d.abs.getRelativeSecondsDouble();
1474 DLLLOCAL
int getDayOfWeek()
const {
1475 return relative ? 0 : d.abs.getDayOfWeek();
1478 DLLLOCAL
void getISOWeek(
int& yr,
int& week,
int& wday)
const {
1484 return d.abs.getISOWeek(yr, week, wday);
1487 DLLLOCAL
bool isEqual(
const qore_date_private& dt)
const {
1488 return !compare(*
this, dt);
1491 DLLLOCAL
void localtime(
struct tm& tms)
const {
1495 d.abs.localtime(tms);
1498 DLLLOCAL
void gmtime(
struct tm& tms)
const {
1506 DLLLOCAL
void get(qore_time_info& info)
const {
1513 DLLLOCAL
void get(
const AbstractQoreZoneInfo* zone, qore_time_info& info)
const {
1517 d.abs.get(zone, info);
1520 DLLLOCAL
void format(
QoreString& str,
const char* fmt)
const;
1522 DLLLOCAL
void getAsString(
QoreString& str)
const {
1524 d.abs.getAsString(str);
1526 d.rel.getAsString(str);
1531 DLLLOCAL
static qore_date_private* getDateFromISOWeek(qore_date_private& result,
int year,
int week,
int day,
1534 xsink->
raiseException(
"ISO-8601-INVALID-WEEK",
"week numbers must be positive (value passed: %d)", week);
1539 int jan1 = qore_date_info::getDayOfWeek(year, 1, 1);
1543 int mw = 52 + ((jan1 == 4 && !qore_date_info::isLeapYear(year))
1544 || (jan1 == 3 && qore_date_info::isLeapYear(year)));
1546 xsink->
raiseException(
"ISO-8601-INVALID-WEEK",
"there are only %d calendar weeks in year %d (week "
1547 "value passed: %d)", mw, year, week);
1552 if (day < 1 || day > 7) {
1553 xsink->
raiseException(
"ISO-8601-INVALID-DAY",
"calendar week days must be between 1 and 7 for Mon - Sun "
1554 "(day value passed: %d)", day);
1567 else if (jan1 > 1 && jan1 < 5) {
1582 result.setLocalDate(qore_date_info::getEpochSeconds(y, m, d) + ((week - 1) * 7 + (day - 1)) * 86400, 0);
1586 DLLLOCAL
const AbstractQoreZoneInfo* getZone()
const {
1587 return relative ? 0 : d.abs.getZone();
DLLEXPORT int64 q_epoch_us(int &us)
returns the seconds and microseconds from the epoch
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:50
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:93
DLLEXPORT void concat(const QoreString *str, ExceptionSink *xsink)
concatenates a string and converts encodings if necessary
DLLEXPORT int sprintf(const char *fmt,...)
this will concatentate a formatted string to the existing string according to the format string and t...
long long int64
64bit integer type, cannot use int64_t here since it breaks the API on some 64-bit systems due to equ...
Definition: common.h:260
DLLEXPORT const AbstractQoreZoneInfo * currentTZ()
returns the current local time zone, note that if 0 = UTC
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:276
for returning broken-down time information
Definition: DateTime.h:41