Programa para averiguar el dia de la semana

Iniciado por Caster, 18 Julio 2013, 15:40 PM

0 Miembros y 1 Visitante están viendo este tema.

Caster

Buenas, en un libro que estoy leyendo viene un programa, que a partir de una fecha base (Lunes, Enero 1, 1900) averigua el dia de la semana introduciendo dia mes y año. El programa entero es el siguiente:

#include <stdio.h>

void leerentrada(int *pm, int *pd, int *pa);
int convertir(int mm, int dd, int aa);

int main()
{
   int mm, dd, aa;
   int dia_semana;

   static char *diasemana[] = {    "Domingo",
                                   "Lunes",
                                   "Martes",
                                   "Miércoles",
                                   "Jueves",
                                   "viernes",
                                   "Sabado"    };

   static char *mes[] = {  "Enero",
                           "Febrero",
                           "Marzo",
                           "Abril",
                           "Mayo",
                           "Junio",
                           "Julio",
                           "Agosto",
                           "Septiembre",
                           "Octubre",
                           "Noviembre",
                           "Diciembre" };

   printf("Rutina de conversión de fecha\n Para parar, introducir 0 0 0");

   leerentrada(&mm, &dd, &aa);

   while (mm > 0)
   {
       dia_semana = convertir (mm, dd, aa);
       printf("\n%s, %s %d, %d", diasemana[dia_semana], mes[mm-1], dd, aa);
       leerentrada(&mm, &dd, &aa);
   }
   return 0;
}

void leerentrada(int *pm, int *pd, int *pa)
{
   printf("\n\nIntroducir mm dd aaaa: ");
   scanf("%d %d %d", pm, pd, pa);
}

int convertir (int mm, int dd, int aa)
{
   long int ndias;     // numero de dias desde el comienzo de 1900
   long int nciclos;   //numero de ciclos de 4 años despues de 1900
   int nanios;         //numero de años despues del ultimo ciclo de 4 años
   int dia;            //dia de la semana (0, 1, 2, 3, 4, 5 o 6)

   aa -= 1900;

   ndias= (long) (30.42 * (mm - 1) + dd); //dia aproximado del año

   if (mm == 2) ++ndias;   //ajuste para febrero
   if ((mm > 2) && (mm < 8)) --ndias;  //ajuste para marzo-julio
   if ((aa % 4 == 0) && (mm > 2)) ++ndias; //ajuste para el año bisiesto

   nciclos = aa / 4;   //ciclos de 4 años a partir de 1900

   ndias += nciclos * 1461;    //añadir dias por ciclos de 4 años

   nanios = aa % 4;        //años despues del ultimo ciclo de 4 años

   if (nanios > 0) ndias += 365 * nanios + 1; //añadir dias por años despues del ultimo ciclo

   if (ndias > 59) --ndias; //ajustar para 1990 (NO años bisiesto)

   dia = ndias % 7;

   return (dia);
}


el codigo esta copiado exactamente igual que en libro, con los comentarios para explicarlo.

Me ha costado, pero he entendido, en parte, la logica del programa, porque lo que no entiendo es como hace la funcion convertir para sacar el dia de la semana, de esa funcion la unica linea que entiendo es esta:

aa -= 1900;

Lo que hace es sacar los años que han pasado desde el año 1900 hasta hoy, pero a partir de ahi no entiendo nada de nada y queria pedir a ver si alguien me lo explica de alguna manera mas clara que en libro.

eferion

Código (cpp) [Seleccionar]
ndias= (long) (30.42 * (mm - 1) + dd); //dia aproximado del año

Enero: 31 días
Febrero: 28 días
Marzo: 31 días
Abril: 30 días
...

Total días por año: 365 días ( 12 meses )
Media de días por mes: 365 / 12 = 30.41666

Para calcular el número de días calcula la media de días por mes y lo multiplica por el número de mes que hayas puesto.

Luego hace un ajuste rápido para los meses de menos de 31 días y ajusta también posibles años bisiestos y listo.

Caster

Cita de: eferion en 18 Julio 2013, 15:59 PM
Código (cpp) [Seleccionar]
ndias= (long) (30.42 * (mm - 1) + dd); //dia aproximado del año

Enero: 31 días
Febrero: 28 días
Marzo: 31 días
Abril: 30 días
...

Total días por año: 365 días ( 12 meses )
Media de días por mes: 365 / 12 = 30.41666

Para calcular el número de días calcula la media de días por mes y lo multiplica por el número de mes que hayas puesto.

Luego hace un ajuste rápido para los meses de menos de 31 días y ajusta también posibles años bisiestos y listo.

Es a partir de esa linea lo que no entiendo, por que si es Febrero le suma un dia, si esta entre Marzo y Julio se lo resta, a partir de esa linea no entiendo ningun ajuste de los que hace.

eferion

a ver... si tu sabes que, de promedio, cada mes tiene 30.42 días.

Si tu pones 5 de Julio de 1900... qué día del año es??

Lo primero es calcular el número de días hasta Julio, es decir, 30.42 * ( 7 - 1 ) = 182.52.

Como estás trabajando con enteros, el resultado se trunca a 182.

Si tu sumas: 31 + 28 + 31 + 30 + 31 + 30 = 181 ( uno menos ).

Luego en las siguientes líneas hace los ajustes necesarios para terminar de cuadrar el dato.

Una vez que tienes el número de días que hay entre el 1 de enero de 1900 y la fecha que has introducido, divides entre 7 y te quedas con el resto... ese resto te da el día de la semana.



Caster

Vale, ahora creo que lo entendi todo, muchas gracias.