1994-08-22 11:15:31 +00:00
|
|
|
|
#include <ctype.h>
|
2002-02-28 11:35:23 +00:00
|
|
|
|
#include <stdlib.h>
|
1998-02-24 10:37:28 +00:00
|
|
|
|
#include <time.h>
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
|
|
|
|
#define __DATE_CPP
|
|
|
|
|
#include <date.h>
|
2002-09-13 14:56:23 +00:00
|
|
|
|
#include <diction.h>
|
1995-05-18 14:18:01 +00:00
|
|
|
|
#include <real.h>
|
1994-08-22 11:15:31 +00:00
|
|
|
|
#include <strings.h>
|
|
|
|
|
|
1995-06-23 15:26:52 +00:00
|
|
|
|
#define DAYYEAR 365
|
1994-09-07 17:00:25 +00:00
|
|
|
|
#define DAYBIAS 36525L
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
2002-09-13 14:56:23 +00:00
|
|
|
|
static const byte _days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
|
|
|
|
|
|
|
|
|
inline bool is_leap(int year)
|
|
|
|
|
{ return (year % 4) == 0; }
|
|
|
|
|
|
1995-05-18 14:18:01 +00:00
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
// Utility functions
|
|
|
|
|
///////////////////////////////////////////////////////////
|
1995-05-09 09:12:26 +00:00
|
|
|
|
|
|
|
|
|
TDate::TDate(const TDate &d) : _val(d._val)
|
1995-05-18 14:18:01 +00:00
|
|
|
|
{}
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
|
|
|
|
TDate::TDate(long l) : _val(l)
|
|
|
|
|
{
|
|
|
|
|
if (_val == TODAY)
|
|
|
|
|
{
|
2003-06-26 14:51:30 +00:00
|
|
|
|
_val = NULLDATE;
|
1996-05-23 16:28:10 +00:00
|
|
|
|
time_t lt;
|
2003-06-26 14:51:30 +00:00
|
|
|
|
if (time(<) != -1)
|
|
|
|
|
{
|
|
|
|
|
struct tm * timeloc = localtime(<);
|
|
|
|
|
if (timeloc != NULL)
|
|
|
|
|
_val = makedata(timeloc->tm_mday, timeloc->tm_mon+1, timeloc->tm_year + 1900);
|
|
|
|
|
}
|
1998-02-24 10:37:28 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
1995-06-23 15:26:52 +00:00
|
|
|
|
if (_val == 0)
|
|
|
|
|
_val = NULLDATE;
|
|
|
|
|
else
|
1998-02-24 10:37:28 +00:00
|
|
|
|
{
|
1995-06-23 15:26:52 +00:00
|
|
|
|
if (_val < 1000000L)
|
|
|
|
|
{
|
|
|
|
|
long wd = _val;
|
|
|
|
|
int cnt = 1900;
|
|
|
|
|
if (wd > DAYBIAS)
|
|
|
|
|
{
|
|
|
|
|
wd -= DAYBIAS;
|
|
|
|
|
cnt += 100;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
while (wd < 0)
|
|
|
|
|
{
|
|
|
|
|
cnt -= 100;
|
|
|
|
|
wd += DAYBIAS;
|
|
|
|
|
}
|
2002-09-13 14:56:23 +00:00
|
|
|
|
int m, y, leap;
|
|
|
|
|
for(y = 0; wd > DAYYEAR + (leap = is_leap(y)); y++)
|
1995-06-23 15:26:52 +00:00
|
|
|
|
wd -= (DAYYEAR + leap);
|
1995-07-13 09:48:22 +00:00
|
|
|
|
for(m = 0; wd > (_days_in_month[m] + (leap && (m == 1))); m++)
|
|
|
|
|
wd -= (_days_in_month[m] + (leap && (m == 1)));
|
1995-06-23 15:26:52 +00:00
|
|
|
|
_val = makedata((int) wd, m+1, y+cnt);
|
|
|
|
|
}
|
1998-02-24 10:37:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TDate::TDate(const char* s)
|
|
|
|
|
{
|
|
|
|
|
_val = NULLDATE;
|
1995-08-09 09:54:36 +00:00
|
|
|
|
|
1995-12-13 15:13:51 +00:00
|
|
|
|
const int len = (s && *s) ? strlen(s) : 0;
|
1995-08-09 09:54:36 +00:00
|
|
|
|
if (len != 8 && len != 10)
|
1995-05-18 14:18:01 +00:00
|
|
|
|
return;
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
2004-03-12 15:08:44 +00:00
|
|
|
|
int d = 0, m = 0, y = 0, i;
|
1995-08-09 09:54:36 +00:00
|
|
|
|
if (len == 8)
|
|
|
|
|
{
|
2004-03-12 15:08:44 +00:00
|
|
|
|
for (i = 0; i < 8; i++)
|
1995-08-09 09:54:36 +00:00
|
|
|
|
if (!isdigit(s[i])) break;
|
|
|
|
|
if (i == 8)
|
|
|
|
|
{
|
2004-04-26 13:37:16 +00:00
|
|
|
|
TString8 str(s);
|
1996-05-23 16:28:10 +00:00
|
|
|
|
d = atoi(((const char *)str)+6); str.cut(6);
|
|
|
|
|
m = atoi(((const char *)str)+4); str.cut(4);
|
|
|
|
|
y = atoi(((const char *)str)+0);
|
1995-08-09 09:54:36 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (len == 10)
|
|
|
|
|
{
|
|
|
|
|
if (s[2] == s[5] && !isdigit(s[2]))
|
|
|
|
|
{
|
|
|
|
|
d = atoi(s);
|
|
|
|
|
m = atoi(&s[3]);
|
|
|
|
|
y = atoi(&s[6]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef DBG
|
2003-06-26 14:51:30 +00:00
|
|
|
|
if (d < 1 || d > 31 || m < 1 || m > 12 || y < 0)
|
1995-08-09 09:54:36 +00:00
|
|
|
|
yesnofatal_box("Lamentati con Guy se la data %s non viene accettata!", s);
|
|
|
|
|
#endif
|
|
|
|
|
_val = makedata(d, m, y);
|
1995-05-09 09:12:26 +00:00
|
|
|
|
}
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
|
|
|
|
TDate::TDate(int day, int month, int year)
|
|
|
|
|
{
|
1995-08-09 09:54:36 +00:00
|
|
|
|
if (day >= 1 && day <= 31 && month >= 1 && month <= 12 && year > 0)
|
1995-06-23 15:26:52 +00:00
|
|
|
|
_val = makedata(day, month, year);
|
1994-08-22 11:15:31 +00:00
|
|
|
|
else
|
1995-06-23 15:26:52 +00:00
|
|
|
|
_val = NULLDATE;
|
1995-05-09 09:12:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
1994-09-23 10:27:04 +00:00
|
|
|
|
int TDate::last_day(int month, int year)
|
1994-09-08 14:40:02 +00:00
|
|
|
|
// parse_filastrok(
|
1995-05-18 14:18:01 +00:00
|
|
|
|
// "trenta giorni ha novembre
|
1994-09-08 14:40:02 +00:00
|
|
|
|
// con april, giugno e settembre
|
1995-05-09 09:12:26 +00:00
|
|
|
|
// son ventotto case uno
|
1994-09-08 14:40:02 +00:00
|
|
|
|
// per default ce n'ha trentuno");
|
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
int d = _days_in_month[month-1];
|
2003-02-05 14:26:24 +00:00
|
|
|
|
if (month == 2 && is_leap(year))
|
2002-09-13 14:56:23 +00:00
|
|
|
|
d++;
|
1994-09-23 10:27:04 +00:00
|
|
|
|
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());
|
1994-09-08 14:40:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-04-30 15:31:34 +00:00
|
|
|
|
bool TDate::empty() const
|
1997-06-04 14:38:22 +00:00
|
|
|
|
{
|
|
|
|
|
return _val == 0;
|
|
|
|
|
}
|
|
|
|
|
|
1995-05-09 09:12:26 +00:00
|
|
|
|
int TDate::wday() const
|
|
|
|
|
{
|
|
|
|
|
// day of week (1=lunedi)
|
1995-05-18 14:18:01 +00:00
|
|
|
|
// DDJ algorithm (4/1995) Della serie: "non e' colpa mia se funziona".
|
1995-05-09 09:12:26 +00:00
|
|
|
|
int m = month();
|
|
|
|
|
int d = day();
|
|
|
|
|
int y = year();
|
|
|
|
|
|
1995-05-18 14:18:01 +00:00
|
|
|
|
if (m <= 2) // Gennaio e Febbraio sono gli ultimi mesi dell'anno scorso
|
1995-05-09 09:12:26 +00:00
|
|
|
|
{
|
|
|
|
|
y --;
|
|
|
|
|
m += 12;
|
|
|
|
|
}
|
|
|
|
|
|
1995-05-18 14:18:01 +00:00
|
|
|
|
return ((d + 2*m + 3*(m+1)/5 + y + y/4 - y/100 + y/400) % 7) + 1; // Pure magic
|
1995-05-09 09:12:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-11-03 11:40:09 +00:00
|
|
|
|
void TDate::set_day(int n)
|
|
|
|
|
{
|
|
|
|
|
CHECK(n > 0 && n < 32, "TDate::set_day: giorno insensato");
|
|
|
|
|
_val = makedata(n, month(), year());
|
|
|
|
|
}
|
|
|
|
|
void TDate::set_month(int n)
|
|
|
|
|
{
|
|
|
|
|
CHECK(n > 0 && n < 13, "TDate::set_month: mese impossibile");
|
|
|
|
|
_val = makedata(day(), n, year());
|
|
|
|
|
}
|
1999-04-06 15:34:39 +00:00
|
|
|
|
|
|
|
|
|
void TDate::set_year(int n)
|
|
|
|
|
{
|
|
|
|
|
_val = makedata(day(), month(), n);
|
|
|
|
|
}
|
1994-09-08 14:40:02 +00:00
|
|
|
|
|
1994-08-22 11:15:31 +00:00
|
|
|
|
TDate::operator const char*() const
|
|
|
|
|
{
|
1995-05-09 09:12:26 +00:00
|
|
|
|
return string();
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TDate& TDate::operator =(const char* s)
|
|
|
|
|
{
|
|
|
|
|
return *this = TDate(s);
|
|
|
|
|
}
|
|
|
|
|
|
1999-01-19 09:15:17 +00:00
|
|
|
|
TDate& TDate::operator =(long val)
|
|
|
|
|
{
|
|
|
|
|
if (val < 0L)
|
2003-06-26 14:51:30 +00:00
|
|
|
|
*this = TDate(val);
|
|
|
|
|
else
|
|
|
|
|
_val = val;
|
1999-01-19 09:15:17 +00:00
|
|
|
|
return *this;
|
|
|
|
|
}
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
|
|
|
|
void TDate::print_on(ostream& out) const
|
|
|
|
|
{
|
|
|
|
|
out << string();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TDate::read_from(istream& in)
|
|
|
|
|
{
|
|
|
|
|
char s[256];
|
|
|
|
|
in >> s;
|
1995-08-09 09:54:36 +00:00
|
|
|
|
TDate d(s);
|
|
|
|
|
_val = d._val;
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
1997-11-26 11:10:07 +00:00
|
|
|
|
TObject* TDate::dup() const
|
|
|
|
|
{
|
|
|
|
|
TDate * d = new TDate(*this);
|
|
|
|
|
return d;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
1995-05-17 17:05:52 +00:00
|
|
|
|
// @mfunc Ritorna la data in formato di stringa (anche in formato ANSI)
|
|
|
|
|
//
|
|
|
|
|
// @rdesc Se si tratta di una data valida ritorna la stringa secondo il
|
|
|
|
|
// formato scelto (vedi <t TDate_mgafmt>), altrimenti ritorna ""
|
|
|
|
|
char* TDate::string(
|
|
|
|
|
TDate_mgafmt yearf, // @parm Formato per l'anno (default def)
|
|
|
|
|
char sep, // @parm Carattere separatore (default '-')
|
|
|
|
|
TDate_mgafmt dayf, // @parm Formato per il giorno (default def)
|
|
|
|
|
TDate_mgafmt monthf, // @parm Formato per il mese (default def)
|
|
|
|
|
TDate_order ord) const // @parm Ordine con la quale visualizzare la data
|
|
|
|
|
// (vedi <t TDate_order>; default gma_date)
|
1995-05-09 09:12:26 +00:00
|
|
|
|
{
|
1995-05-18 14:18:01 +00:00
|
|
|
|
if (!ok() || *this == botime)
|
|
|
|
|
return "";
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
1995-05-18 14:18:01 +00:00
|
|
|
|
if (yearf == ANSI)
|
|
|
|
|
{
|
|
|
|
|
yearf = full;
|
|
|
|
|
ord = amg_date;
|
1995-06-23 15:26:52 +00:00
|
|
|
|
sep='\0';
|
1995-05-18 14:18:01 +00:00
|
|
|
|
}
|
1995-05-09 09:12:26 +00:00
|
|
|
|
|
2002-07-03 14:48:48 +00:00
|
|
|
|
TString80 df, yf, mf;
|
1995-05-18 14:18:01 +00:00
|
|
|
|
bool letterflag = FALSE;
|
1995-05-09 09:12:26 +00:00
|
|
|
|
|
1995-05-18 14:18:01 +00:00
|
|
|
|
// format day
|
|
|
|
|
if (dayf == letters)
|
1995-06-23 15:26:52 +00:00
|
|
|
|
{
|
1995-05-18 14:18:01 +00:00
|
|
|
|
const real ddd(day());
|
|
|
|
|
df = ddd.string("LETTERE");
|
|
|
|
|
letterflag = TRUE;
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
1995-05-18 14:18:01 +00:00
|
|
|
|
else if (dayf == weekday)
|
1995-05-09 09:12:26 +00:00
|
|
|
|
{
|
1998-02-24 10:37:28 +00:00
|
|
|
|
df.format("%s %d", itow(wday()), day());
|
1995-05-18 14:18:01 +00:00
|
|
|
|
letterflag = TRUE;
|
|
|
|
|
}
|
|
|
|
|
else
|
1998-02-24 10:37:28 +00:00
|
|
|
|
df.format(dayf == brief ? "%d" : "%02d", day());
|
1995-05-18 14:18:01 +00:00
|
|
|
|
|
|
|
|
|
// format year
|
|
|
|
|
if (yearf == letters)
|
1995-06-23 15:26:52 +00:00
|
|
|
|
{
|
1995-05-18 14:18:01 +00:00
|
|
|
|
const real ddd(year());
|
|
|
|
|
yf = ddd.string("LETTERE");
|
|
|
|
|
letterflag = TRUE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (yearf == brief)
|
1998-02-24 10:37:28 +00:00
|
|
|
|
yf.format("%02d", year() % 100);
|
1995-05-09 09:12:26 +00:00
|
|
|
|
else
|
1998-02-24 10:37:28 +00:00
|
|
|
|
yf.format("%04d", year());
|
1995-05-18 14:18:01 +00:00
|
|
|
|
|
|
|
|
|
// format month
|
|
|
|
|
if (monthf == letters)
|
|
|
|
|
{
|
|
|
|
|
letterflag = TRUE;
|
|
|
|
|
mf = itom(month());
|
1995-05-09 09:12:26 +00:00
|
|
|
|
}
|
1995-05-18 14:18:01 +00:00
|
|
|
|
else if (monthf == quarter)
|
|
|
|
|
{
|
|
|
|
|
if (ord < m_date) ord = ma_date;
|
2002-09-13 14:56:23 +00:00
|
|
|
|
mf.format("%s %d", TR("trimestre"), (month()/3)+1);
|
1995-05-18 14:18:01 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
1998-02-24 10:37:28 +00:00
|
|
|
|
mf.format(monthf == brief ? "%d" : "%02d", month());
|
1995-05-18 14:18:01 +00:00
|
|
|
|
|
|
|
|
|
if ((letterflag && sep == '-') || sep == 'S')
|
|
|
|
|
sep = ' ';
|
|
|
|
|
|
|
|
|
|
// build date string
|
|
|
|
|
|
2002-07-03 14:48:48 +00:00
|
|
|
|
TString& dfm = get_tmp_string(80);
|
|
|
|
|
|
1995-05-18 14:18:01 +00:00
|
|
|
|
switch (ord)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
default:
|
|
|
|
|
dfm << df << sep << mf << sep << yf;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
1998-11-03 10:27:35 +00:00
|
|
|
|
return dfm.get_buffer();
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-06-23 15:26:52 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
|
|
|
|
int TDate::day() const
|
|
|
|
|
{
|
1997-06-25 07:04:37 +00:00
|
|
|
|
return int(_val % 100L);
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TDate::month() const
|
|
|
|
|
{
|
1997-06-25 07:04:37 +00:00
|
|
|
|
return int((_val % 10000L) / 100L);
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int TDate::year() const
|
1995-06-23 15:26:52 +00:00
|
|
|
|
{
|
1997-06-25 07:04:37 +00:00
|
|
|
|
return int(_val / 10000L);
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1997-06-03 09:45:44 +00:00
|
|
|
|
int TDate::week() const
|
|
|
|
|
{
|
1998-11-03 10:27:35 +00:00
|
|
|
|
TDate y(1, 1, year());
|
|
|
|
|
const int w = y.wday();
|
|
|
|
|
if (w > 1) y -= w-1;
|
|
|
|
|
return int((*this - y) / 7 + 1);
|
1997-06-03 09:45:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-04-06 15:34:39 +00:00
|
|
|
|
TDate& TDate::operator +=(long nday)
|
|
|
|
|
{
|
|
|
|
|
const long d = day() + nday;
|
|
|
|
|
if (d > 0 && d < 29)
|
|
|
|
|
_val += nday;
|
|
|
|
|
else
|
|
|
|
|
_val = julian2date(date2julian() + nday);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
1997-06-03 09:45:44 +00:00
|
|
|
|
|
2000-05-05 15:25:49 +00:00
|
|
|
|
void TDate::get_week_year(int &weekd, int &yeard, bool complete)
|
|
|
|
|
{
|
|
|
|
|
weekd = week();
|
|
|
|
|
yeard = year();
|
|
|
|
|
const int wday = TDate(1,1,yeard).wday();
|
|
|
|
|
if (complete)
|
|
|
|
|
{
|
|
|
|
|
if (wday != 1)
|
|
|
|
|
weekd --;
|
|
|
|
|
if (weekd <= 0)
|
|
|
|
|
{
|
|
|
|
|
weekd = 52;
|
|
|
|
|
yeard --;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (weekd > 52)
|
|
|
|
|
{
|
|
|
|
|
weekd = 1;
|
|
|
|
|
yeard ++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1994-08-22 11:15:31 +00:00
|
|
|
|
void TDate::addmonth(int nmonth)
|
|
|
|
|
{
|
1995-06-23 15:26:52 +00:00
|
|
|
|
const int wday = day();
|
1997-06-25 07:04:37 +00:00
|
|
|
|
int wyear = year();
|
|
|
|
|
int wmonth = month() + nmonth;
|
|
|
|
|
while (wmonth > 12)
|
1995-06-23 15:26:52 +00:00
|
|
|
|
{
|
|
|
|
|
wmonth -= 12;
|
|
|
|
|
wyear++;
|
|
|
|
|
}
|
|
|
|
|
_val = makedata(wday, wmonth, wyear);
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TDate::addyear(int nyear)
|
|
|
|
|
{
|
1997-06-25 07:04:37 +00:00
|
|
|
|
const int wday = day();
|
|
|
|
|
const int wmonth = month();
|
|
|
|
|
const int wyear = year() + nyear;
|
1995-06-23 15:26:52 +00:00
|
|
|
|
_val = makedata(wday, wmonth, wyear);
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TDate::isdate(const char* s)
|
1995-08-09 09:54:36 +00:00
|
|
|
|
{
|
|
|
|
|
const int len = strlen(s);
|
|
|
|
|
if (len != 8 && len != 10)
|
1995-07-13 09:48:22 +00:00
|
|
|
|
return FALSE;
|
1995-06-23 15:26:52 +00:00
|
|
|
|
|
2004-03-12 15:08:44 +00:00
|
|
|
|
int d = 0, m = 0, y = 0, i;
|
1995-08-09 09:54:36 +00:00
|
|
|
|
if (len == 8)
|
|
|
|
|
{
|
2004-03-12 15:08:44 +00:00
|
|
|
|
for (i = 0; i < 8; i++)
|
1995-08-09 09:54:36 +00:00
|
|
|
|
if (!isdigit(s[i])) break;
|
|
|
|
|
if (i == 8)
|
|
|
|
|
{
|
|
|
|
|
TString16 str(s);
|
1996-05-23 16:28:10 +00:00
|
|
|
|
d = atoi(((const char *)str)+6); str.cut(6);
|
|
|
|
|
m = atoi(((const char *)str)+4); str.cut(4);
|
|
|
|
|
y = atoi(((const char *)str)+0);
|
1995-08-09 09:54:36 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (len == 10)
|
|
|
|
|
{
|
|
|
|
|
if (s[2] == s[5] && !isdigit(s[2]))
|
|
|
|
|
{
|
|
|
|
|
d = atoi(s);
|
|
|
|
|
m = atoi(&s[3]);
|
|
|
|
|
y = atoi(&s[6]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (d < 1 || d > 31 ||
|
|
|
|
|
m < 1 || m > 12 ||
|
|
|
|
|
y < 0)
|
1995-06-23 15:26:52 +00:00
|
|
|
|
return FALSE;
|
|
|
|
|
|
1999-02-02 08:43:43 +00:00
|
|
|
|
return d <= last_day(m,y);
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool TDate::ok() const
|
|
|
|
|
{
|
1995-06-23 15:26:52 +00:00
|
|
|
|
return _val > 0;
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-11-03 10:27:35 +00:00
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
1995-05-17 17:05:52 +00:00
|
|
|
|
// @func TDate& | operator + | Incrementa la data di un certo numero di giorni
|
1998-10-01 13:52:27 +00:00
|
|
|
|
TDate operator +(
|
1995-05-17 17:05:52 +00:00
|
|
|
|
const TDate& a, // @parm Data a cui aggiungere i giorni
|
|
|
|
|
long nday) // @parm Numero di giorni da aggiungere
|
|
|
|
|
|
|
|
|
|
// @syntax operator + (const TDate& a, long nday)
|
|
|
|
|
// @syntax operator + (long nday, const TDate& a)
|
|
|
|
|
//
|
|
|
|
|
// @comm E' indifferente quale parametro viene passato per primo
|
1994-08-22 11:15:31 +00:00
|
|
|
|
{
|
1998-11-03 10:27:35 +00:00
|
|
|
|
TDate tmp(a);
|
|
|
|
|
tmp += nday;
|
1998-10-01 13:52:27 +00:00
|
|
|
|
return tmp;
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1998-10-01 13:52:27 +00:00
|
|
|
|
TDate operator +(const long nday, const TDate& b)
|
1994-08-22 11:15:31 +00:00
|
|
|
|
{
|
1998-11-03 10:27:35 +00:00
|
|
|
|
TDate tmp(b);
|
|
|
|
|
tmp += nday;
|
1998-10-01 13:52:27 +00:00
|
|
|
|
return tmp;
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
1995-05-17 17:05:52 +00:00
|
|
|
|
// @func TDate& | operator - | Decrementa la data di un certo numero di giorni
|
1998-10-01 13:52:27 +00:00
|
|
|
|
TDate operator -(
|
1995-05-17 17:05:52 +00:00
|
|
|
|
const TDate& a, // @parm Data da decrementare
|
|
|
|
|
long nday) // @parm Numero di giorni da togliere
|
1994-08-22 11:15:31 +00:00
|
|
|
|
{
|
1998-11-03 10:27:35 +00:00
|
|
|
|
TDate tmp(a);
|
|
|
|
|
tmp += -nday;
|
1998-10-01 13:52:27 +00:00
|
|
|
|
return tmp;
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
1995-10-12 15:04:26 +00:00
|
|
|
|
// @func TDate& | operator - | Calcola la differenza tra due date
|
|
|
|
|
long operator -(
|
|
|
|
|
const TDate& a, // @parm Data da decrementare
|
|
|
|
|
const TDate& b) // @parm Data da sottrarre
|
|
|
|
|
{
|
|
|
|
|
const long diff = a.date2julian() - b.date2julian();
|
|
|
|
|
return diff;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
1995-05-17 17:05:52 +00:00
|
|
|
|
// @func Scambia la data <p a> con la data <p b>
|
|
|
|
|
void swap(
|
|
|
|
|
TDate& a, // @parm Prima data da scambiare
|
|
|
|
|
TDate& b) // @parm Seconda data da scambiare
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
|
|
|
|
{
|
1998-10-01 13:52:27 +00:00
|
|
|
|
const TDate tmp = b;
|
1994-08-22 11:15:31 +00:00
|
|
|
|
b = a;
|
1998-10-01 13:52:27 +00:00
|
|
|
|
a = tmp;
|
1994-08-22 11:15:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
1995-05-17 17:05:52 +00:00
|
|
|
|
// @func Ritorna la data piu' piccola tra <p a> e <p b>
|
|
|
|
|
const TDate& fnc_min(
|
|
|
|
|
const TDate& a, // @parm Prima data da confrontare
|
|
|
|
|
const TDate& b) // @parm Secondo data da confrontare
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
if (a < b) return a;
|
|
|
|
|
else return b;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
1995-05-17 17:05:52 +00:00
|
|
|
|
// @func Ritorna la data piu' grande tra <p a> e <p b>
|
|
|
|
|
const TDate& fnc_max(
|
|
|
|
|
const TDate& a, // @parm Prima data da confrontare
|
|
|
|
|
const TDate& b) // @parm Secondo data da confrontare
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
if (a > b) return a;
|
|
|
|
|
else return b;
|
|
|
|
|
}
|
|
|
|
|
|
1995-05-18 14:18:01 +00:00
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
// TFormatted_date
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
TFormatted_date::TFormatted_date(int day, int month, int year, const char* form)
|
|
|
|
|
: TDate(day, month, year)
|
|
|
|
|
{
|
|
|
|
|
set_format(form);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TFormatted_date::TFormatted_date(const TDate& d, const char* form)
|
|
|
|
|
: TDate(d)
|
|
|
|
|
{
|
|
|
|
|
set_format(form);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TFormatted_date::TFormatted_date(const TFormatted_date& d)
|
|
|
|
|
: TDate(d)
|
|
|
|
|
{
|
|
|
|
|
set_format(d._format);
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
1995-05-18 14:18:01 +00:00
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @mfunc Permette di stabilire il criterio di formattazione delle date
|
1995-05-18 14:18:01 +00:00
|
|
|
|
void TFormatted_date::set_format(
|
|
|
|
|
const char* f) // @parm Stringa di 5 caratteri che indica il formato della data
|
|
|
|
|
|
|
|
|
|
// @comm Ogni carattere del parametro <p f> permette di settare un tipo di formattazione
|
|
|
|
|
// della data:
|
|
|
|
|
// <nl>1<> carattere -<gt> FORMATO. Puo' assumere i seguenti valori:
|
|
|
|
|
// <nl> 1 = giorno-mese-anno
|
1995-06-12 10:49:19 +00:00
|
|
|
|
// <nl> 2 = mese-anno-giorno
|
1995-05-18 14:18:01 +00:00
|
|
|
|
// <nl> 3 = anno-giorno-mese
|
|
|
|
|
// <nl> 4 = solo anno
|
|
|
|
|
// <nl> 5 = solo mese
|
|
|
|
|
// <nl> 6 = solo giorno
|
|
|
|
|
// <nl> 7 = mese-anno
|
|
|
|
|
// <nl><nl>2<> carattere -<gt> Formato GIORNO. Puo assumere i seguenti valori:
|
|
|
|
|
// <nl> 2 = formato normale (es. 4)
|
|
|
|
|
// <nl> 4 = formato con 0 (es. 04)
|
|
|
|
|
// <nl> 5 = lettere (es. quattro)
|
|
|
|
|
// <nl> 6 = giorno della settimana
|
|
|
|
|
// <nl><nl>3<> carattere -<gt> Formato MESE. Puo assumere i seguenti valori:
|
|
|
|
|
// <nl> 2 = formato normale (es. 4)
|
|
|
|
|
// <nl> 4 = formato con 0 (es. 04)
|
|
|
|
|
// <nl> 5 = lettere (es. quattro)
|
|
|
|
|
// <nl> 7 = trimestre
|
|
|
|
|
// <nl><nl>4<> carattere -<gt> Formato ANNO. Puo' assumere i seguenti valori:
|
|
|
|
|
// <nl> 2 = breve (es. 95)
|
|
|
|
|
// <nl> 4 = lungo (es. 1995)
|
1998-05-27 13:41:48 +00:00
|
|
|
|
// <nl><nl>5<> carattere -<gt> Carattere SEPARATORE. Puo' essere un carattere o lo spazio o essere omesso (sep= char nullo)
|
1995-05-18 14:18:01 +00:00
|
|
|
|
|
|
|
|
|
{
|
1998-05-27 13:41:48 +00:00
|
|
|
|
CHECKS(memchr(f, 0, 4) == NULL, "Bad date format (you must define all the first 4 chars) :", f);
|
1995-05-18 14:18:01 +00:00
|
|
|
|
memcpy(_format, f, 5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char* TFormatted_date::string() const
|
|
|
|
|
{
|
|
|
|
|
TDate_mgafmt yearf = (TDate_mgafmt)(_format[3] - '0');
|
|
|
|
|
char sep = _format[4];
|
|
|
|
|
TDate_mgafmt dayf = (TDate_mgafmt)(_format[1] - '0');
|
|
|
|
|
TDate_mgafmt monthf = (TDate_mgafmt)(_format[2] - '0');
|
|
|
|
|
TDate_order ord = (TDate_order)(_format[0] - '0');
|
|
|
|
|
|
|
|
|
|
return TDate::string(yearf, sep, dayf, monthf, ord);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
// Utility functions
|
|
|
|
|
///////////////////////////////////////////////////////////
|
1994-08-22 11:15:31 +00:00
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
1995-05-17 17:05:52 +00:00
|
|
|
|
// @func Converte un numero da 1 a 12 nel corrispondente mese
|
|
|
|
|
const char* itom(
|
1998-04-30 14:59:01 +00:00
|
|
|
|
int m) // @parm Numero del mese da convertire in parole (da 1 a 12)
|
1995-05-17 17:05:52 +00:00
|
|
|
|
|
|
|
|
|
// @comm Se il parametro <p m> e' maggiore di 12 viene calcolato il nome del
|
|
|
|
|
// mese corrispondente a tale cifra (es. 15 = "Marzo")
|
1994-08-22 11:15:31 +00:00
|
|
|
|
{
|
1999-04-06 15:34:39 +00:00
|
|
|
|
CHECK(m>=1, "Il mese indicato deve essere un numero da 1 a 12 ");
|
2002-09-13 14:56:23 +00:00
|
|
|
|
const char* const nomi[12] =
|
1994-08-22 11:15:31 +00:00
|
|
|
|
{
|
2002-09-13 14:56:23 +00:00
|
|
|
|
TR("Gennaio"), TR("Febbraio"), TR("Marzo"),
|
|
|
|
|
TR("Aprile"), TR("Maggio"), TR("Giugno"),
|
|
|
|
|
TR("Luglio"), TR("Agosto"), TR("Settembre"),
|
|
|
|
|
TR("Ottobre"), TR("Novembre"), TR("Dicembre")
|
|
|
|
|
};
|
1994-08-22 11:15:31 +00:00
|
|
|
|
return nomi[(m-1) % 12];
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
1995-05-17 17:05:52 +00:00
|
|
|
|
// @func Ritorna il nome del giorno (1-7)
|
|
|
|
|
const char* itow(
|
1998-04-30 14:59:01 +00:00
|
|
|
|
int d) // @parm Numero del giorna da convertire in parole (da 1 a 7)
|
1995-05-17 17:05:52 +00:00
|
|
|
|
|
|
|
|
|
// @comm Come primo giorno della setimana e' preso il Lunedi.
|
|
|
|
|
// <nl>Se il parametro <p d> e' maggiore di 7 viene calcolato il nome del
|
|
|
|
|
// giorno corrispondente a tale cifra (es. 15 = "Lunedi")
|
1994-08-22 11:15:31 +00:00
|
|
|
|
{
|
1998-04-30 14:59:01 +00:00
|
|
|
|
CHECKD(d >= 1 && d <= 7, "Bad week day ", d);
|
2002-09-13 14:56:23 +00:00
|
|
|
|
const char* const nomi[7] =
|
|
|
|
|
{ TR("Luned<EFBFBD>"), TR("Marted<EFBFBD>"), TR("Mercoled<EFBFBD>"), TR("Gioved<EFBFBD>"),
|
|
|
|
|
TR("Venerd<EFBFBD>"), TR("Sabato"), TR("Domenica") };
|
1994-08-22 11:15:31 +00:00
|
|
|
|
return nomi[(d-1) % 7];
|
|
|
|
|
}
|
1995-05-18 14:18:01 +00:00
|
|
|
|
|