From b01aa15cbec4b9a6820d0387572858abf87bab45 Mon Sep 17 00:00:00 2001 From: angelo Date: Fri, 23 Jun 1995 15:26:52 +0000 Subject: [PATCH] Modificata la rappresentazione interna delle date. Modificati gli operatori di addizione, sottrazione ecc. git-svn-id: svn://10.65.10.50/trunk@1502 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- include/date.cpp | 240 ++++++++++++++++++++++++++++++----------------- include/date.h | 21 +++-- 2 files changed, 166 insertions(+), 95 deletions(-) diff --git a/include/date.cpp b/include/date.cpp index 3b35dc0bf..5bf261054 100755 --- a/include/date.cpp +++ b/include/date.cpp @@ -4,13 +4,17 @@ #define __DATE_CPP #include -#include +#ifndef FOXPRO #include +#endif #include #include +#if XVT_OS != XVT_OS_SCOUNIX +#include +#endif +#define DAYYEAR 365 #define DAYBIAS 36525L -#define NULLDATE -99999L /////////////////////////////////////////////////////////// // Utility functions @@ -20,6 +24,8 @@ HIDDEN TDate __tmp_date; HIDDEN char __date_tmp_string[128]; +HIDDEN const byte dm[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + TDate::TDate(const TDate &d) : _val(d._val) {} @@ -28,9 +34,60 @@ TDate::TDate(long l) : _val(l) { if (_val == TODAY) { - char s[16]; - cgetdata(&_val, s); - } +#if XVT_OS == XVT_OS_SCOUNIX +#ifndef FOXPRO + long lt; + struct tm *timeloc; + FILE *f; + + sprintf(_int_s1, "date.%-d", getuid()); + if ((f = fopen(_int_s1, "r")) == NULL) + { + if (time(<) == -1) return ; + timeloc = localtime(<) ; + _val = makedata(timeloc->tm_mday, timeloc->tm_mon+1, timeloc->tm_year); + } + else + { + fscanf(f, "%ld", _val); + fclose(f); + } +#endif +#else + int junk; + union REGS inregs, outregs; + + inregs.h.ah = 0x2A; + junk = intdos(&inregs, &outregs); + _val = makedata(outregs.h.dl, outregs.h.dh, outregs.x.cx); +#endif + } else + if (_val == 0) + _val = NULLDATE; + else + if (_val < 1000000L) + { + long wd = _val; + int cnt = 1900; + if (wd > DAYBIAS) + { + wd -= DAYBIAS; + cnt += 100; + } + else + while (wd < 0) + { + cnt -= 100; + wd += DAYBIAS; + } + int m, y, leap; + + for(y = 0; wd > DAYYEAR + (leap = ((y % 4 ) == 0)); y++) + wd -= (DAYYEAR + leap); + for(m = 0; wd > (dm[m] + (leap && (m == 1))); m++) + wd -= (dm[m] + (leap && (m == 1))); + _val = makedata((int) wd, m+1, y+cnt); + } } @@ -40,66 +97,33 @@ TDate::TDate(const char* s) if (!isdate(s)) return; - if (strlen(s) == 10) + int day, month, year; + + if (strchr(s, '-') == NULL) { - int day = atoi(s), month = atoi(&s[3]), year = atoi(&s[6]); - long off = 0L; - - if (year > 1000) - { - if (year < 1951) off -= DAYBIAS; - if (year < 1851) off -= DAYBIAS; - if (year < 1751) off -= DAYBIAS; - year %= 100; // modify - } - _val = makedata(day, month, year) + off; + strcpy(__date_tmp_string, s); + + day = atoi(__date_tmp_string + 6); __date_tmp_string[6] = '\0'; + month = atoi(__date_tmp_string + 4); __date_tmp_string[4] = '\0'; + year = atoi(__date_tmp_string); } else - if (strchr(s, '-') == NULL) - { - strcpy(__date_tmp_string, s); - - int day = atoi(__date_tmp_string + 6); __date_tmp_string[6] = '\0'; - int month = atoi(__date_tmp_string + 4); __date_tmp_string[4] = '\0'; - int year = atoi(__date_tmp_string); - long off = 0L; - - if (year > 1000) - { - if (year < 1951) off -= DAYBIAS; - if (year < 1851) off -= DAYBIAS; - if (year < 1751) off -= DAYBIAS; - year %= 100; // modify - } - _val = makedata(day, month, year) + off; - } - else _val = cpackdata((char*)s); + { + day = atoi(s); + month = atoi(&s[3]); + year = atoi(&s[6]); + if (strlen(s) < 10) + year += 1900; + } + _val = makedata(day, month, year); } TDate::TDate(int day, int month, int year) { - if (day == TODAY) - { - char s[16]; - cgetdata(&_val, s); - } + if (day && month && year) + _val = makedata(day, month, year); else - if (day && month && year) - { - long off = 0L; - - if (year > 1000) - { - if (year < 1951) off -= DAYBIAS; - if (year < 1851) off -= DAYBIAS; - if (year < 1751) off -= DAYBIAS; - year %= 100; // modify - } - _val = makedata(day, month, year) + off; - if (!ok()) _val = NULLDATE; - } - else - _val = NULLDATE; + _val = NULLDATE; } int TDate::last_day(int month, int year) @@ -181,7 +205,11 @@ void TDate::read_from(istream& in) { char s[256]; in >> s; - if (isdate(s)) _val = cpackdata(s); + if (isdate(s)) + { + TDate d(s); + _val = d._val; + } else _val = NULLDATE; } @@ -204,6 +232,7 @@ char* TDate::string( { yearf = full; ord = amg_date; + sep='\0'; } TString df(2), yf(4), mf(2); @@ -211,10 +240,12 @@ char* TDate::string( // format day if (dayf == letters) - { + { +#ifndef FOXPRO const real ddd(day()); df = ddd.string("LETTERE"); letterflag = TRUE; +#endif } else if (dayf == weekday) { @@ -226,10 +257,12 @@ char* TDate::string( // format year if (yearf == letters) - { + { +#ifndef FOXPRO const real ddd(year()); yf = ddd.string("LETTERE"); letterflag = TRUE; +#endif } else if (yearf == brief) @@ -287,65 +320,100 @@ char* TDate::string( return __date_tmp_string; } +long TDate::date2julian() const +{ + const int d = day(), m = month(), y = year(); + + return (long)(d - 32076) + + 1461L * (y + 4800L + (m - 14) / 12) / 4 + + 367 * ( m - 2 - (m - 14) / 12 * 12) / 12 + - 3 * ((y + 4900L + (m - 14) / 12) / 100) / 4 + + 1; + +} + +long TDate::julian2date(long julian) const +{ + long x, z, m, d, y; + const long daysPer400Years = 146097L; + const long fudgedDaysPer4000Years = 1460970L + 31; + + x = julian + 68569L; + z = 4 * x / daysPer400Years; + x = x - (daysPer400Years * z + 3) / 4; + y = 4000 * (x + 1) / fudgedDaysPer4000Years; + x = x - 1461 * y / 4 + 31; + m = 80 * x / 2447; + d = x - 2447 * m / 80; + x = m / 11; + m = m + 2 - 12 * x; + y = 100 * (z - 49) + y + x; + return makedata((int) d, (int) m, (int) y); +} int TDate::day() const { - return ::day(_val); + return (int) (_val % 100L); } int TDate::month() const { - return ::month(_val); + return (int) ((_val % 10000L) / 100L); } int TDate::year() const -{ - return ::year(_val); +{ + return (int) (_val / 10000L); } void TDate::addmonth(int nmonth) { - _val = ::addmonth(_val, nmonth); + const int wday = day(); + int wmonth = month() + nmonth, wyear = year(); + + if (wmonth > 12) + { + wmonth -= 12; + wyear++; + } + _val = makedata(wday, wmonth, wyear); } void TDate::addyear(int nyear) { - _val = ::addyear(_val, nyear); + const int wday = day(), wmonth = month(); + int wyear = year() + nyear; + + _val = makedata(wday, wmonth, wyear); } bool TDate::isdate(const char* s) { if (!*s) return FALSE; - if (strlen(s) == 10) - { - int day = atoi(s), - month = atoi(&s[3]), - year = atoi(&s[6]); - if (day < 1 || day > 31 || - month < 1 || month > 12 || - year < 1700 || year > 2100) - return FALSE; + int day = atoi(s), + + month = atoi(&s[3]), + year = atoi(&s[6]); + if (day < 1 || day > 31 || + month < 1 || month > 12 || + year < 0) + return FALSE; - char s1[16]; - sprintf(s1, "%02d-%02d-%02d", day, month, year%100); - return (bool)cverdata(s1); - } - - return (bool)cverdata((char*)s); + return day <= dm[month - 1] || (month == 2 && (year % 4 == 0) && day == 29); } bool TDate::ok() const { - return _val <= 2 * DAYBIAS && _val >= -2 * DAYBIAS; + return _val > 0; } @@ -360,7 +428,7 @@ TDate& operator +( // @comm E' indifferente quale parametro viene passato per primo { - __tmp_date = long(a) + nday; + __tmp_date = a.julian2date(a.date2julian() + nday); return __tmp_date; } @@ -368,8 +436,8 @@ TDate& operator +( TDate& operator +(const long nday, const TDate& b) { - __tmp_date = long(b) + nday; - return __tmp_date; + __tmp_date = b.julian2date(b.date2julian() + nday); + return __tmp_date; } @@ -379,7 +447,7 @@ TDate& operator -( long nday) // @parm Numero di giorni da togliere { - __tmp_date = long(a)- nday; + __tmp_date = a.julian2date(a.date2julian() - nday); return __tmp_date; } diff --git a/include/date.h b/include/date.h index 8e36c1a91..ea8f574e0 100755 --- a/include/date.h +++ b/include/date.h @@ -5,8 +5,8 @@ #include #endif - -#define TODAY -1 +#define NULLDATE 0L +#define TODAY -1L // @doc EXTERNAL @@ -52,11 +52,14 @@ protected: friend bool operator ==(const TDate& a, const TDate& b); // @cmember Controlla se una 2 date sono diverse friend bool operator !=(const TDate& a, const TDate& b); - + long makedata(int day, int month, int year) const { return (10000L * year) + ( 100L * month) + day; } + // @access Public Member public: // @cmember Ritorna la data in formato di stringa (anche in formato ANSI) char* string(TDate_mgafmt year = full, char sep = '-', TDate_mgafmt day = full, TDate_mgafmt month = full, TDate_order ord = gma_date) const ; + long date2julian() const; + long julian2date(long julian) const; // @cmember Ritorna il giorno int day() const ; @@ -93,16 +96,16 @@ public: // @cmember Incrementa la data di un certo numero di giorni TDate& operator +=(const long nday) - { _val += nday; return *this; } + { _val = julian2date(date2julian() + nday); return *this; } // @cmember Decrementa la data di un certo numero di giorni TDate& operator -=(const long nday) - { _val -= nday; return *this; } + { _val = julian2date(date2julian() - nday); return *this; } // @cmember Incrementa la data di un giorno TDate& operator ++() - { _val++; return *this; } + { _val = julian2date(date2julian() + 1); return *this; } // @cmember Decrementa la data di un giorno TDate& operator --() - { _val--; return *this; } + { _val = julian2date(date2julian() - 1); return *this; } // @cmember Stampa sull'output passato la data void print_on(ostream& out) const ; @@ -131,11 +134,11 @@ public: // @cmember Costruttore TDate(const TDate& d); // @cmember Costruttore - TDate(long l); + TDate(long l = NULLDATE); // @cmember Costruttore TDate(const char* s); // @cmember Costruttore - TDate(int day = 0, int month = 0, int year = 0); + TDate(int day, int month, int year); }; class TFormatted_date : public TDate