00001 #include "Utilitarios/DataTempo/data.H"
00002
00003 #include <ctime>
00004
00005 using namespace Utilitarios::DataTempo;
00006 using namespace Utilitarios::Manipuladores;
00007
00008 using namespace std;
00009
00010 istream& Utilitarios::DataTempo::operator >> (istream& entrada, Mes& mes)
00011 {
00012 string nome_do_mes;
00013 entrada >> nome_do_mes;
00014 for(int i = 0; i != numero_total_de_meses; ++i)
00015 if(nomes_dos_meses[i] == nome_do_mes) {
00016 mes = Mes(i);
00017 return entrada;
00018 }
00019 entrada.clear(ios::failbit);
00020 return entrada;
00021 }
00022
00023 string Utilitarios::DataTempo::nomes_dos_meses[numero_total_de_meses + 1] = {
00024 "",
00025 "Janeiro",
00026 "Fevereiro",
00027 "Março",
00028 "Abril",
00029 "Maio",
00030 "Junho",
00031 "Julho",
00032 "Agosto",
00033 "Setembro",
00034 "Outubro",
00035 "Novembro",
00036 "Dezembro"
00037 };
00038
00039
00040 std::istream& Utilitarios::DataTempo::operator >> (std::istream& entrada,
00041 DiaDaSemana& dia_da_semana)
00042 {
00043 string nome_do_dia;
00044 entrada >> nome_do_dia;
00045 for(int i = 0; i != numero_total_de_dias_da_semana; ++i)
00046 if(nomes_dos_dias_da_semana[i] == nome_do_dia) {
00047 dia_da_semana = DiaDaSemana(i);
00048 return entrada;
00049 }
00050 entrada.clear(ios::failbit);
00051 return entrada;
00052 }
00053
00054 string Utilitarios::DataTempo::
00055 nomes_dos_dias_da_semana[numero_total_de_dias_da_semana] = {
00056 "Domingo",
00057 "segunda-feira",
00058 "terça-feira",
00059 "quarta-feira",
00060 "quinta-feira",
00061 "sexta-feira",
00062 "Sábado"
00063 };
00064
00065
00066 void Utilitarios::DataTempo::Data::carrega(std::istream& entrada) {
00067 Ano ano;
00068 int mes;
00069 Dia dia;
00070
00071 entrada >> ano >> il
00072 >> mes >> il
00073 >> dia >> il;
00074
00075 if(not entrada or not cumpreInvariante())
00076 throw Erros::ErroAoCarregar("Utilitarios::DataTempo::Data");
00077
00078 ano_ = ano;
00079 mes_ = Mes(mes);
00080 dia_ = dia;
00081 }
00082
00083 Utilitarios::DataTempo::Data Utilitarios::DataTempo::Data::actual()
00084 {
00085 if(data_actual_obtida_do_sistema) {
00086 time_t aux = time(0);
00087 tm tempo_actual = *localtime(&aux);
00088
00089 return Data(1900 + tempo_actual.tm_year,
00090 Mes(tempo_actual.tm_mon + 1),
00091 tempo_actual.tm_mday);
00092 } else
00093 while(true) {
00094 cout << "Introduza a data actual (ano mes dia): ";
00095 Data data;
00096 cin >> data;
00097 if(not cin) {
00098 cin.clear();
00099 cin >> il;
00100 cout << "Data errada." << endl;
00101 } else
00102 return data;
00103 }
00104 }
00105
00106 std::istream&
00107 Utilitarios::DataTempo::operator >> (std::istream& entrada, Data& data) {
00108 Ano ano;
00109 int mes;
00110 Dia dia;
00111
00112 entrada >> ano >> ws;
00113
00114 if(ano < Data::ano_minimo) {
00115 entrada.clear(ios::failbit);
00116 return entrada;
00117 }
00118
00119 if(entrada.peek() == '/')
00120 entrada.get();
00121
00122 entrada >> mes >> ws;
00123
00124 if(mes < 1 or mes > numero_total_de_meses) {
00125 entrada.clear(ios::failbit);
00126 return entrada;
00127 }
00128
00129 if(entrada.peek() == '/')
00130 entrada.get();
00131
00132 entrada >> dia;
00133
00134 if(dia < 0 or dia > numeroDeDiasEm(Mes(mes), ano)) {
00135 entrada.clear(ios::failbit);
00136 return entrada;
00137 }
00138
00139 if(entrada)
00140 data = Data(ano, Mes(mes), dia);
00141
00142 return entrada;
00143 }
00144
00145 bool Utilitarios::DataTempo::Data::data_actual_obtida_do_sistema = true;
00146
00147 #ifdef TESTE
00148
00149 #include <fstream>
00150
00151 void testaMes()
00152 {
00153 cout << "Testando DataTempo::Mes..." << endl;
00154
00155 Mes mes = janeiro;
00156
00157 if(numero_total_de_meses != 12)
00158 cerr << "Erro: número total de meses." << endl;
00159
00160 #if __GNUC__ > 1 && __GNUC_MINOR__ >= 96
00161 mes += 13;
00162 if(mes != fevereiro)
00163 cerr << "Erro: operador +=." << endl;
00164 #else
00165 mes = fevereiro;
00166 #endif
00167
00168 --mes;
00169 if(mes != janeiro)
00170 cerr << "Erro: operador -- prefixo." << endl;
00171
00172 mes--;
00173 if(mes != dezembro)
00174 cerr << "Erro: operador -- prefixo." << endl;
00175
00176 ++mes;
00177 Mes outro_mes = mes++;
00178 if(mes != fevereiro)
00179 cerr << "Erro: operador ++ prefixo ou sufixo." << endl;
00180 if(outro_mes != janeiro)
00181 cerr << "Erro: operador ++ sufixo." << endl;
00182
00183 #if __GNUC__ > 1 && __GNUC_MINOR__ >= 96
00184 outro_mes -= 13;
00185 if(outro_mes != dezembro)
00186 cerr << "Erro: operador -=." << endl;
00187 #else
00188 outro_mes = dezembro;
00189 #endif
00190
00191 if(outro_mes + 25 != janeiro)
00192 cerr << "Erro: operador +." << endl;
00193
00194 if(outro_mes + -25 != novembro)
00195 cerr << "Erro: operador +." << endl;
00196
00197 if(outro_mes - 25 != novembro)
00198 cerr << "Erro: operador -." << endl;
00199
00200 if(mes - outro_mes != 2)
00201 cerr << "Erro: operador - (entre meses)." << endl;
00202
00203 ofstream saida("teste");
00204 saida << mes << endl;
00205 saida.close();
00206
00207 ifstream entrada("teste");
00208 entrada >> outro_mes;
00209 if(outro_mes != mes)
00210 cerr << "Erro: operador << ou >>." << endl;
00211
00212 if(numeroDeDiasEm(dezembro, 2000) != 31)
00213 cerr << "Erro: numeroDeDiasEm()." << endl;
00214
00215 if(numeroDeDiasEm(fevereiro, 2000) != 29)
00216 cerr << "Erro: eBissexto()." << endl;
00217
00218 if(numeroDeDiasEm(fevereiro, 1900) != 28)
00219 cerr << "Erro: eBissexto()." << endl;
00220
00221 if(numeroDeDiasEm(fevereiro, 1996) != 29)
00222 cerr << "Erro: eBissexto()." << endl;
00223 }
00224
00225 void testaDiaDaSemana()
00226 {
00227 cout << "Testando DataTempo::DiaDaSemana..." << endl;
00228
00229 DiaDaSemana dia = segunda_feira;
00230
00231 if(numero_total_de_dias_da_semana != 7)
00232 cerr << "Erro: número total de dias da semana." << endl;
00233
00234 #if __GNUC__ > 1 && __GNUC_MINOR__ >= 96
00235 dia += 8;
00236 if(dia != terca_feira)
00237 cerr << "Erro: operador +=." << endl;
00238 #else
00239 dia = terca_feira;
00240 #endif
00241
00242 --dia;
00243 if(dia != segunda_feira)
00244 cerr << "Erro: operador -- prefixo." << endl;
00245
00246 dia--;
00247 if(dia != domingo)
00248 cerr << "Erro: operador -- prefixo." << endl;
00249
00250 ++dia;
00251 DiaDaSemana outro_dia = dia++;
00252 if(dia != terca_feira)
00253 cerr << "Erro: operador ++ prefixo ou sufixo." << endl;
00254 if(outro_dia != segunda_feira)
00255 cerr << "Erro: operador ++ sufixo." << endl;
00256
00257 #if __GNUC__ > 1 && __GNUC_MINOR__ >= 96
00258 outro_dia -= 8;
00259 if(outro_dia != domingo)
00260 cerr << "Erro: operador -=." << endl;
00261 #else
00262 outro_dia = domingo;
00263 #endif
00264
00265 if(outro_dia + 15 != segunda_feira)
00266 cerr << "Erro: operador +." << endl;
00267
00268 if(outro_dia + -15 != sabado)
00269 cerr << "Erro: operador +." << endl;
00270
00271 if(outro_dia - 15 != sabado)
00272 cerr << "Erro: operador -." << endl;
00273
00274 if(dia - outro_dia != 2)
00275 cerr << "Erro: operador - (entre dias da semana)." << endl;
00276
00277 ofstream saida("teste");
00278 saida << dia << endl;
00279 saida.close();
00280
00281 ifstream entrada("teste");
00282 entrada >> outro_dia;
00283 if(outro_dia != dia)
00284 cerr << "Erro: operador << ou >>." << endl;
00285 }
00286
00287 void testaData()
00288 {
00289 cout << "Testando DataTempo::Data..." << endl;
00290
00291 Data data(1965, setembro, 14);
00292
00293 if(data.ano() != 1965)
00294 cerr << "Erro: Data::ano() ou construtor." << endl;
00295
00296 if(data.mes() != 9)
00297 cerr << "Erro: Data::mes() ou construtor." << endl;
00298
00299 if(data.dia() != 14)
00300 cerr << "Erro: Data::dia() ou construtor." << endl;
00301
00302 if(data != Data(1965, setembro, 14))
00303 cerr << "Erro: operador !=." << endl;
00304
00305 if(not (data == Data(1965, setembro, 14)))
00306 cerr << "Erro: operador ==." << endl;
00307
00308 Data outra_data = data + 12983;
00309 if(outra_data != Data(2001, abril, 1))
00310 cerr << "Erro: operador +." << endl;
00311
00312 ofstream saida;
00313
00314 saida.open("teste");
00315 saida << data << endl;
00316 saida.close();
00317
00318 ifstream entrada;
00319
00320 entrada.open("teste");
00321 entrada >> outra_data;
00322 if(outra_data != data)
00323 cerr << "Erro: operador << ou >>." << endl;
00324 entrada.close();
00325
00326 outra_data = data + 12983;
00327
00328 saida.open("teste");
00329 data.guarda(saida);
00330 outra_data.guarda(saida);
00331 saida.close();
00332
00333 entrada.open("teste");
00334 Data data_lida(entrada);
00335 if(data_lida != data)
00336 cerr << "Erro: operador << ou >>." << endl;
00337 data.carrega(entrada);
00338 if(data != outra_data)
00339 cerr << "Erro: carrega()." << endl;
00340 entrada.close();
00341
00342 Data data_de_transicao(1999, dezembro, 31);
00343
00344 ++data_de_transicao;
00345 if(data_de_transicao != Data(2000, janeiro, 1))
00346 cerr << "Erro: Data::operator ++ ()." << endl;
00347
00348 --data_de_transicao;
00349 if(data_de_transicao != Data(1999, dezembro, 31))
00350 cerr << "Erro: Data::operator -- ()." << endl;
00351
00352 Data anterior = data_de_transicao++;
00353 if(data_de_transicao != Data(2000, janeiro, 1))
00354 cerr << "Erro: Data::operator ++ (int)." << endl;
00355 if(anterior != Data(1999, dezembro, 31))
00356 cerr << "Erro: Data::operator ++ (int)." << endl;
00357
00358 anterior = data_de_transicao--;
00359 if(data_de_transicao != Data(1999, dezembro, 31))
00360 cerr << "Erro: Data::operator -- (int)." << endl;
00361 if(anterior != Data(2000, janeiro, 1))
00362 cerr << "Erro: Data::operator -- (int)." << endl;
00363
00364 if(not anterior.anoEBissexto())
00365 cerr << "Erro: Data::anoEBissexto()." << endl;
00366 if(data_de_transicao.anoEBissexto())
00367 cerr << "Erro: Data::anoEBissexto()." << endl;
00368
00369 Data data_juliana(2452001);
00370 if(data_juliana != Data(2001, abril, 1))
00371 cerr << "Erro: Data::Data(int dia_juliano)." << endl;
00372
00373 if(data_juliana.diaDaSemana() != domingo)
00374 cerr << "Erro: Data::diaDaSemana()." << endl;
00375
00376 --data_juliana;
00377 if(data_juliana != Data(2001, marco, 31))
00378 cerr << "Erro: Data::operator -- ()." << endl;
00379
00380 if(data_juliana.diaDaSemana() != sabado)
00381 cerr << "Erro: Data::diaDaSemana()." << endl;
00382
00383 Data para_juliana(2001, abril, 1);
00384 if(para_juliana.diaJuliano() != 2452001)
00385 cerr << "Erro: Data::diaJuliano()." << endl;
00386
00387 Data nao_bissexto(1900, fevereiro, 1);
00388 if(nao_bissexto.anoEBissexto())
00389 cerr << "Erro: Data::anoEBissexto()." << endl;
00390
00391 Data bissexto(1904, fevereiro, 1);
00392 if(not bissexto.anoEBissexto())
00393 cerr << "Erro: Data::anoEBissexto()." << endl;
00394
00395 if(nao_bissexto.numeroDeDiasNoMes() != 28 or
00396 bissexto.numeroDeDiasNoMes() != 29)
00397 cerr << "Erro: Data::numeroDeDiasNoMes()." << endl;
00398
00399 data = Data(1965, setembro, 14);
00400 outra_data = data;
00401
00402 outra_data += 12983;
00403 if(outra_data != Data(2001, abril, 1))
00404 cerr << "Erro: operador +=." << endl;
00405
00406 outra_data -= 12983;
00407 if(outra_data != Data(1965, setembro, 14))
00408 cerr << "Erro: operador -=." << endl;
00409
00410 cout << "Verificação manual: data actual = " << Data::actual() << endl;
00411
00412 Data::estabeleceDataActualPedidaAoUtilizador();
00413
00414 cout << "Verificação manual: deve pedir data actual!" << endl;
00415 data = Data::actual();
00416 cout << "Verificação manual: data pedida = " << data << endl;
00417
00418 Data::estabeleceDataActualObtidaDoSistema();
00419 cout << "Verificação manual: não deve pedir data actual!" << endl;
00420 cout << "Verificação manual: data actual = " << Data::actual() << endl;
00421 }
00422
00423 int main()
00424 {
00425 testaMes();
00426 testaDiaDaSemana();
00427 testaData();
00428 }
00429
00430 #endif