Titulo : Funciones Date y Time=====================
Y ahora en otro orden de cosas vamos a tratar una serie de funciones
bajo el denominador común de Date y Time.
Estas funciones no son mías, son una traducción de lo originalmente publicado
en el
Foro CCS Library y su autor es
Aurelian NichitaYo me he limitado a traducirlas al español y probar que funcionan.
Incluye las funciones:
esAgnoBisiesto(int y)
diasDesdeAgno1(int y, int m, int d)
segundosDesdeHora0(int h, int m, int s)
segundosDesdeAgno1(int yr, mo, dy, hr, mi, se)
segundosEntre(int yr1, mo1, dy1, hr1, mi1, se1, yr2, mo2, dy2, hr2, mi2, se2)
ISODiaDeLaSemana(int YY, int MM, int DD)
ISONumeroDeLaSemana(int YY, int MM, int DD, int& weekOfYear, int& actualYear)
Codigo:
// Definiciones y Funciones de Date Time ////////////////////////////////////////////////
// Números ISO de los dias de la semana
#define LUNES 1
#define MARTES 2
#define MIERCOLES 3
#define JUEVES 4
#define VIERNES 5
#define SABADO 6
#define DOMINGO 7
const int Dias_de_cada_Mes[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} };
const int Orden_Dias_Semana[7] = {6, 7, 1, 2, 3, 4, 5};
#define SEGUNDOS_EN_UN_DIA 86400
#define SEGUNDOS_EN_UNA_HORA 3600
#define SEGUNDOS_EN_UN_MINUTO 60
#define MINUTOS_EN_UN_DIA 1440
#define MINUTOS_EN_UNA_HORA 60
#define HORAS_EN_UN_DIA 24
// Algunas funciones que seran usadas mas adelante
#inline
short esAgnoBisiesto(int y) {
return (y % 4 == 0);
}
#separate
int32 diasDesdeAgno1(int y, int m, int d) {
int32 dias = 0;
int i;
short es_bisiesto;
es_bisiesto = esAgnoBisiesto(y);
for (i=1; i<y; i++) {
if (esAgnoBisiesto(i))
dias += 366;
else
dias += 365;
}
for (i=1; i<m; i++)
dias += Dias_de_cada_Mes[es_bisiesto][ i ];
dias += d;
return dias;
}
#separate
int32 segundosDesdeHora0(int h, int m, int s) {
int32 segundos;
segundos = (int32)h * SEGUNDOS_EN_UNA_HORA;
segundos += (int32)m * SEGUNDOS_EN_UN_MINUTO;
segundos += s;
return segundos;
}
#separate
int32 segundosDesdeAgno1(int yr, mo, dy, hr, mi, se) {
int32 segundos;
segundos = diasDesdeAgno1(yr, mo, dy) * SEGUNDOS_EN_UN_DIA;
segundos += segundosDesdeHora0(hr, mi, se);
return segundos;
}
// Calcula el numero de segundos entre dos fechas y horas
// Adaptado para años entre 2001 y 2135 (limitado por el tamaño de los int32)
#separate
int32 segundosEntre(int yr1, mo1, dy1, hr1, mi1, se1, yr2, mo2, dy2, hr2, mi2, se2) {
int32 inicio;
int32 final;
inicio = segundosDesdeAgno1(yr1, mo1, dy1, hr1, mi1, se1);
final = segundosDesdeAgno1(yr2, mo2, dy2, hr2, mi2, se2);
if (inicio > final)
return inicio-final;
else
return final-inicio;
}
// Calculo del dia de la semana. Adaptado SOLO para años del 2000 al 2099
#separate
int ISODiaDeLaSemana(int YY, int MM, int DD) {
signed long diaDeLaSemana;
int cent = 20; // YYYY / 100
// Algoritmo de congruencia de Zeller
if (MM < 3) {
MM = MM + 12;
if (YY > 0)
YY--;
else {
YY = 99;
cent--;
}
}
diaDeLaSemana = DD;
diaDeLaSemana += (((signed long)MM + 1) * 26) / 10;
diaDeLaSemana += YY;
diaDeLaSemana += YY / 4;
diaDeLaSemana += cent / 4;
diaDeLaSemana -= cent * 2;
while (diaDeLaSemana < 0)
diaDeLaSemana += 7;
diaDeLaSemana %= 7;
return Orden_Dias_Semana[(int)diaDeLaSemana]; // Ahora tenemos el número ISO del dia de la semana
}
// Calculo de número ISO de la semana. Adaptado SOLO para años del 2001 al 2098
#separate
void ISONumeroDeLaSemana(int YY, int MM, int DD, int& weekOfYear, int& actualYear)
{
signed long diaDelAgno;
int DiaDeLaSemanaInicial;
int DiaDeLaSemanaFinal;
short bisiesto;
signed int i;
do {
bisiesto = esAgnoBisiesto(YY);
diaDelAgno = 0;
for (i=1; i<=MM; i++) {
if (i < MM)
diaDelAgno += Dias_de_cada_Mes[bisiesto][ i ];
else
diaDelAgno += DD;
}
actualYear = YY;
DiaDeLaSemanaInicial = ISODiaDeLaSemana(actualYear, 1, 1);
if (DiaDeLaSemanaInicial > JUEVES)
diaDelAgno -= 8 - DiaDeLaSemanaInicial;
else
diaDelAgno += DiaDeLaSemanaInicial - 1;
if (diaDelAgno <= 0)
weekOfYear = 0xFF;
else {
weekOfYear = diaDelAgno / 7;
if (diaDelAgno % 7 != 0)
weekOfYear++;
if (weekOfYear > 52) {
DiaDeLaSemanaFinal = DiaDeLaSemanaInicial;
if (bisiesto) {
if (DiaDeLaSemanaFinal == DOMINGO)
DiaDeLaSemanaFinal = LUNES;
else
DiaDeLaSemanaFinal++;
}
if (DiaDeLaSemanaFinal < JUEVES) {
actualYear++;
weekOfYear = 1;
}
}
}
if (weekOfYear == 0xFF) {
if ((--DD)==0) {
if ((--MM)==0) {
YY--;
MM = 12;
}
DD = Dias_de_cada_Mes[esAgnoBisiesto(YY)][MM];
}
}
} while (weekOfYear == 0xFF);
}