Aggiornati form Corretta query_mode della TRelapp Corretto warning long->int in text git-svn-id: svn://10.65.10.50/trunk@1376 c028cbd2-c16b-5b4b-a496-9718f37d4682
521 lines
12 KiB
C++
Executable File
521 lines
12 KiB
C++
Executable File
#include <ctype.h>
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
|
||
#define __DATE_CPP
|
||
#include <date.h>
|
||
#include <extcdecl.h>
|
||
#include <real.h>
|
||
#include <strings.h>
|
||
#include <utility.h>
|
||
|
||
#define DAYBIAS 36525L
|
||
#define NULLDATE -99999L
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Utility functions
|
||
///////////////////////////////////////////////////////////
|
||
|
||
// @doc EXTERNAL
|
||
|
||
HIDDEN TDate __tmp_date;
|
||
HIDDEN char __date_tmp_string[128];
|
||
|
||
TDate::TDate(const TDate &d) : _val(d._val)
|
||
{}
|
||
|
||
TDate::TDate(long l) : _val(l)
|
||
{
|
||
if (_val == TODAY)
|
||
{
|
||
char s[16];
|
||
cgetdata(&_val, s);
|
||
}
|
||
}
|
||
|
||
|
||
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);
|
||
}
|
||
|
||
TDate::TDate(int day, int month, int year)
|
||
{
|
||
if (day == TODAY)
|
||
{
|
||
char s[16];
|
||
cgetdata(&_val, s);
|
||
}
|
||
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;
|
||
}
|
||
|
||
int TDate::last_day(int month, int year)
|
||
// parse_filastrok(
|
||
// "trenta giorni ha 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) Della serie: "non e' colpa mia se funziona".
|
||
int m = month();
|
||
int d = day();
|
||
int y = year();
|
||
|
||
if (m <= 2) // Gennaio e Febbraio sono gli ultimi mesi dell'anno scorso
|
||
{
|
||
y --;
|
||
m += 12;
|
||
}
|
||
|
||
return ((d + 2*m + 3*(m+1)/5 + y + y/4 - y/100 + y/400) % 7) + 1; // Pure magic
|
||
}
|
||
|
||
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;
|
||
}
|
||
|
||
// @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)
|
||
{
|
||
if (!ok() || *this == botime)
|
||
return "";
|
||
|
||
if (yearf == ANSI)
|
||
{
|
||
yearf = full;
|
||
ord = amg_date;
|
||
}
|
||
|
||
TString df(2), yf(4), mf(2);
|
||
bool letterflag = FALSE;
|
||
|
||
// format day
|
||
if (dayf == letters)
|
||
{
|
||
const real ddd(day());
|
||
df = ddd.string("LETTERE");
|
||
letterflag = TRUE;
|
||
}
|
||
else if (dayf == weekday)
|
||
{
|
||
df = format("%s %d", itow(wday()), day());
|
||
letterflag = TRUE;
|
||
}
|
||
else
|
||
df = format(dayf == brief ? "%d" : "%02d", day());
|
||
|
||
// format year
|
||
if (yearf == letters)
|
||
{
|
||
const real ddd(year());
|
||
yf = ddd.string("LETTERE");
|
||
letterflag = TRUE;
|
||
}
|
||
else
|
||
if (yearf == brief)
|
||
yf.format("%02d", year() % 100);
|
||
else
|
||
yf.format("%04d", year());
|
||
|
||
// format month
|
||
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 == '-') || sep == 'S')
|
||
sep = ' ';
|
||
|
||
// build date string
|
||
|
||
TFixed_string dfm(__date_tmp_string, 128);
|
||
dfm.cut(0);
|
||
|
||
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;
|
||
}
|
||
|
||
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;
|
||
}
|
||
|
||
|
||
// @func TDate& | operator + | Incrementa la data di un certo numero di giorni
|
||
TDate& operator +(
|
||
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
|
||
|
||
{
|
||
__tmp_date = long(a) + nday;
|
||
return __tmp_date;
|
||
}
|
||
|
||
|
||
TDate& operator +(const long nday, const TDate& b)
|
||
|
||
{
|
||
__tmp_date = long(b) + nday;
|
||
return __tmp_date;
|
||
}
|
||
|
||
|
||
// @func TDate& | operator - | Decrementa la data di un certo numero di giorni
|
||
TDate& operator -(
|
||
const TDate& a, // @parm Data da decrementare
|
||
long nday) // @parm Numero di giorni da togliere
|
||
|
||
{
|
||
__tmp_date = long(a)- nday;
|
||
return __tmp_date;
|
||
}
|
||
|
||
// @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
|
||
|
||
{
|
||
__tmp_date = b;
|
||
b = a;
|
||
a = __tmp_date;
|
||
}
|
||
|
||
|
||
// @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
|
||
|
||
{
|
||
if (a < b) return a;
|
||
else return b;
|
||
}
|
||
|
||
// @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
|
||
|
||
{
|
||
if (a > b) return a;
|
||
else return b;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// 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);
|
||
}
|
||
|
||
// @mfunc Permette di stabilire il criterio di formattazione delle date
|
||
|
||
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
|
||
// <nl> 2 = mese-anno-giorno
|
||
// <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)
|
||
// <nl><nl>5<> carattere -<gt> Carattere SEPARATORE. Puo' essere un carattere o lo spazio
|
||
|
||
{
|
||
CHECKS(memchr(f, 0, 5) == NULL, "Bad date format ", f);
|
||
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
|
||
///////////////////////////////////////////////////////////
|
||
|
||
// @func Converte un numero da 1 a 12 nel corrispondente mese
|
||
const char* itom(
|
||
byte m) // @parm Numero del mese da convertire in parole (da 1 a 12)
|
||
|
||
// @comm Se il parametro <p m> e' maggiore di 12 viene calcolato il nome del
|
||
// mese corrispondente a tale cifra (es. 15 = "Marzo")
|
||
{
|
||
const char* nomi[12] =
|
||
{
|
||
"Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno",
|
||
"Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"
|
||
};
|
||
|
||
return nomi[(m-1) % 12];
|
||
}
|
||
|
||
// @func Ritorna il nome del giorno (1-7)
|
||
const char* itow(
|
||
byte d) // @parm Numero del giorna da convertire in parole (da 1 a 7)
|
||
|
||
// @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")
|
||
{
|
||
const char* nomi[7] =
|
||
{ "Lunedi", "Martedi", "Mercoledi", "Giovedi", "Venerdi",
|
||
"Sabato", "Domenica" };
|
||
return nomi[(d-1) % 7];
|
||
}
|
||
|