#include #include #include #define __DATE_CPP #include #include #include #include #define DAYBIAS 36525L #define NULLDATE -99999L #include HIDDEN TDate __tmp_date; HIDDEN char __date_tmp_string[64]; TDate::TDate(const TDate &d) : _val(d._val) { memcpy(_format, "1444-", 5); } TDate::TDate(long l) : _val(l) { if (_val == TODAY) { char s[10]; cgetdata(&_val, s); } memcpy(_format, "1444-", 5); } TDate::TDate(const char* s) { _val = NULLDATE; if (!isdate(s)) return; if (strlen(s) == 10) { 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; } 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); memcpy(_format, "1444-", 5); } TDate::TDate(int day, int month, int year) { if (day == TODAY) { char s[10]; cgetdata(&_val, s); } else if ((day == 0) || (month == 0) || (year == 0)) _val = NULLDATE; else { 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; } memcpy(_format, "1444-", 5); } void TDate::set_format(const char* f) { memcpy(_format, f, 5); } int TDate::last_day(int month, int year) // parse_filastrok( // "trenta giorni case novembre // con april, giugno e settembre // son ventotto case uno // per default ce n'ha trentuno"); { int d; switch(month) { case 4: case 6: case 9: case 11: d = 30; break; case 2: d = year % 4 ? 28 : 29; break; default: d = 31; break; } return d; } void TDate::set_end_month() { _val = makedata(last_day(month(),year()),month(),year()); } bool TDate::is_end_month() { return day() == last_day(month(),year()); } int TDate::wday() const { // day of week (1=lunedi) // DDJ algorithm (4/1995) int m = month(); int d = day(); int y = year(); if (m <= 2) { y --; m += 12; } return ((d + 2*m + 3*(m+1)/5 + y + y/4 - y/100 + y/400) % 7) + 1; } void TDate::set_day(int n) { _val = makedata(n, month(), year()); } void TDate::set_month(int n) { _val = makedata(day(), n, year()); } void TDate::set_year(int n) { _val = makedata(day(), month(), n); } TDate::operator const char*() const { return string(); } TDate& TDate::operator =(const char* s) { return *this = TDate(s); } void TDate::print_on(ostream& out) const { out << string(); } void TDate::read_from(istream& in) { char s[256]; in >> s; if (isdate(s)) _val = cpackdata(s); else _val = NULLDATE; } char* TDate::string(TDate_mgafmt yearf, char sep, TDate_mgafmt dayf, TDate_mgafmt monthf, TDate_order ord) const { if (!ok()) return ""; int yeardgts = (int)yearf; if (yearf == def || dayf != def || monthf != def || ord > amg_date) { // nonstandard: use new format // yearf == def significa usa il formato standard specificato TString dfm(32); if (yearf == def) { yearf = (TDate_mgafmt)(_format[3] - '0'); ord = (TDate_order)(_format[0] - '0'); sep = _format[4]; } if (dayf == def) dayf = (TDate_mgafmt)(_format[1] - '0'); if (monthf== def) monthf = (TDate_mgafmt)(_format[2] - '0'); TString df(2), yf(4), mf(2); bool letterflag = FALSE; // format each one if (dayf == letters) { real ddd(day()); letterflag = TRUE; df = ddd.string("LETTERE"); } else if (dayf == weekday) { letterflag = TRUE; df = format("%s %d", itow(wday()), day()); } else df = format(dayf == brief ? "%d" : "%02d", day()); if (yearf == letters) { real ddd(year()); letterflag = TRUE; yf = ddd.string("LETTERE"); } else if (yearf == brief && year() < 2000) yf = format("%d", year() - 1900); else yf = format("%d", year()); if (monthf == letters) { letterflag = TRUE; mf = itom(month()); } else if (monthf == quarter) { if (ord < m_date) ord = ma_date; mf = format("%do trimestre", (month() / 3) + 1); } else mf = format(monthf == brief ? "%d" : "%02d", month()); if (letterflag || sep == 'S') sep = ' '; // build date string // single field dfm = ""; switch (ord) { case gma_date: dfm << df << sep << mf << sep << yf; break; case mga_date: dfm << mf << sep << df << sep << yf; break; case amg_date: dfm << yf << sep << mf << sep << df; break; case a_date: dfm << yf; break; case m_date: dfm << mf; break; case g_date: dfm << df; break; case ma_date: dfm << mf << sep << yf; break; } strcpy(__date_tmp_string, (const char*)dfm); } else { long wv = _val; int cnt = wv >= DAYBIAS ? 2000 : 1900; while (wv < 0) { cnt -= 100; wv += DAYBIAS; } ceditdata(wv, __date_tmp_string); if (strcmp(__date_tmp_string, " - - ") == 0) return ""; if (sep != '-') for (char* s = __date_tmp_string; *s; s++) if (*s == '-') *s = sep; if (yeardgts > 2) { char s[8]; int year = cnt + atoi(__date_tmp_string + 6); if (yeardgts == 3) sprintf(s, "%03d", year % 1000); else sprintf(s, "%04d", year); __date_tmp_string[6] = '\0'; strcat(__date_tmp_string, s); if (ord == amg_date) { char* d = __date_tmp_string; const char g[3] = { d[0], d[1], '\0' }; const char m[3] = { d[3], d[4], '\0' }; sprintf(d, "%s%c%s%c%s", &d[6], sep, m, sep, g); } else if (ord == mga_date) { char* d = __date_tmp_string; char c = d[0]; d[0] = d[3]; d[3] = c; c = d[1]; d[1] = d[4]; d[4] = c; } } else if (yeardgts == ANSI) { char* s = __date_tmp_string; s[2] = '\0'; s[5] = '\0'; const int day = atoi(s); const int month = atoi(s + 3); const int year = atoi(s + 6); sprintf(__date_tmp_string, "%04d%02d%02d", year, month, day); } } return __date_tmp_string; } int TDate::day() const { return ::day(_val); } int TDate::month() const { return ::month(_val); } int TDate::year() const { return ::year(_val); } void TDate::addmonth(int nmonth) { _val = ::addmonth(_val, nmonth); } void TDate::addyear(int nyear) { _val = ::addyear(_val, nyear); } 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; char s1[16]; sprintf(s1, "%02d-%02d-%02d", day, month, year%100); return (bool)cverdata(s1); } return (bool)cverdata((char*)s); } bool TDate::ok() const { return _val <= 2 * DAYBIAS && _val >= -2 * DAYBIAS; } TDate& operator +(const TDate& a, long nday) { __tmp_date = long(a) + nday; return __tmp_date; } TDate& operator +(const long nday, const TDate& b) { __tmp_date = long(b) + nday; return __tmp_date; } TDate& operator -(const TDate& a, long nday) { __tmp_date = long(a)- nday; return __tmp_date; } void swap(TDate& a, TDate& b) { __tmp_date = b; b = a; a = __tmp_date; } const TDate& fnc_min(const TDate& a, const TDate& b) { if (a < b) return a; else return b; } const TDate& fnc_max(const TDate& a, const TDate& b) { if (a > b) return a; else return b; } // Converte un numero da 1 a 12 nel corrispondente mese const char* itom(byte m) { const char* nomi[12] = { "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre" }; return nomi[(m-1) % 12]; } const char* itow(byte d) { const char* nomi[7] = { "Lunedi", "Martedi", "Mercoledi", "Giovedi", "Venerdi", "Sabato", "Domenica" }; return nomi[(d-1) % 7]; }