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)
80 template <
typename T1,
typename T2>
81 DLLLOCAL
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);
95 else if (bigger < 0 && smaller > 0) {
102 template <
typename T1,
typename T2>
103 DLLLOCAL
void normalize_units2(T1& bigger, T2& smaller,
int ratio) {
104 if (smaller <= -ratio || smaller >= ratio) {
105 int64 units = smaller / ratio;
107 smaller -= (T2)(units * ratio);
118 template <
typename T1>
119 DLLLOCAL
void normalize_units3(T1& bigger,
unsigned& smaller,
unsigned ratio) {
120 if (smaller >= ratio) {
121 int64 units = smaller / ratio;
123 smaller -= (int)(units * ratio);
127 hashdecl qore_date_info {
129 DLLLOCAL
static const int month_lengths[];
131 DLLLOCAL
static const int positive_months[];
132 DLLLOCAL
static const int negative_months[];
134 DLLLOCAL
static bool isLeapYear(
int year);
142 DLLLOCAL
static void get_epoch_year(
int64 &epoch,
int& year,
bool& ly) {
144 epoch -= SECS_TO_2KLD;
147 int64 mult = epoch / SECS_IN_400_YEARS;
149 epoch %= SECS_IN_400_YEARS;
153 epoch = LEAPDAY_OFFSET + SECS_PER_DAY;
154 year = (int)(mult * 400 + 2000);
162 epoch += SECS_IN_400_YEARS;
169 int64 d = epoch / SECS_IN_100_YEARS;
176 epoch -= d * SECS_IN_100_YEARS;
183 d = epoch / SECS_IN_4_YEARS;
185 epoch %= SECS_IN_4_YEARS;
192 ly = epoch < SECS_AFTER_LD || epoch >= (SECS_PER_YEAR * 4);
197 d = epoch / SECS_PER_YEAR;
202 epoch -= d * SECS_PER_YEAR;
206 year = (int)(mult * 400 + 2000 + yo);
212 if (epoch >= SECS_AFTER_LD) {
214 epoch -= SECS_AFTER_LD;
218 epoch += LEAPDAY_OFFSET;
220 epoch += SECS_PER_DAY;
227 DLLLOCAL
static int leap_days_from_epoch(
int year,
int month) {
228 assert(month > 0 && month < 13);
232 d = year/4 - year/100 + year/400 - 477;
233 if (month < 3 && isLeapYear(year))
238 d = year/4 - year/100 + year/400 - 477;
243 if (month > 2 && isLeapYear(year + 1))
249 DLLLOCAL
static int getLastDayOfMonth(
int month,
int year) {
250 assert(month > 0 && month < 13);
252 return qore_date_info::month_lengths[month];
253 return qore_date_info::isLeapYear(year) ? 29 : 28;
256 DLLLOCAL
static int getDayOfWeek(
int year,
int month,
int day) {
257 assert(month > 0 && month < 13);
258 int a = (14 - month) / 12;
260 int m = month + 12 * a - 2;
261 return (day + y + y / 4 - y / 100 + y / 400 + (31 * m / 12)) % 7;
265 DLLLOCAL
static int64 getEpochSeconds(
int year,
int month,
int day) {
275 int64 epoch = (year - 1970) * SECS_PER_YEAR + (positive_months[month - 1] + day - 1 + 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 + (month > 2 && qore_date_info::isLeapYear(year) ? 1 : 0);
297 DLLLOCAL
static int getMonthIxFromAbbr(
const char* abbr);
301 DLLLOCAL
void normalize_dm(
int& year,
int& month,
int& day);
304 DLLLOCAL
void normalize_day(
int& year,
int& month,
int& day);
306 class qore_relative_time;
308 DLLLOCAL
extern const char *STATIC_UTC;
310 hashdecl qore_simple_tm {
322 DLLLOCAL
void zero() {
332 DLLLOCAL
void set(
int n_year,
int n_month,
int n_day,
int n_hour,
int n_minute,
int n_second,
int n_us) {
343 DLLLOCAL
void set(
int64 seconds,
unsigned my_us) {
344 normalize_units3<int64>(seconds, my_us, 1000000);
351 qore_date_info::get_epoch_year(seconds, year, ly);
355 day = (int)(seconds / SECS_PER_DAY);
356 seconds %= SECS_PER_DAY;
358 for (month = 1; month < 12; ++month) {
359 int ml = qore_date_info::month_lengths[month];
360 if (ly && month == 2)
371 second = (int)seconds;
372 hour = second / SECS_PER_HOUR;
373 second %= SECS_PER_HOUR;
374 minute = second / SECS_PER_MINUTE;
375 second %= SECS_PER_MINUTE;
380 DLLLOCAL
bool hasValue()
const {
381 return year || month || day || hour || minute || second || us;
386 hashdecl qore_time_info :
public qore_simple_tm {
390 const AbstractQoreZoneInfo* zone;
392 DLLLOCAL
void set(
int64 epoch,
unsigned n_us,
int n_utcoffset,
bool n_isdst,
const char* n_zname,
const AbstractQoreZoneInfo* n_zone) {
393 zname = n_zname ? n_zname : STATIC_UTC;
394 utcoffset = n_utcoffset;
398 qore_simple_tm::set(epoch + utcoffset, n_us);
401 DLLLOCAL qore_time_info& operator=(
const qore_simple_tm& t) {
417 DLLLOCAL
void copyTo(
qore_tm& info) {
422 info.minute = minute;
423 info.second = second;
425 info.zone_name = zname;
426 info.utc_secs_east = utcoffset;
433 hashdecl qore_simple_tm2 :
public qore_simple_tm {
434 DLLLOCAL qore_simple_tm2() {
436 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) {
437 set(year, month, day, hour, minute, second, us);
439 DLLLOCAL qore_simple_tm2(
int64 secs,
unsigned my_us) {
442 DLLLOCAL
void setLiteral(
int64 date,
int usecs) {
445 year = (int)(date / 10000000000ll);
446 date -= year* 10000000000ll;
447 month = (int)(date / 100000000ll);
448 date -= month * 100000000ll;
449 day = (int)(date / 1000000ll);
450 date -= day * 1000000ll;
451 hour = (int)(date / 10000ll);
452 date -= hour * 10000ll;
453 minute = (int)(date / 100ll);
454 second = (int)(date - minute* 100ll);
457 normalize_units2<int, int>(second, us, 1000000);
458 normalize_units2<int, int>(minute, second, 60);
459 normalize_units2<int, int>(hour, minute, 60);
460 normalize_units2<int, int>(day, hour, 24);
465 normalize_units2<int, int>(year, month, 12);
475 normalize_day(year, month, day);
479 DLLLOCAL
void getISOWeek(
int& yr,
int& week,
int& wday)
const;
482 DLLLOCAL
void concatOffset(
int utcoffset,
QoreString& str);
484 class qore_absolute_time {
485 friend class qore_relative_time;
489 const AbstractQoreZoneInfo* zone;
492 DLLLOCAL
void setLocalIntern(
int n_us) {
494 normalize_units2<int64, int>(epoch, n_us, 1000000);
498 int off = AbstractQoreZoneInfo::getUTCOffset(zone);
500 printd(5,
"qore_absolute_time::setLocalIntern() epoch: %lld -> %lld (std off: %d)\n", epoch, epoch - off, off);
504 int aoff = AbstractQoreZoneInfo::getUTCOffset(zone, epoch);
506 printd(5,
"qore_absolute_time::setLocalIntern() epoch: %lld -> %lld (aoff: %d diff: %d)\n", epoch, epoch - (aoff - off), aoff, aoff - off);
507 epoch -= (aoff - off);
510 printd(5,
"qore_absolute_time::setLocalIntern() epoch: %lld zone: %s\n", epoch, AbstractQoreZoneInfo::getRegionName(zone));
513 DLLLOCAL
void setTM(qore_simple_tm2& tm,
struct tm& tms,
bool dst =
false)
const {
514 tms.tm_year = tm.year - 1900;
515 tms.tm_mon = tm.month - 1;
516 tms.tm_mday = tm.day;
517 tms.tm_hour = tm.hour;
518 tms.tm_min = tm.minute;
519 tms.tm_sec = tm.second;
521 tms.tm_wday = qore_date_info::getDayOfWeek(tm.year, tm.month, tm.day);
522 tms.tm_yday = qore_date_info::getDayNumber(tm.year, tm.month, tm.day) - 1;
526 DLLLOCAL
void setNowIntern() {
531 DLLLOCAL
void set(
const AbstractQoreZoneInfo* n_zone,
const QoreValue v);
533 DLLLOCAL
void set(
const AbstractQoreZoneInfo* n_zone,
int64 n_epoch,
int n_us) {
536 normalize_units2<int64, int>(epoch, n_us, 1000000);
540 DLLLOCAL
void set(
double f,
const AbstractQoreZoneInfo* n_zone =
currentTZ()) {
543 us = (int)((f - (
float)((int)f)) * 1000000);
546 DLLLOCAL
void setLocal(
const AbstractQoreZoneInfo* n_zone,
int64 n_epoch,
int n_us) {
549 normalize_units2<int64, int>(epoch, n_us, 1000000);
550 setLocalIntern(n_us);
553 DLLLOCAL
void set(
const AbstractQoreZoneInfo* n_zone,
int year,
int month,
int day,
int hour,
int minute,
int second,
int n_us) {
555 epoch = qore_date_info::getEpochSeconds(year, month, day, hour, minute, second);
557 setLocalIntern(n_us);
562 DLLLOCAL
void set(
const AbstractQoreZoneInfo* n_zone,
int year,
int month,
int day,
int hour,
int minute,
int second,
int n_us,
ExceptionSink* xsink) {
565 epoch = qore_date_info::getEpochSeconds(year, month, day, hour, minute, second);
567 setLocalIntern(n_us);
570 if (month < 1 || month > 12) {
571 xsink->
raiseException(
"INVALID-DATE",
"invalid month value: %d; expecting 1 - 12 inclusive", month);
575 xsink->
raiseException(
"INVALID-DATE",
"invalid day value: %d; day must be > 0", day);
579 int dom = qore_date_info::getLastDayOfMonth(month, year);
581 xsink->
raiseException(
"INVALID-DATE",
"invalid day of the month: %d; %04d-%02 has %d days", day, year, month, dom);
585 if (hour < 0 || hour > 23) {
586 xsink->
raiseException(
"INVALID-DATE",
"invalid hour value: %d; expecting 0 - 23 inclusive", hour);
589 if (minute < 0 || minute > 60) {
590 xsink->
raiseException(
"INVALID-DATE",
"invalid minute value: %d; expecting 0 - 60 inclusive", minute);
593 if (second < 0 || second > 60) {
594 xsink->
raiseException(
"INVALID-DATE",
"invalid second value: %d; expecting 0 - 60 inclusive", second);
597 if (n_us < 0 || n_us > 999999) {
598 xsink->
raiseException(
"INVALID-DATE",
"invalid microsecond value: %d; expecting 0 - 999999 inclusive", n_us);
605 DLLLOCAL
void set(
const qore_absolute_time& p) {
611 DLLLOCAL
void set(
const char* str,
const AbstractQoreZoneInfo* n_zone =
currentTZ(),
ExceptionSink* xsink = 0);
613 DLLLOCAL
void setZone(
const AbstractQoreZoneInfo* n_zone) {
617 DLLLOCAL
void setTime(
int h,
int m,
int s,
int usecs) {
618 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
621 normalize_units2<int, int>(s, usecs, 1000000);
622 normalize_units2<int, int>(m, s, 60);
623 normalize_units2<int, int>(h, m, 60);
630 epoch = qore_date_info::getEpochSeconds(tm.year, tm.month, tm.day, h, m, s);
631 setLocalIntern(usecs);
634 DLLLOCAL
void setLiteral(
int64 date,
int usecs = 0) {
640 tm.setLiteral(date, usecs);
643 epoch = qore_date_info::getEpochSeconds(tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);
645 setLocalIntern(usecs);
648 DLLLOCAL
void setNow() {
654 DLLLOCAL
void setNow(
const AbstractQoreZoneInfo* n_zone) {
659 DLLLOCAL
void getISOWeek(
int& yr,
int& week,
int& wday)
const {
660 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
661 tm.getISOWeek(yr, week, wday);
664 DLLLOCAL
void get(qore_time_info& info)
const {
667 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst, zname);
669 info.set(epoch, us, offset, isdst, zname, zone);
672 DLLLOCAL
void get(
const AbstractQoreZoneInfo* z, qore_time_info& info)
const {
675 int offset = AbstractQoreZoneInfo::getUTCOffset(z, epoch, isdst, zname);
676 info.set(epoch, us, offset, isdst, zname, zone);
679 DLLLOCAL
void getDate(qore_simple_tm& tm)
const {
680 int off = AbstractQoreZoneInfo::getUTCOffset(zone, epoch);
681 tm.set(epoch + off, us);
684 DLLLOCAL
short getYear()
const {
685 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
689 DLLLOCAL
int getMonth()
const {
690 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
694 DLLLOCAL
int getDay()
const {
695 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
699 DLLLOCAL
int getHour()
const {
701 return (
int)(((epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch)) % SECS_PER_DAY) / SECS_PER_HOUR);
706 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst, zname);
707 info.set(epoch, us, offset, isdst, zname, zone);
711 DLLLOCAL
int getMinute()
const {
713 return (
int)(((epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch)) % SECS_PER_HOUR) / SECS_PER_MINUTE);
718 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst, zname);
719 info.set(epoch, us, offset, isdst, zname, zone);
723 DLLLOCAL
int getSecond()
const {
725 return ((epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch)) % SECS_PER_MINUTE);
730 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst, zname);
731 info.set(epoch, us, offset, isdst, zname, zone);
735 DLLLOCAL
int getMillisecond()
const {
739 DLLLOCAL
int getMicrosecond()
const {
743 DLLLOCAL
int64 getRelativeSeconds()
const {
744 return getRelativeMicroseconds() / 1000000;
747 DLLLOCAL
int64 getRelativeMilliseconds()
const {
748 return getRelativeMicroseconds() / 1000;
751 DLLLOCAL
int64 getRelativeMicroseconds()
const;
753 DLLLOCAL
double getRelativeSecondsDouble()
const {
754 return ((
double)getRelativeMicroseconds()) / 1000000.0;
757 DLLLOCAL
void localtime(
struct tm& tms)
const {
759 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst);
760 qore_simple_tm2 tm(epoch + offset, us);
762 setTM(tm, tms, isdst);
765 DLLLOCAL
void gmtime(
struct tm& tms)
const {
766 qore_simple_tm2 tm(epoch, us);
767 setTM(tm, tms,
false);
770 DLLLOCAL
int compare(
const qore_absolute_time& r)
const {
782 DLLLOCAL
int getDayOfWeek()
const {
783 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
784 return qore_date_info::getDayOfWeek(tm.year, tm.month, tm.day);
787 DLLLOCAL
int getDayNumber()
const {
788 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
789 return qore_date_info::getDayNumber(tm.year, tm.month, tm.day);
792 DLLLOCAL
bool hasValue()
const {
793 return epoch || us ? true :
false;
796 DLLLOCAL
int64 getEpochSeconds()
const {
797 return epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch);
800 DLLLOCAL
int64 getEpochMilliseconds()
const {
801 return getEpochSeconds() * 1000 + (us / 1000);
804 DLLLOCAL
int64 getEpochMicroseconds()
const {
805 return getEpochSeconds() * 1000000 + us;
808 DLLLOCAL
int64 getEpochSecondsUTC()
const {
812 DLLLOCAL
int64 getEpochMicrosecondsUTC()
const {
813 return epoch * 1000000 + us;
816 DLLLOCAL
int64 getEpochMillisecondsUTC()
const {
817 return epoch * 1000 + (us / 1000);
820 DLLLOCAL qore_absolute_time& operator+=(
const qore_relative_time& dt);
821 DLLLOCAL qore_absolute_time& operator-=(
const qore_relative_time& dt);
823 DLLLOCAL
void getAsString(
QoreString& str)
const;
825 DLLLOCAL
void unaryMinus() {
830 DLLLOCAL
const AbstractQoreZoneInfo* getZone()
const {
834 DLLLOCAL
void addSecondsTo(
int64 secs,
int n_us = 0) {
835 set(zone, epoch + secs, us + n_us);
839 class qore_relative_time :
public qore_simple_tm {
840 friend class qore_absolute_time;
842 DLLLOCAL
void normalize(
bool for_comparison =
false) {
846 normalize_units<int, int>(second, us, 1000000);
849 normalize_units<int, int>(minute, second, 60);
852 normalize_units<int, int>(hour, minute, 60);
856 if (for_comparison) {
857 normalize_units<int, int>(day, hour, 24);
858 normalize_units<int, int>(year, day, 365);
859 normalize_units<int, int>(month, day, 31);
863 normalize_units<int, int>(year, month, 12);
866 DLLLOCAL
void setIso8601(
const char* str);
869 DLLLOCAL
void set(
int n_year,
int n_month,
int n_day,
int n_hour,
int n_minute,
int n_second,
int n_us) {
870 qore_simple_tm::set(n_year, n_month, n_day, n_hour, n_minute, n_second, n_us);
876 DLLLOCAL
void set(
const char* str);
878 DLLLOCAL
void set(
const qore_relative_time& p) {
889 DLLLOCAL
void setDifference(
int64 seconds,
int micros,
const qore_absolute_time& dt) {
890 int64 sec = seconds - dt.epoch;
893 year = month = day = hour = minute = 0;
896 normalize_units<int64, int>(sec, us, 1000000);
901 normalize_units<int, int64>(hour, sec, 3600);
904 normalize_units<int, int64>(minute, sec, 60);
909 DLLLOCAL
void setLiteral(
int64 date,
int usecs = 0) {
910 year = (int)(date / 10000000000ll);
911 date -= year* 10000000000ll;
912 month = (int)(date / 100000000ll);
913 date -= month * 100000000ll;
914 day = (int)(date / 1000000ll);
915 date -= day * 1000000ll;
916 hour = (int)(date / 10000ll);
917 date -= hour * 10000ll;
918 minute = (int)(date / 100ll);
919 second = (int)(date - minute* 100ll);
925 DLLLOCAL
void addFractionalYear(
double d) {
929 addFractionalDay(d - dy);
933 DLLLOCAL
void addFractionalMonth(
double d) {
937 addFractionalDay(d - dy);
940 DLLLOCAL
void addFractionalDay(
double d) {
944 addFractionalHour(d - h);
947 DLLLOCAL
void addFractionalHour(
double d) {
951 addFractionalMinute(d - m);
954 DLLLOCAL
void addFractionalMinute(
double d) {
958 addFractionalSecond(d - s);
961 DLLLOCAL
void addFractionalSecond(
double d) {
966 DLLLOCAL
void setSeconds(
int64 s,
int usecs = 0) {
980 DLLLOCAL
void setTime(
int h,
int m,
int s,
int usecs) {
987 DLLLOCAL
short getYear()
const {
991 DLLLOCAL
int getMonth()
const {
995 DLLLOCAL
int getDay()
const {
999 DLLLOCAL
int getHour()
const {
1003 DLLLOCAL
int getMinute()
const {
1007 DLLLOCAL
int getSecond()
const {
1011 DLLLOCAL
int getMillisecond()
const {
1015 DLLLOCAL
int getMicrosecond()
const {
1019 DLLLOCAL
int compare(
const qore_relative_time& rt)
const {
1021 qore_relative_time l;
1022 l.set(year, month, day, hour, minute, second, us);
1024 qore_relative_time r;
1025 r.set(rt.year, rt.month, rt.day, rt.hour, rt.minute, rt.second, rt.us);
1028 if (l.year > r.year)
1030 if (l.year < r.year)
1032 if (l.month > r.month)
1034 if (l.month < r.month)
1040 if (l.hour > r.hour)
1042 if (l.hour < r.hour)
1044 if (l.minute > r.minute)
1046 if (l.minute < r.minute)
1048 if (l.second > r.second)
1050 if (l.second < r.second)
1059 DLLLOCAL
void unaryMinus() {
1069 DLLLOCAL
int64 getRelativeSeconds()
const {
1070 return getRelativeMicroseconds() / 1000000;
1073 DLLLOCAL
int64 getRelativeMilliseconds()
const {
1074 return getRelativeMicroseconds() / 1000;
1077 DLLLOCAL
int64 getRelativeMicroseconds()
const {
1078 return (
int64)us + (
int64)second * MICROSECS_PER_SEC
1079 + (
int64)minute* MICROSECS_PER_MINUTE
1080 + (
int64)hour * MICROSECS_PER_HOUR
1081 + (
int64)day * MICROSECS_PER_AVG_DAY
1082 + (month ? (
int64)month * MICROSECS_PER_MAX_MONTH : 0ll)
1083 + (year ? (
int64)year * MICROSECS_PER_AVG_YEAR : 0ll);
1086 DLLLOCAL
double getRelativeSecondsDouble()
const {
1087 return ((
double)getRelativeMicroseconds()) / 1000000.0;
1090 DLLLOCAL qore_relative_time& operator+=(
const qore_relative_time& dt);
1091 DLLLOCAL qore_relative_time& operator-=(
const qore_relative_time& dt);
1092 DLLLOCAL qore_relative_time& operator-=(
const qore_absolute_time& dt);
1094 DLLLOCAL
void getAsString(
QoreString& str)
const {
1098 #define PL(n) (n == 1 ? "" : "s")
1101 str.
sprintf(
" %d year%s", year, PL(year)), f++;
1103 str.
sprintf(
" %d month%s", month, PL(month)), f++;
1105 str.
sprintf(
" %d day%s", day, PL(day)), f++;
1107 str.
sprintf(
" %d hour%s", hour, PL(hour)), f++;
1109 str.
sprintf(
" %d minute%s", minute, PL(minute)), f++;
1110 if (second || (!f && !us))
1111 str.
sprintf(
" %d second%s", second, PL(second));
1115 if (ms * 1000 == us)
1116 str.
sprintf(
" %d millisecond%s", ms, PL(ms));
1118 str.
sprintf(
" %d microsecond%s", us, PL(us));
1126 DLLLOCAL
void getTM(
struct tm& tms)
const {
1131 tms.tm_min = minute;
1132 tms.tm_sec = second;
1138 DLLLOCAL
void get(qore_time_info& info)
const {
1147 DLLLOCAL
void zero() {
1148 qore_simple_tm::zero();
1151 DLLLOCAL
bool hasValue()
const {
1152 return qore_simple_tm::hasValue();
1155 DLLLOCAL
void addSecondsTo(
double secs) {
1156 addSecondsTo((
int64)secs, (
int)((secs - (
float)((
int)secs)) * 1000000));
1159 DLLLOCAL
void addSecondsTo(
int64 secs,
int n_us = 0) {
1160 int h = secs / 3600;
1174 static inline void zero_tm(
struct tm& tms) {
1187 class qore_date_private {
1188 friend class qore_absolute_time;
1189 friend class qore_relative_time;
1196 qore_absolute_time abs;
1197 qore_relative_time rel;
1202 DLLLOCAL qore_date_private(
bool r =
false) : relative(r) {
1209 DLLLOCAL qore_date_private(
const AbstractQoreZoneInfo* zone,
const QoreValue v) : relative(false) {
1213 DLLLOCAL qore_date_private(
const AbstractQoreZoneInfo* zone,
int64 seconds,
int us = 0) : relative(false) {
1214 d.abs.set(zone, seconds, us);
1217 DLLLOCAL qore_date_private(
const AbstractQoreZoneInfo* zone,
int y,
int mo,
int dy,
int h,
int mi,
int s,
int us) : relative(false) {
1218 d.abs.set(zone, y, mo, dy, h, mi, s, us);
1221 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) {
1222 d.abs.set(zone, y, mo, dy, h, mi, s, us, xsink);
1225 DLLLOCAL qore_date_private(
const QoreValue v) : relative(true) {
1230 DLLLOCAL qore_date_private(
int y,
int mo,
int dy,
int h,
int mi,
int s,
int us,
bool r) : relative(r) {
1232 d.rel.set(y, mo, dy, h, mi, s, us);
1234 d.abs.set(
currentTZ(), y, mo, dy, h, mi, s, us);
1237 DLLLOCAL
static int compare(
const qore_date_private& left,
const qore_date_private& right) {
1240 return right.relative ? left.d.rel.compare(right.d.rel) : -1;
1242 return right.relative ? 1 : left.d.abs.compare(right.d.abs);
1245 DLLLOCAL qore_date_private& operator=(
const qore_date_private& p) {
1251 relative = p.relative;
1255 DLLLOCAL
void setNow() {
1260 DLLLOCAL
void setNow(
const AbstractQoreZoneInfo* n_zone) {
1262 d.abs.setNow(n_zone);
1265 DLLLOCAL
void setDate(
const qore_date_private& p) {
1270 DLLLOCAL
void setDate(
const struct tm& tms,
int us) {
1273 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);
1276 DLLLOCAL
void setAbsoluteDate(
const char* str,
const AbstractQoreZoneInfo* zone =
currentTZ(),
ExceptionSink* xsink = 0);
1277 DLLLOCAL
void setRelativeDate(
const char* str);
1279 DLLLOCAL
void setDate(
const char* str);
1280 DLLLOCAL
void setDate(
const char* str,
ExceptionSink* xsink);
1282 DLLLOCAL
bool isRelative()
const {
1286 DLLLOCAL
void setZone(
const AbstractQoreZoneInfo* n_zone) {
1288 d.abs.setZone(n_zone);
1291 DLLLOCAL
short getYear()
const {
1292 return relative ? d.rel.getYear() : d.abs.getYear();
1295 DLLLOCAL
int getMonth()
const {
1296 return relative ? d.rel.getMonth() : d.abs.getMonth();
1299 DLLLOCAL
int getDay()
const {
1300 return relative ? d.rel.getDay() : d.abs.getDay();
1303 DLLLOCAL
int getHour()
const {
1304 return relative ? d.rel.getHour() : d.abs.getHour();
1307 DLLLOCAL
int getMinute()
const {
1308 return relative ? d.rel.getMinute() : d.abs.getMinute();
1311 DLLLOCAL
int getSecond()
const {
1312 return relative ? d.rel.getSecond() : d.abs.getSecond();
1315 DLLLOCAL
int getMillisecond()
const {
1316 return relative ? d.rel.getMillisecond() : d.abs.getMillisecond();
1319 DLLLOCAL
int getMicrosecond()
const {
1320 return relative ? d.rel.getMicrosecond() : d.abs.getMicrosecond();
1323 DLLLOCAL
bool hasValue()
const {
1324 return relative ? d.rel.hasValue() : d.abs.hasValue();
1327 DLLLOCAL
int64 getEpochSeconds()
const {
1328 return relative ? d.rel.getRelativeSeconds() : d.abs.getEpochSeconds();
1331 DLLLOCAL
int64 getEpochSecondsUTC()
const {
1332 return relative ? d.rel.getRelativeSeconds() : d.abs.getEpochSecondsUTC();
1335 DLLLOCAL
int64 getEpochMillisecondsUTC()
const {
1336 return relative ? d.rel.getRelativeMilliseconds() : d.abs.getEpochMillisecondsUTC();
1339 DLLLOCAL
int64 getEpochMicrosecondsUTC()
const {
1340 return relative ? d.rel.getRelativeMicroseconds() : d.abs.getEpochMicrosecondsUTC();
1343 DLLLOCAL
int getDayNumber()
const {
1344 return relative ? 0 : d.abs.getDayNumber();
1348 DLLLOCAL
void add(
const qore_date_private& dt) {
1353 setDate(getEpochSecondsUTC() + dt.d.abs.getEpochSecondsUTC(), d.abs.getMicrosecond() + dt.d.abs.getMicrosecond());
1357 assert(dt.relative);
1361 DLLLOCAL
void unaryMinus() {
1369 DLLLOCAL
void subtractBy(
const qore_date_private& dt) {
1374 int64 secs = d.abs.getEpochSecondsUTC();
1375 int us = d.abs.getMicrosecond();
1377 d.rel.setDifference(secs, us, dt.d.abs);
1388 DLLLOCAL
void addSecondsTo(
int64 secs,
int us) {
1390 d.abs.addSecondsTo(secs, us);
1392 d.rel.addSecondsTo(secs, us);
1395 DLLLOCAL
void setTime(
int h,
int m,
int s,
int us) {
1397 d.rel.setTime(h, m, s, us);
1399 d.abs.setTime(h, m, s, us);
1402 DLLLOCAL
void setDate(
const AbstractQoreZoneInfo* n_zone,
int year,
int month,
int day,
int hour,
int minute,
int second,
int n_us) {
1404 d.abs.set(n_zone, year, month, day, hour, minute, second, n_us);
1407 DLLLOCAL
void setDate(
const AbstractQoreZoneInfo* zone,
int64 seconds,
int us = 0) {
1409 d.abs.set(zone, seconds, us);
1412 DLLLOCAL
void setDate(
int64 seconds,
int us = 0) {
1417 DLLLOCAL
void setLocalDate(
int64 seconds,
int us) {
1419 d.abs.setLocal(
currentTZ(), seconds, us);
1422 DLLLOCAL
void setLocalDate(
const AbstractQoreZoneInfo* zone,
int64 seconds,
int us) {
1424 d.abs.setLocal(zone, seconds, us);
1427 DLLLOCAL
void setDateLiteral(
int64 date,
int us = 0) {
1429 d.abs.setLiteral(date, us);
1432 DLLLOCAL
void setRelativeDateLiteral(
int64 date,
int us = 0) {
1434 d.rel.setLiteral(date, us);
1437 DLLLOCAL
void setRelativeDateSeconds(
int64 s,
int us = 0) {
1439 d.rel.setSeconds(s, us);
1442 DLLLOCAL
int64 getRelativeSeconds()
const {
1443 return relative ? d.rel.getRelativeSeconds() : d.abs.getRelativeSeconds();
1446 DLLLOCAL
int64 getRelativeMilliseconds()
const {
1447 return relative ? d.rel.getRelativeMilliseconds() : d.abs.getRelativeMilliseconds();
1450 DLLLOCAL
int64 getRelativeMicroseconds()
const {
1451 return relative ? d.rel.getRelativeMicroseconds() : d.abs.getRelativeMicroseconds();
1454 DLLLOCAL
double getRelativeSecondsDouble()
const {
1455 return relative ? d.rel.getRelativeSecondsDouble() : d.abs.getRelativeSecondsDouble();
1458 DLLLOCAL
int getDayOfWeek()
const {
1459 return relative ? 0 : d.abs.getDayOfWeek();
1462 DLLLOCAL
void getISOWeek(
int& yr,
int& week,
int& wday)
const {
1468 return d.abs.getISOWeek(yr, week, wday);
1471 DLLLOCAL
bool isEqual(
const qore_date_private& dt)
const {
1472 return !compare(*
this, dt);
1475 DLLLOCAL
void localtime(
struct tm& tms)
const {
1479 d.abs.localtime(tms);
1482 DLLLOCAL
void gmtime(
struct tm& tms)
const {
1490 DLLLOCAL
void get(qore_time_info& info)
const {
1497 DLLLOCAL
void get(
const AbstractQoreZoneInfo* zone, qore_time_info& info)
const {
1501 d.abs.get(zone, info);
1504 DLLLOCAL
void format(
QoreString& str,
const char* fmt)
const;
1506 DLLLOCAL
void getAsString(
QoreString& str)
const {
1508 d.abs.getAsString(str);
1510 d.rel.getAsString(str);
1515 DLLLOCAL
static qore_date_private* getDateFromISOWeek(qore_date_private& result,
int year,
int week,
int day,
ExceptionSink* xsink) {
1517 xsink->
raiseException(
"ISO-8601-INVALID-WEEK",
"week numbers must be positive (value passed: %d)", week);
1522 int jan1 = qore_date_info::getDayOfWeek(year, 1, 1);
1526 int mw = 52 + ((jan1 == 4 && !qore_date_info::isLeapYear(year)) || (jan1 == 3 && qore_date_info::isLeapYear(year)));
1528 xsink->
raiseException(
"ISO-8601-INVALID-WEEK",
"there are only %d calendar weeks in year %d (week value passed: %d)", mw, year, week);
1533 if (day < 1 || day > 7) {
1534 xsink->
raiseException(
"ISO-8601-INVALID-DAY",
"calendar week days must be between 1 and 7 for Mon - Sun (day value passed: %d)", day);
1547 else if (jan1 > 1 && jan1 < 5) {
1563 result.setLocalDate(qore_date_info::getEpochSeconds(y, m, d) + ((week - 1) * 7 + (day - 1)) * 86400, 0);
1567 DLLLOCAL
const AbstractQoreZoneInfo* getZone()
const {
1568 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:48
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:275
for returning broken-down time information
Definition: DateTime.h:41