[C con Clase] class fecha

Salvador Pozo salvador en conclase.net
Vie Feb 25 09:20:06 CET 2011


Hola:

Hay que hacer varias consideraciones a tu ejemplo. Lamentablemente, la fea costumbre de cambiar la hora dos veces al año puede acarrear serios problemas a los programadores.

Primero: las fechas anteriores al 1/1/1970 no son admisibles. Es decir, no se pueden representar usando el formato condensado, ya que este almacena segundos desde esa fecha, y no admite valores negativos.

Segundo: mktime convierte el valor de la fecha indicada en la estructura a segundos, pero hace una corrección según la zona horaria en la que te encuentres.
En mi caso, al estar en España, resta una hora (3600 segundos), porque estoy en la zona GMT-1.
Esto puede producir problemas, ya que si intento conseguir el valor para las cero horas del 1/1/1970 se produce un error.

Tercero: todos los campos de la estructura tm deben ser inicializados, con excepción de tm_wday y tm_yday. O sea, que tienes que poner una hora, minuto y segundo, y asignar el valor a tm_isdst (que indica si está activo el horarios de ahorro de energía).
 
Bueno, lo del horario de ahorro no importa demasiado, se usa para saber si un día concreto tiene 23, 24 o 25 horas, y no nos importa en este caso. Puede asignarse el valor -1.

Consecuencia: si necesitas trabajar con fechas anteriores a 1970, no te sirve esta solución.

El segundo inconveniente se puede corregir usando como hora las 12 de mediodia.

Tu ejemplo corregido puede quedar así:

----8<------
#include<iostream>
#include<ctime>

using namespace std;

class fecha{
	int dia;
	int mes;
	int anio;
public:
	fecha() : dia(1), mes(1), anio(1970) {}//constructor
	void presenta();
	void sumadias(int dias); //sin implementar
};

void fecha::presenta(){
	cout<<"\n   Mostrando fecha "<<"\n\n";
	cout<<"Dia: "<<dia<<"\n\n";
	cout<<"Mes : "<<mes<<"\n\n";
	cout<<"Anio : "<<anio<<"\n\n";
}

void fecha::sumadias(int dias) {
	time_t fechaensegundos;
	struct tm fech;
	
	fech.tm_mday = dia;
	fech.tm_mon = (mes -1);
	fech.tm_year = (anio-1900);
	fech.tm_sec = fech.tm_min = 0;
	fech.tm_hour = 12;
	fech.tm_isdst = -1; // No está activo
	
	fechaensegundos = mktime(&fech);//convierte la fecha en segundos
	cout <<"\nfecha actual es: "<< fech.tm_mday << "/" << fech.tm_mon+1 << "/" << fech.tm_year+1900 << "\n";

	fechaensegundos+= (dias*24*60*60); //suma
	cout << "\nluego de sumar "<<dias<<" dias :" ;
	fech = *gmtime(&fechaensegundos);
	cout<< fech.tm_mday << "/" << fech.tm_mon+1 << "/" << (fech.tm_year+1900) << "\n";
}

int main(){
	fecha F;
	F.presenta();
	F.sumadias(9);
	return 0;
} 
----8<------

w> //probado en turbo C 3.0 con cero errores

Un último consejo: consigue un compilador más actualizado, Turbo C está obsoleto. :)

-- 
Salvador Pozo (Administrador)
mailto:salvador en conclase.net


Más información sobre la lista de distribución Cconclase