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,
bool allow_z =
false);
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,
509 int aoff = AbstractQoreZoneInfo::getUTCOffset(zone, epoch);
511 printd(5,
"qore_absolute_time::setLocalIntern() epoch: %lld -> %lld (aoff: %d diff: %d)\n", epoch,
512 epoch - (aoff - off), aoff, aoff - off);
513 epoch -= (aoff - off);
516 printd(5,
"qore_absolute_time::setLocalIntern() epoch: %lld zone: %s\n", epoch,
517 AbstractQoreZoneInfo::getRegionName(zone));
520 DLLLOCAL
void setTM(qore_simple_tm2& tm,
struct tm& tms,
bool dst =
false)
const {
521 tms.tm_year = tm.year - 1900;
522 tms.tm_mon = tm.month - 1;
523 tms.tm_mday = tm.day;
524 tms.tm_hour = tm.hour;
525 tms.tm_min = tm.minute;
526 tms.tm_sec = tm.second;
528 tms.tm_wday = qore_date_info::getDayOfWeek(tm.year, tm.month, tm.day);
529 tms.tm_yday = qore_date_info::getDayNumber(tm.year, tm.month, tm.day) - 1;
533 DLLLOCAL
void setNowIntern() {
538 DLLLOCAL
void set(
const AbstractQoreZoneInfo* n_zone,
const QoreValue v);
540 DLLLOCAL
void set(
const AbstractQoreZoneInfo* n_zone,
int64 n_epoch,
int n_us) {
543 normalize_units2<int64, int>(epoch, n_us, 1000000);
547 DLLLOCAL
void set(
double f,
const AbstractQoreZoneInfo* n_zone = currentTZ()) {
550 us = (int)((f - (
float)((int)f)) * 1000000);
553 DLLLOCAL
void setLocal(
const AbstractQoreZoneInfo* n_zone,
int64 n_epoch,
int n_us) {
556 normalize_units2<int64, int>(epoch, n_us, 1000000);
557 setLocalIntern(n_us);
560 DLLLOCAL
void set(
const AbstractQoreZoneInfo* n_zone,
int year,
int month,
int day,
int hour,
int minute,
561 int second,
int n_us) {
563 epoch = qore_date_info::getEpochSeconds(year, month, day, hour, minute, second);
565 setLocalIntern(n_us);
571 DLLLOCAL
void set(
const AbstractQoreZoneInfo* n_zone,
int year,
int month,
int day,
int hour,
int minute,
575 epoch = qore_date_info::getEpochSeconds(year, month, day, hour, minute, second);
577 setLocalIntern(n_us);
580 if (month < 1 || month > 12) {
581 xsink->
raiseException(
"INVALID-DATE",
"invalid month value: %d; expecting 1 - 12 inclusive", month);
585 xsink->
raiseException(
"INVALID-DATE",
"invalid day value: %d; day must be > 0", day);
589 int dom = qore_date_info::getLastDayOfMonth(month, year);
591 xsink->
raiseException(
"INVALID-DATE",
"invalid day of the month: %d; %04d-%02 has %d days", day, year,
596 if (hour < 0 || hour > 23) {
597 xsink->
raiseException(
"INVALID-DATE",
"invalid hour value: %d; expecting 0 - 23 inclusive", hour);
600 if (minute < 0 || minute > 60) {
601 xsink->
raiseException(
"INVALID-DATE",
"invalid minute value: %d; expecting 0 - 60 inclusive", minute);
604 if (second < 0 || second > 60) {
605 xsink->
raiseException(
"INVALID-DATE",
"invalid second value: %d; expecting 0 - 60 inclusive", second);
608 if (n_us < 0 || n_us > 999999) {
609 xsink->
raiseException(
"INVALID-DATE",
"invalid microsecond value: %d; expecting 0 - 999999 inclusive", n_us);
617 DLLLOCAL
void set(
const qore_absolute_time& p) {
623 DLLLOCAL
void set(
const char* str,
const AbstractQoreZoneInfo* n_zone = currentTZ(),
ExceptionSink* xsink = 0);
625 DLLLOCAL
void setZone(
const AbstractQoreZoneInfo* n_zone) {
629 DLLLOCAL
void setTime(
int h,
int m,
int s,
int usecs) {
630 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
634 normalize_units2<int, int>(s, usecs, 1000000);
635 normalize_units2<int, int>(m, s, 60);
636 normalize_units2<int, int>(h, m, 60);
643 epoch = qore_date_info::getEpochSeconds(tm.year, tm.month, tm.day, h, m, s);
644 setLocalIntern(usecs);
647 DLLLOCAL
void setLiteral(
int64 date,
int usecs = 0) {
653 tm.setLiteral(date, usecs);
656 epoch = qore_date_info::getEpochSeconds(tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);
659 setLocalIntern(usecs);
662 DLLLOCAL
void setNow() {
668 DLLLOCAL
void setNow(
const AbstractQoreZoneInfo* n_zone) {
673 DLLLOCAL
void getISOWeek(
int& yr,
int& week,
int& wday)
const {
674 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
675 tm.getISOWeek(yr, week, wday);
678 DLLLOCAL
void get(qore_time_info& info)
const {
681 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst, zname);
683 info.set(epoch, us, offset, isdst, zname, zone);
686 DLLLOCAL
void get(
const AbstractQoreZoneInfo* z, qore_time_info& info)
const {
689 int offset = AbstractQoreZoneInfo::getUTCOffset(z, epoch, isdst, zname);
690 info.set(epoch, us, offset, isdst, zname, zone);
693 DLLLOCAL
void getDate(qore_simple_tm& tm)
const {
694 int off = AbstractQoreZoneInfo::getUTCOffset(zone, epoch);
695 tm.set(epoch + off, us);
698 DLLLOCAL
short getYear()
const {
699 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
703 DLLLOCAL
int getMonth()
const {
704 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
708 DLLLOCAL
int getDay()
const {
709 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
713 DLLLOCAL
int getHour()
const {
715 return (
int)(((epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch)) % SECS_PER_DAY) / SECS_PER_HOUR);
720 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst, zname);
721 info.set(epoch, us, offset, isdst, zname, zone);
725 DLLLOCAL
int getMinute()
const {
727 return (
int)(((epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch)) % SECS_PER_HOUR) / SECS_PER_MINUTE);
732 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst, zname);
733 info.set(epoch, us, offset, isdst, zname, zone);
737 DLLLOCAL
int getSecond()
const {
739 return ((epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch)) % SECS_PER_MINUTE);
744 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst, zname);
745 info.set(epoch, us, offset, isdst, zname, zone);
749 DLLLOCAL
int getMillisecond()
const {
753 DLLLOCAL
int getMicrosecond()
const {
757 DLLLOCAL
int64 getRelativeSeconds()
const {
758 return getRelativeMicroseconds() / 1000000;
761 DLLLOCAL
int64 getRelativeMilliseconds()
const {
762 return getRelativeMicroseconds() / 1000;
765 DLLLOCAL
int64 getRelativeMicroseconds()
const;
767 DLLLOCAL
double getRelativeSecondsDouble()
const {
768 return ((
double)getRelativeMicroseconds()) / 1000000.0;
771 DLLLOCAL
void localtime(
struct tm& tms)
const {
773 int offset = AbstractQoreZoneInfo::getUTCOffset(zone, epoch, isdst);
774 qore_simple_tm2 tm(epoch + offset, us);
776 setTM(tm, tms, isdst);
779 DLLLOCAL
void gmtime(
struct tm& tms)
const {
780 qore_simple_tm2 tm(epoch, us);
781 setTM(tm, tms,
false);
784 DLLLOCAL
int compare(
const qore_absolute_time& r)
const {
796 DLLLOCAL
int getDayOfWeek()
const {
797 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
798 return qore_date_info::getDayOfWeek(tm.year, tm.month, tm.day);
801 DLLLOCAL
int getDayNumber()
const {
802 qore_simple_tm2 tm(epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch), us);
803 return qore_date_info::getDayNumber(tm.year, tm.month, tm.day);
806 DLLLOCAL
bool hasValue()
const {
807 return epoch || us ? true :
false;
810 DLLLOCAL
int64 getEpochSeconds()
const {
811 return epoch + AbstractQoreZoneInfo::getUTCOffset(zone, epoch);
814 DLLLOCAL
int64 getEpochMilliseconds()
const {
815 return getEpochSeconds() * 1000 + (us / 1000);
818 DLLLOCAL
int64 getEpochMicroseconds()
const {
819 return getEpochSeconds() * 1000000 + us;
822 DLLLOCAL
int64 getEpochSecondsUTC()
const {
826 DLLLOCAL
int64 getEpochMicrosecondsUTC()
const {
827 return epoch * 1000000 + us;
830 DLLLOCAL
int64 getEpochMillisecondsUTC()
const {
831 return epoch * 1000 + (us / 1000);
834 DLLLOCAL qore_absolute_time& operator+=(
const qore_relative_time& dt);
835 DLLLOCAL qore_absolute_time& operator-=(
const qore_relative_time& dt);
837 DLLLOCAL
void getAsString(
QoreString& str)
const;
839 DLLLOCAL
void unaryMinus() {
844 DLLLOCAL
const AbstractQoreZoneInfo* getZone()
const {
848 DLLLOCAL
void addSecondsTo(
int64 secs,
int n_us = 0) {
849 set(zone, epoch + secs, us + n_us);
853class qore_relative_time :
public qore_simple_tm {
854friend class qore_absolute_time;
856 DLLLOCAL
void normalize(
bool for_comparison =
false) {
860 normalize_units<int, int>(second, us, 1000000);
863 normalize_units<int, int>(minute, second, 60);
866 normalize_units<int, int>(hour, minute, 60);
870 if (for_comparison) {
871 normalize_units<int, int>(day, hour, 24);
872 normalize_units<int, int>(year, day, 365);
873 normalize_units<int, int>(month, day, 31);
877 normalize_units<int, int>(year, month, 12);
880 DLLLOCAL
void setIso8601(
const char* str);
883 DLLLOCAL
void set(
int n_year,
int n_month,
int n_day,
int n_hour,
int n_minute,
int n_second,
int n_us) {
884 qore_simple_tm::set(n_year, n_month, n_day, n_hour, n_minute, n_second, n_us);
890 DLLLOCAL
void set(
const char* str);
892 DLLLOCAL
void set(
const qore_relative_time& p) {
903 DLLLOCAL
void setDifference(
int64 seconds,
int micros,
const qore_absolute_time& dt) {
904 int64 sec = seconds - dt.epoch;
907 year = month = day = hour = minute = 0;
910 normalize_units<int64, int>(sec, us, 1000000);
915 normalize_units<int, int64>(hour, sec, 3600);
918 normalize_units<int, int64>(minute, sec, 60);
923 DLLLOCAL
void setLiteral(
int64 date,
int usecs = 0) {
924 year = (int)(date / 10000000000ll);
925 date -= year* 10000000000ll;
926 month = (int)(date / 100000000ll);
927 date -= month * 100000000ll;
928 day = (int)(date / 1000000ll);
929 date -= day * 1000000ll;
930 hour = (int)(date / 10000ll);
931 date -= hour * 10000ll;
932 minute = (int)(date / 100ll);
933 second = (int)(date - minute* 100ll);
939 DLLLOCAL
void addFractionalYear(
double d) {
943 addFractionalDay(d - dy);
947 DLLLOCAL
void addFractionalMonth(
double d) {
951 addFractionalDay(d - dy);
954 DLLLOCAL
void addFractionalDay(
double d) {
958 addFractionalHour(d - h);
961 DLLLOCAL
void addFractionalHour(
double d) {
965 addFractionalMinute(d - m);
968 DLLLOCAL
void addFractionalMinute(
double d) {
972 addFractionalSecond(d - s);
975 DLLLOCAL
void addFractionalSecond(
double d) {
980 DLLLOCAL
void setSeconds(
int64 s,
int usecs = 0) {
994 DLLLOCAL
void setTime(
int h,
int m,
int s,
int usecs) {
1001 DLLLOCAL
short getYear()
const {
1005 DLLLOCAL
int getMonth()
const {
1009 DLLLOCAL
int getDay()
const {
1013 DLLLOCAL
int getHour()
const {
1017 DLLLOCAL
int getMinute()
const {
1021 DLLLOCAL
int getSecond()
const {
1025 DLLLOCAL
int getMillisecond()
const {
1029 DLLLOCAL
int getMicrosecond()
const {
1033 DLLLOCAL
int compare(
const qore_relative_time& rt)
const {
1035 qore_relative_time l;
1036 l.set(year, month, day, hour, minute, second, us);
1038 qore_relative_time r;
1039 r.set(rt.year, rt.month, rt.day, rt.hour, rt.minute, rt.second, rt.us);
1042 if (l.year > r.year)
1044 if (l.year < r.year)
1046 if (l.month > r.month)
1048 if (l.month < r.month)
1054 if (l.hour > r.hour)
1056 if (l.hour < r.hour)
1058 if (l.minute > r.minute)
1060 if (l.minute < r.minute)
1062 if (l.second > r.second)
1064 if (l.second < r.second)
1073 DLLLOCAL
void unaryMinus() {
1083 DLLLOCAL
int64 getRelativeSeconds()
const {
1084 return getRelativeMicroseconds() / 1000000;
1087 DLLLOCAL
int64 getRelativeMilliseconds()
const {
1088 return getRelativeMicroseconds() / 1000;
1091 DLLLOCAL
int64 getRelativeMicroseconds()
const {
1092 return (
int64)us + (
int64)second * MICROSECS_PER_SEC
1093 + (
int64)minute* MICROSECS_PER_MINUTE
1094 + (
int64)hour * MICROSECS_PER_HOUR
1095 + (
int64)day * MICROSECS_PER_AVG_DAY
1096 + (month ? (
int64)month * MICROSECS_PER_MAX_MONTH : 0ll)
1097 + (year ? (
int64)year * MICROSECS_PER_AVG_YEAR : 0ll);
1100 DLLLOCAL
double getRelativeSecondsDouble()
const {
1101 return ((
double)getRelativeMicroseconds()) / 1000000.0;
1104 DLLLOCAL qore_relative_time& operator+=(
const qore_relative_time& dt);
1105 DLLLOCAL qore_relative_time& operator-=(
const qore_relative_time& dt);
1106 DLLLOCAL qore_relative_time& operator-=(
const qore_absolute_time& dt);
1108 DLLLOCAL
void getAsString(
QoreString& str)
const {
1112#define PL(n) (n == 1 ? "" : "s")
1115 str.
sprintf(
" %d year%s", year, PL(year)), f++;
1117 str.
sprintf(
" %d month%s", month, PL(month)), f++;
1119 str.
sprintf(
" %d day%s", day, PL(day)), f++;
1121 str.
sprintf(
" %d hour%s", hour, PL(hour)), f++;
1123 str.
sprintf(
" %d minute%s", minute, PL(minute)), f++;
1124 if (second || (!f && !us))
1125 str.
sprintf(
" %d second%s", second, PL(second));
1129 if (ms * 1000 == us)
1130 str.
sprintf(
" %d millisecond%s", ms, PL(ms));
1132 str.
sprintf(
" %d microsecond%s", us, PL(us));
1140 DLLLOCAL
void getTM(
struct tm& tms)
const {
1145 tms.tm_min = minute;
1146 tms.tm_sec = second;
1152 DLLLOCAL
void get(qore_time_info& info)
const {
1161 DLLLOCAL
void zero() {
1162 qore_simple_tm::zero();
1165 DLLLOCAL
bool hasValue()
const {
1166 return qore_simple_tm::hasValue();
1169 DLLLOCAL
void addSecondsTo(
double secs) {
1170 addSecondsTo((
int64)secs, (
int)((secs - (
float)((
int)secs)) * 1000000));
1173 DLLLOCAL
void addSecondsTo(
int64 secs,
int n_us = 0) {
1174 int h = secs / 3600;
1188static inline void zero_tm(
struct tm& tms) {
1201class qore_date_private {
1202friend class qore_absolute_time;
1203friend class qore_relative_time;
1210 qore_absolute_time abs;
1211 qore_relative_time rel;
1216 DLLLOCAL qore_date_private(
bool r =
false) : relative(r) {
1220 d.abs.set(currentTZ(), 0, 0);
1223 DLLLOCAL qore_date_private(
const AbstractQoreZoneInfo* zone,
const QoreValue v) : relative(false) {
1227 DLLLOCAL qore_date_private(
const AbstractQoreZoneInfo* zone,
int64 seconds,
int us = 0) : relative(false) {
1228 d.abs.set(zone, seconds, us);
1231 DLLLOCAL qore_date_private(
const AbstractQoreZoneInfo* zone,
int y,
int mo,
int dy,
int h,
int mi,
int s,
int us) : relative(false) {
1232 d.abs.set(zone, y, mo, dy, h, mi, s, us);
1235 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) {
1236 d.abs.set(zone, y, mo, dy, h, mi, s, us, xsink);
1239 DLLLOCAL qore_date_private(
const QoreValue v) : relative(true) {
1244 DLLLOCAL qore_date_private(
int y,
int mo,
int dy,
int h,
int mi,
int s,
int us,
bool r) : relative(r) {
1246 d.rel.set(y, mo, dy, h, mi, s, us);
1248 d.abs.set(currentTZ(), y, mo, dy, h, mi, s, us);
1251 DLLLOCAL
static int compare(
const qore_date_private& left,
const qore_date_private& right) {
1254 return right.relative ? left.d.rel.compare(right.d.rel) : -1;
1256 return right.relative ? 1 : left.d.abs.compare(right.d.abs);
1259 DLLLOCAL qore_date_private& operator=(
const qore_date_private& p) {
1265 relative = p.relative;
1269 DLLLOCAL
void setNow() {
1274 DLLLOCAL
void setNow(
const AbstractQoreZoneInfo* n_zone) {
1276 d.abs.setNow(n_zone);
1279 DLLLOCAL
void setDate(
const qore_date_private& p) {
1284 DLLLOCAL
void setDate(
const struct tm& tms,
int us) {
1287 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);
1290 DLLLOCAL
void setAbsoluteDate(
const char* str,
const AbstractQoreZoneInfo* zone = currentTZ(),
ExceptionSink* xsink = 0);
1291 DLLLOCAL
void setRelativeDate(
const char* str);
1293 DLLLOCAL
void setDate(
const char* str);
1294 DLLLOCAL
void setDate(
const char* str,
ExceptionSink* xsink);
1296 DLLLOCAL
bool isRelative()
const {
1300 DLLLOCAL
void setZone(
const AbstractQoreZoneInfo* n_zone) {
1302 d.abs.setZone(n_zone);
1305 DLLLOCAL
short getYear()
const {
1306 return relative ? d.rel.getYear() : d.abs.getYear();
1309 DLLLOCAL
int getMonth()
const {
1310 return relative ? d.rel.getMonth() : d.abs.getMonth();
1313 DLLLOCAL
int getDay()
const {
1314 return relative ? d.rel.getDay() : d.abs.getDay();
1317 DLLLOCAL
int getHour()
const {
1318 return relative ? d.rel.getHour() : d.abs.getHour();
1321 DLLLOCAL
int getMinute()
const {
1322 return relative ? d.rel.getMinute() : d.abs.getMinute();
1325 DLLLOCAL
int getSecond()
const {
1326 return relative ? d.rel.getSecond() : d.abs.getSecond();
1329 DLLLOCAL
int getMillisecond()
const {
1330 return relative ? d.rel.getMillisecond() : d.abs.getMillisecond();
1333 DLLLOCAL
int getMicrosecond()
const {
1334 return relative ? d.rel.getMicrosecond() : d.abs.getMicrosecond();
1337 DLLLOCAL
bool hasValue()
const {
1338 return relative ? d.rel.hasValue() : d.abs.hasValue();
1341 DLLLOCAL
int64 getEpochSeconds()
const {
1342 return relative ? d.rel.getRelativeSeconds() : d.abs.getEpochSeconds();
1345 DLLLOCAL
int64 getEpochSecondsUTC()
const {
1346 return relative ? d.rel.getRelativeSeconds() : d.abs.getEpochSecondsUTC();
1349 DLLLOCAL
int64 getEpochMillisecondsUTC()
const {
1350 return relative ? d.rel.getRelativeMilliseconds() : d.abs.getEpochMillisecondsUTC();
1353 DLLLOCAL
int64 getEpochMicrosecondsUTC()
const {
1354 return relative ? d.rel.getRelativeMicroseconds() : d.abs.getEpochMicrosecondsUTC();
1357 DLLLOCAL
int getDayNumber()
const {
1358 return relative ? 0 : d.abs.getDayNumber();
1362 DLLLOCAL
void add(
const qore_date_private& dt) {
1367 setDate(getEpochSecondsUTC() + dt.d.abs.getEpochSecondsUTC(), d.abs.getMicrosecond()
1368 + dt.d.abs.getMicrosecond());
1373 assert(dt.relative);
1377 DLLLOCAL
void unaryMinus() {
1385 DLLLOCAL
void subtractBy(
const qore_date_private& dt) {
1390 int64 secs = d.abs.getEpochSecondsUTC();
1391 int us = d.abs.getMicrosecond();
1393 d.rel.setDifference(secs, us, dt.d.abs);
1404 DLLLOCAL
void addSecondsTo(
int64 secs,
int us) {
1406 d.abs.addSecondsTo(secs, us);
1408 d.rel.addSecondsTo(secs, us);
1411 DLLLOCAL
void setTime(
int h,
int m,
int s,
int us) {
1413 d.rel.setTime(h, m, s, us);
1415 d.abs.setTime(h, m, s, us);
1418 DLLLOCAL
void setDate(
const AbstractQoreZoneInfo* n_zone,
int year,
int month,
int day,
int hour,
int minute,
1419 int second,
int n_us) {
1421 d.abs.set(n_zone, year, month, day, hour, minute, second, n_us);
1424 DLLLOCAL
void setDate(
const AbstractQoreZoneInfo* zone,
int64 seconds,
int us = 0) {
1426 d.abs.set(zone, seconds, us);
1429 DLLLOCAL
void setDate(
int64 seconds,
int us = 0) {
1431 d.abs.set(currentTZ(), seconds, us);
1434 DLLLOCAL
void setLocalDate(
int64 seconds,
int us) {
1436 d.abs.setLocal(currentTZ(), seconds, us);
1439 DLLLOCAL
void setLocalDate(
const AbstractQoreZoneInfo* zone,
int64 seconds,
int us) {
1441 d.abs.setLocal(zone, seconds, us);
1444 DLLLOCAL
void setDateLiteral(
int64 date,
int us = 0) {
1446 d.abs.setLiteral(date, us);
1449 DLLLOCAL
void setRelativeDateLiteral(
int64 date,
int us = 0) {
1451 d.rel.setLiteral(date, us);
1454 DLLLOCAL
void setRelativeDateSeconds(
int64 s,
int us = 0) {
1456 d.rel.setSeconds(s, us);
1459 DLLLOCAL
int64 getRelativeSeconds()
const {
1460 return relative ? d.rel.getRelativeSeconds() : d.abs.getRelativeSeconds();
1463 DLLLOCAL
int64 getRelativeMilliseconds()
const {
1464 return relative ? d.rel.getRelativeMilliseconds() : d.abs.getRelativeMilliseconds();
1467 DLLLOCAL
int64 getRelativeMicroseconds()
const {
1468 return relative ? d.rel.getRelativeMicroseconds() : d.abs.getRelativeMicroseconds();
1471 DLLLOCAL
double getRelativeSecondsDouble()
const {
1472 return relative ? d.rel.getRelativeSecondsDouble() : d.abs.getRelativeSecondsDouble();
1475 DLLLOCAL
int getDayOfWeek()
const {
1476 return relative ? 0 : d.abs.getDayOfWeek();
1479 DLLLOCAL
void getISOWeek(
int& yr,
int& week,
int& wday)
const {
1485 return d.abs.getISOWeek(yr, week, wday);
1488 DLLLOCAL
bool isEqual(
const qore_date_private& dt)
const {
1489 return !compare(*
this, dt);
1492 DLLLOCAL
void localtime(
struct tm& tms)
const {
1496 d.abs.localtime(tms);
1499 DLLLOCAL
void gmtime(
struct tm& tms)
const {
1507 DLLLOCAL
void get(qore_time_info& info)
const {
1514 DLLLOCAL
void get(
const AbstractQoreZoneInfo* zone, qore_time_info& info)
const {
1518 d.abs.get(zone, info);
1521 DLLLOCAL
void format(
QoreString& str,
const char* fmt)
const;
1523 DLLLOCAL
void getAsString(
QoreString& str)
const {
1525 d.abs.getAsString(str);
1527 d.rel.getAsString(str);
1532 DLLLOCAL
static qore_date_private* getDateFromISOWeek(qore_date_private& result,
int year,
int week,
int day,
1535 xsink->
raiseException(
"ISO-8601-INVALID-WEEK",
"week numbers must be positive (value passed: %d)", week);
1540 int jan1 = qore_date_info::getDayOfWeek(year, 1, 1);
1544 int mw = 52 + ((jan1 == 4 && !qore_date_info::isLeapYear(year))
1545 || (jan1 == 3 && qore_date_info::isLeapYear(year)));
1547 xsink->
raiseException(
"ISO-8601-INVALID-WEEK",
"there are only %d calendar weeks in year %d (week "
1548 "value passed: %d)", mw, year, week);
1553 if (day < 1 || day > 7) {
1554 xsink->
raiseException(
"ISO-8601-INVALID-DAY",
"calendar week days must be between 1 and 7 for Mon - Sun "
1555 "(day value passed: %d)", day);
1568 else if (jan1 > 1 && jan1 < 5) {
1583 result.setLocalDate(qore_date_info::getEpochSeconds(y, m, d) + ((week - 1) * 7 + (day - 1)) * 86400, 0);
1587 DLLLOCAL
const AbstractQoreZoneInfo* getZone()
const {
1588 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:266
The main value class in Qore, designed to be passed by value.
Definition QoreValue.h:279
for returning broken-down time information
Definition DateTime.h:41