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