Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Duda En Calendario Gregoriano :s

Iniciado por yens, 17 de Enero de 2006, 07:09:08 PM

« anterior - próximo »

yens

 Buenas! llevo un buen tiempo pensando en porqué no consigo saber cuál es el problema de mi programa, asi que me he decidido a preguntar por aquí.

El programa (programado en C) tiene que ser capaz de imprimirte en pantalla el día de la semana, según la fecha introducida. Lo he planteado de forma que sume todos los días (contando bisiestos) que hay desde el 15 de octubre de 1582 Viernes(dia de inicio del Calendario Gregoriano) hasta la fecha indicada y mediante el uso de divisiones modulares sacar si es bisiesto o no (año%4==0 es bisiesto) (dias_totales%7==0 viernes.. etc).

Con algunas fechas me funciona, y con otras no y nosé a qué se debe, creo tener todo bien planteado... me podríais echar una mano? os dejo el código aquí mismo:

Citar
#include //printf
#include //system

main(){
//VARIABLES

  //variables introducidas por el usuario
  int dia,mes,anno;
  //variable que almacena dias de los meses
  int meses[12]={31,28,31,30,31,30,31,31,30,31,30,31};
  //variable que almacena los dias de la semana
  char dia_semana[7][10]={"Viernes","Sabado","Domingo","Lunes","Martes","Miercoles","Jueves"};
  //variable para obtener mes introducido respecto a la tabla meses
  int mes_tabla;
  //variables auxiliares
  int i,j,dias=0;
  //variable que contiene el nº de dias previos al 15 octubre del año 1528
  int dias_previos=288; //31+28+31+30+31+30+31+31+30+15
  //bienvenida del programa
  printf("Bienvenido al programa que le permitira conocer el dia de la semana\nintroduciendo la fecha deseada segun el Calendario Gregoriano.\n\n");
  //***printf("Introduzca la fecha en formato dd,mm,aaaa: ");***
  //recogemos fecha introducida y la almacenamos
  printf("Introduzca el dia: ");
  scanf("%i",&dia);
  printf("Introduzca el mes: ");
  scanf("%i",&mes);
  printf("Introduzca el anno: ");
  scanf("%i",&anno);
  //correcion del mes introducido respecto a la tabla
  mes_tabla=mes-1;
  //comprobacion del anno bisiesto
  if(anno%4==0){
       meses[1]=29;
       }
  //calculo de dias desde el inicio del calendario (15/10/1582) hasta el dia 1 del mes introducido
  for(i=0;i       dias=dias+meses;
       }   
  dias=dias-288;//restamos dias_previos que no entran en el calendario gregoriano
  dias=dias+dia;//sumamos dias desde el dia 1 del mes introducido hasta el dia introducido
  //mediante division modular sabremos el dia de la semana, partiendo de que viernes=0
  dias=dias%7;
  //comprobacion de dia e impresion por pantalla del dia
  printf("\nEl dia de la semana es: ");
  for(i=0;i<7;i++){                       
       if(i==dias){
            for(j=0;j<10;j++){
                 printf("%c",dia_semana[dias][j]);
                 }
            break;
            }
       }
 
//fin de programa
printf("\n\n");
system ("pause");
}

Se me acaba de ocurrir que igual se debía a que las variables tipo numero int almacenan hasta 2^32 (en el caso de mi compilador, devcpp) numeros posibles... pero me extraña que sea por eso... xD.

Espero que sea fácil de solucionar el problema... porque yo no le encuentro nada mal (oh sí que nunca tengo fallos... xDD). Gracias de antemano ;)

yens

 Ha sido escribir en un papel una fecha, comprobar poco a poco y sacar el fallo!!!!

Sorry por usar espacio sin sentido... xDDD. El problema estaba en que no tenia en cuenta los dias de los años, estaba trabajando siempre sobre el año 1582, por eso al introducir fechas menores que 15 octubes del 1582 (o de cualquier año, pues siempre interpretaba el mismo) me daba un valor de días en el dias%7 menor que 0, por consecuente no escribia el dia... xd!

Grugnorr

 Agregar que no todos los años múltiplos de 4 son bisiestos...  busca un poco más
hat the hells!

Sacrifai

 Cómo calcular el día de la semana mentalmente

Siguiendo estos pasos puedes calcular el día de la semana de una fecha cualquiera de los años de cuatro cifras que empiecen por 19 (como 1986) o 20 (como 2004)

  1. Divide las dos últimas cifras del año entre 4, desechando el resto.
  2. Suma al resultado el día del mes.
  3. Suma la clave del mes: EFM AMJ JAS OND = 144 025 036 146[a]
  4. Resta 1 para los meses de Enero y Febrero en los años bisiestos  
  5. Resta 1 si la fecha empieza por 20.
  6. Añade el número formado por los dos últimos dígitos del año.
  7. Divide entre 7 y toma el resto.

El resto te indica el día de la semana, siendo el:
0 sábado, 1 domingo, 2 lunes, 3 martes, 4 miércoles, 5 jueves, 6 viernes

Notas:

[a] Para memorizar esta secuencia observa que: 122 =144, 52 =025, 62 =036 y 122 +2=146

En el calendario gregoriano son bisiestos todos los años múltiplos de 4. Los años  seculares (los que acaban en 00),  solamente son bisiestos cuando son múltiplos de 400. Por ejemplo, 1900 no fue bisiesto, a pesar de ser múltiplo de 4, ya que es un año secular no múltiplo de 400, en cambio si lo ha sido 2000. Para saber cuando un número es múltiplo de 4 basta fijarse en sus dos últimas cifras, si son múltiplo de 4 (dos veces divisibles por 2), también lo es el número.  

Marci

  :blink: ... :blink:
Mentalmente dice, ya sera con lapiz y papel.

Pogacha

Cita de: "Sacrifai"[a] Para memorizar esta secuencia observa que: 122 =144, 52 =025, 62 =036 y 122 +2=146
Lo mire dos veces hasta darme cuenta 12^2 = 144, 5^2 = 025, 6^2 = 036 y 12^2 +2 = 146


TheWind

  Son bisiestos todos los años que cumplan estas condiciones:

- Multiplo de 4
- No ser multiplo de 400 ni de 4000 (En 400 años hay solo 98 bisisestos, 1600 no fue bisiesto aunque le tocaba)

Eso da un rango valido de 1582 hasta el 24999, ya que el 25000 ya habria q efectuar una correccion de 1 dia, pero no se ha decidido aun como se va  a hacer  (total, hay margen aún).
Se puede reslver el problema en una unica linea mediante una única formula q transforme la fecha en el dia directamente teniendo en cuenta q las semanas del año se repiten cada 28 años (no estoy seguro de si es cada 28 o cada 27).

Salu2

yens

 Me he estado informando y llegué a la conclusión de que:

Es bisiesto si:

- Es múltiplo de 4 y no de 100.
- Si es múltiplo de 4, pero también lo es de 100, si es también de 400 será bisiesto, sino no.

Estoy pensando en tratar de reducir todo a una línea de código con fórmula como has comentado The Wind, pero la verdad es que no lo veo claro... xD.

TheWind

 yo tengo hecha parte de esa formula de un viejo ejercicio.. haber si aun conservo el source code (tiene casi 12 años ya) y te posteo el trozo relevante ok?

Salu2

yens

 Vale, muchas gracias! De todas formas postearé en breves el codigo fuente del ejercicio totalmente resuelto desde mi razonamiento, y con algunas modificaciones en el concepto para ahorrar recursos jeje.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.