elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Únete al Grupo Steam elhacker.NET


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Programas para calcular fechas
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Programas para calcular fechas  (Leído 3,696 veces)
NicolasPileci

Desconectado Desconectado

Mensajes: 32



Ver Perfil
Programas para calcular fechas
« en: 12 Mayo 2017, 20:50 pm »

Estimados,

Serian tan amables de indicarme que error tengo en estos dos programas:

1 - "Calcular fecha siguiente" (Me devuelve la misma fecha siempre)

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. typedef struct
  5. {
  6.    int dia,
  7.        mes,
  8.        año;
  9. }   tFecha;
  10.  
  11. void calcularFechaSiguiente (tFecha fecha);
  12.  
  13. int main()
  14. {
  15.    system ("color 0a");
  16.    tFecha fecha;
  17.    printf("Ingrese dia: \n\n");
  18.    scanf("%d",&fecha.dia);
  19.    printf("\nIngrese mes: \n\n");
  20.    scanf("%d",&fecha.mes);
  21.    printf("\nIngrese año: \n\n");
  22.    scanf("%d",&fecha.año);
  23.    calcularFechaSiguiente (fecha);
  24.    printf("\nFecha final: %d/%d/%d",fecha.dia,fecha.mes,fecha.año);
  25.    return 0;
  26. }
  27.  
  28. void calcularFechaSiguiente (tFecha fecha)
  29. {
  30.    if(fecha.mes == 4 || fecha.mes == 6 || fecha.mes == 9 || fecha.mes == 11)
  31.    {
  32.        if(fecha.dia == 30)
  33.        {
  34.            fecha.dia = 1;
  35.            fecha.mes++;
  36.        }
  37.        else
  38.            fecha.dia++;
  39.    }
  40.    if(fecha.mes == 2)
  41.    {
  42.        if ((fecha.año % 4 == 0) && ((fecha.año % 100 != 0) || (fecha.año % 400 == 0)))
  43.        {
  44.            if(fecha.dia == 29)
  45.            {
  46.                fecha.dia = 1;
  47.                fecha.mes++;
  48.            }
  49.            else
  50.                fecha.dia++;
  51.        }
  52.        if(fecha.dia == 28)
  53.        {
  54.            fecha.dia = 1;
  55.            fecha.mes++;
  56.        }
  57.        else
  58.            fecha.dia++;
  59.    }
  60.    if(fecha.mes == 1 || fecha.mes == 3 || fecha.mes == 5 || fecha.mes == 7 || fecha.mes == 8 || fecha.mes == 10)
  61.    {
  62.        if(fecha.dia == 31)
  63.        {
  64.            fecha.dia = 1;
  65.            fecha.mes++;
  66.        }
  67.        else
  68.            fecha.dia++;
  69.    }
  70.    if(fecha.dia == 31)
  71.    {
  72.        fecha.dia = 1;
  73.        fecha.mes = 1;
  74.        fecha.año++;
  75.    }
  76.    else
  77.        fecha.dia++;
  78. }

1 - "Calcular dias entres dos fechas" (Me devuelve un resultado cualquiera)

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. typedef struct
  5. {
  6.    int dia,
  7.        mes,
  8.        año;
  9. }   tFecha;
  10.  
  11. long calcularFecha (tFecha fecha1, tFecha fecha2);
  12.  
  13. int main()
  14. {
  15.    system ("color 0a");
  16.    tFecha fecha1,
  17.           fecha2;
  18.    long num;
  19.    printf("Ingrese dia - Primera fecha: \n\n");
  20.    scanf("%d",&fecha1.dia);
  21.    printf("\nIngrese mes - Primera fecha: \n\n");
  22.    scanf("%d",&fecha1.mes);
  23.    printf("\nIngrese año - Primera fecha: \n\n");
  24.    scanf("%d",&fecha1.año);
  25.    printf("\nIngrese dia - Segunda fecha: \n\n");
  26.    scanf("%d",&fecha2.dia);
  27.    printf("\nIngrese mes - Segunda fecha: \n\n");
  28.    scanf("%d",&fecha2.mes);
  29.    printf("\nIngrese año - Segunda fecha: \n\n");
  30.    scanf("%d",&fecha2.año);
  31.    num = calcularFecha (fecha1, fecha2);
  32.    printf("\nDias entre las dos fechas: %d.\n",num);
  33.    return 0;
  34. }
  35.  
  36. long calcularFecha (tFecha fecha1, tFecha fecha2)
  37. {
  38. long num = 0,
  39.        i;
  40. if(fecha1.año < fecha2.año)
  41.        for(i=fecha1.año;i<fecha2.año;i++)
  42.        {
  43.            if ((i % 4 == 0) && ((i % 100 != 0) || (i % 400 == 0)))
  44.                num += i*366;
  45.            else
  46.                num += i*365;
  47.        }
  48.    else
  49.        for(i=fecha2.año;i<fecha1.año;i++)
  50.        {
  51.            if ((i % 4 == 0) && ((i % 100 != 0) || (i % 400 == 0)))
  52.                num += i*366;
  53.            else
  54.                num += i*365;
  55.        }
  56.    if(fecha1.mes < fecha2.mes)
  57.        for(i=fecha1.mes;i<fecha2.mes;i++)
  58.        {
  59.            if(i == 4 || i == 6 || i == 9 || i == 11)
  60.                num += i*30;
  61.            if(i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12)
  62.                num += i*31;
  63.            if(i == 2)
  64.                num += i*28;
  65.        }
  66.    else
  67.        for(i=fecha2.mes;i<fecha1.mes;i++)
  68.        {
  69.            if(i == 4 || i == 6 || i == 9 || i == 11)
  70.                num += i*30;
  71.            if(i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12)
  72.                num += i*31;
  73.            if(i == 2)
  74.                num += i*28;
  75.        }
  76. if(fecha1.dia > fecha2.dia)
  77.        num += fecha1.dia - fecha2.dia;
  78. else
  79. num += fecha2.dia - fecha1.dia;
  80.    return num;
  81. }
  82.  

Desde ya muchas gracias.
Saludos!


En línea

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Programas para calcular fechas
« Respuesta #1 en: 12 Mayo 2017, 21:05 pm »

En el primero programa pasas la estructura por valor. Todos los cambios que hagas dentro de la función no se reflejarán fuera de ella, por eso debes pasarla por referencia (un puntero de ella o su dirección) y cuidado con el cambio de acceso a los datos del puntero a la estructura.

Para el segundo programa observa lo siguiente:
Código
  1. if(fecha1.año < fecha2.año)
  2.        for(i=fecha1.año;i<fecha2.año;i++)
  3.        {
  4.            if ((i % 4 == 0) && ((i % 100 != 0) || (i % 400 == 0)))
  5.                num += i*366;
  6.            else
  7.                num += i*365;
  8.        }

Fíjate que num va a tener el número erróneo de días por la simple razón de:
Supongamos que el año es el 2000. Pues en la primera iteración del bucle será 2000*365, a este número, en la segunda iteración será 2000 * 365 + 2001 * 365 y así. La fórmula está mal.


« Última modificación: 12 Mayo 2017, 21:57 pm por MAFUS » En línea

NicolasPileci

Desconectado Desconectado

Mensajes: 32



Ver Perfil
Re: Programas para calcular fechas
« Respuesta #2 en: 23 Mayo 2017, 20:57 pm »

Estimado,

Gracias por tu respuesta. Surgio otro problema dentro del primer programa y es que cuando ingreso un dia 30 y un mes 4, el resultado obtenido es 2/05/17. No puedo hallar el error.

Gracias!
En línea

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Programas para calcular fechas
« Respuesta #3 en: 23 Mayo 2017, 21:45 pm »

Error de lógica. Tal como lo tienes tu programa hace lo siguiente:
Código
  1. if(fecha.mes == 4 || fecha.mes == 6 || fecha.mes == 9 || fecha.mes == 11)
  2. {
  3.    if(fecha.dia == 30)
  4.    {
  5.        fecha.dia = 1;
  6.        fecha.mes++;
  7.    }
  8.    else
  9.        fecha.dia++;
  10. }
  11.  
  12. // ...
  13.  
  14. if(fecha.dia == 31)
  15. {
  16.    fecha.dia = 1;
  17.    fecha.mes = 1;
  18.    fecha.año++;
  19. }
  20. else
  21.    fecha.dia++;

Cómo puedes ver ese último if de la función se ejecuta y como no es día 31 te sumará un día más.
En línea

NicolasPileci

Desconectado Desconectado

Mensajes: 32



Ver Perfil
Re: Programas para calcular fechas
« Respuesta #4 en: 24 Mayo 2017, 14:45 pm »

Perdon,

Ya corregi el codigo, pero aun me sigue sumando un dia de mas en los meses de 30 dias.

Código
  1. void calcularFechaSiguiente (tFecha *fecha)
  2. {
  3.    if(fecha->mes == 4 || fecha->mes == 6 || fecha->mes == 9 || fecha->mes == 11)
  4.    {
  5.        if(fecha->dia == 30)
  6.        {
  7.            fecha->dia = 1;
  8.            fecha->mes++;
  9.        }
  10.        else
  11.            fecha->dia++;
  12.    }
  13.    if(fecha->mes == 2)
  14.    {
  15.        if (fecha->año % 4 == 0 && fecha->año % 100 != 0 || fecha->año % 400 == 0)
  16.        {
  17.            if(fecha->dia == 29)
  18.            {
  19.                fecha->dia = 1;
  20.                fecha->mes++;
  21.            }
  22.            else
  23.                fecha->dia++;
  24.        }
  25.        if(fecha->dia == 28)
  26.        {
  27.            fecha->dia = 1;
  28.            fecha->mes++;
  29.        }
  30.        else
  31.            fecha->dia++;
  32.    }
  33.    if(fecha->mes == 1 || fecha->mes == 3 || fecha->mes == 5 || fecha->mes == 7 || fecha->mes == 8 || fecha->mes == 10)
  34.    {
  35.        if(fecha->dia == 31)
  36.        {
  37.            fecha->dia = 1;
  38.            fecha->mes++;
  39.        }
  40.        else
  41.            fecha->dia++;
  42.    }
  43.    if(fecha->mes == 12)
  44.    {
  45.        if(fecha->dia == 31)
  46.        {
  47.            fecha->dia = 1;
  48.            fecha->mes = 1;
  49.            fecha->año++;
  50.        }
  51.        else
  52.            fecha->dia++;
  53.    }
  54. }
En línea

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Programas para calcular fechas
« Respuesta #5 en: 24 Mayo 2017, 15:59 pm »

De nuevo un error de lógica y parecido al de antes.

Los meses de 30 días están al principio de la función. Cuando los operas pasan a ser meses de 31 días PERO la función no se detiene y llega al código que opera los meses de 31 días. Tu variable ahora es un mes de 31 días y por tanto se le aplica el código de nuevo haciendo que se sume un día.

Tienes 3 formas de solucionar esto:
1. Pones return después de cada operación
2. Haces uso de else if
3. Usas un switch
En línea

Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 3.348


Ver Perfil
Re: Programas para calcular fechas
« Respuesta #6 en: 24 Mayo 2017, 17:49 pm »

El código es susceptible a errores, porque aunque o tratas bien, lo complicas... cometes el error de querer tratarlo en 'formato humano'....
Abstráete todo lo que puedas del asunto humano, y hazlo desde una perspectiva más matemática...entonces la solución queda sencilla (y el código más breve y legible)

Veamos... los meses son 12, el problema aparecerá pués en los días... que cada mes tiene su tela, icluído los años bisiestos...

Código:
//Entonces creamos un string que represente los meses. Y su contenido sean 12 caracteres
MESES= "@ABCDEFGHIJK" // empiezo en la arroba, si no es tu gusto, cambia como prefieras. En realidad, no lo usamos, se pone solo para que se vea de donde proceden los valores de las dos siguientes variables (sino quedaría oscuro).

//Ahora creamos otras también como string constantes
MesesDe31Dias = "@BDFGIK"  //esto es: enero, marzo, mayo, julio, agosto, octubre, diciembre
MeseeDe30Dias ="CEHJ" // esto es: abril, junio, septiembre, noviembre,
//MesesMenos30 = "A" //esto es, febrero... no se utiliza, se pone por claridad  

Ahora creamos la función: Básicamente simplifica la verificación de los meses y la actualización delos díasy mes, se invoca a otra función.

Código:
Funcion FechaSiguiente(Mes, Dia) boolean  //devolvemos false, si los datos de entrada no están en el rango...
   string M

   Si mes esta en el rango 1-12 luego
       M = (Mes + 63) //porque @ es el ASCII 64, y +63 porque mes está en el rango 1-12, no en rango 0-11
       Si MesesDe30Dias.Contiene(M) luego
           Si Dia esta en el rango 1-30 luego
                llamada FijarMesYDia(Dia, 30, Mes)
                Return TRUE
           Fin si
       Si no
           Si MesesDe31Dias.Contiene(M) luego
               Si Dia esta en el rango 1-31 luego
                   llamada FijarMesYDia(Dia, 31, Mes)
                   Return TRUE
               Fin si    
           Si no // el mes es febrero: porque está en rango y no es ninguno de los anteriores...
               Si Dia es menor de 28 luego
                       Incrementar Dia
               Si no //es día 28 ó 29, falta saber si es bisiesto
                    Si Año no es bisiesto // not ((año mod 4 = 0)   and (año mod 100 <> 0)) //falta la comprobación múltiplo de 400...
                        llamada FijarMesYDia(Dia, 28, Mes)
                    Si no // el año es bisiesto, es día 29?
                        llamada FijarMesYDia(Dia, 29, Mes)                                          
                    Fin si
                    Return TRUE
               Fin si    
           Fin si  
       Fin si
   Fin si
Fin funcion

Funcion FijarMesYDia( Dia, DiaLimite, Mes)
    si Dia < Dialimite luego
         Incrementar Dia
    Si no
        Si Mes < 12 luego   // MesLimite
            Incrementar Mes
        Si no
            Mes = 1
        Fin si
        Dia =1
    Fin si
Fin Funcion

Si necesitas velocidad (no parece quesea el caso, esto no se va allamar miles ni millones devecescadavez, supongo), puedes a la entrada cortar con una comprobación en la que la mayor parte delas veces va a caer, y solo unas pocas veces haría el restode comprobaciones:

Código:
Funcion FechaSiguienteRapido(Mes, Dia) boolean
     Si dia <28 luego
         Incrementar Dia
         Return TRUE
    Si no
        // el resto de veces, deberá comprobar los casos según meses, tal como se hace más arriba, pero solo cuando sean días 28,29,30 y 31
    Fin si
Fin Funcion
« Última modificación: 24 Mayo 2017, 17:50 pm por NEBIRE » En línea

NicolasPileci

Desconectado Desconectado

Mensajes: 32



Ver Perfil
Re: Programas para calcular fechas
« Respuesta #7 en: 24 Mayo 2017, 22:04 pm »

Muchas gracias a todos!

Un saludo.
En línea

engel lex
Moderador Global
***
Desconectado Desconectado

Mensajes: 15.514



Ver Perfil
Re: Programas para calcular fechas
« Respuesta #8 en: 24 Mayo 2017, 22:33 pm »

yo propondría una forma mucho más resumida... sería convertir en dias, calcular y convertir de vuelta

para calcular entre 2 dias
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. const int ajuste[12] = {0,1,-1,0,0,1,1,1,2,2,3,3};
  5.  
  6. typedef struct
  7. {
  8.    int dia,
  9.        mes,
  10.        ano,
  11.        dias_conv;
  12. }   tFecha;
  13.  
  14. int main(){
  15.  tFecha fecha1, fecha2;
  16.  printf("Ingrese dia - Primera fecha: \n\n");
  17.  scanf("%d",&fecha1.dia);
  18.  printf("\nIngrese mes - Primera fecha: \n\n");
  19.  scanf("%d",&fecha1.mes);
  20.  printf("\nIngrese año - Primera fecha: \n\n");
  21.  scanf("%d",&fecha1.ano);
  22.  printf("\nIngrese dia - Segunda fecha: \n\n");
  23.  scanf("%d",&fecha2.dia);
  24.  printf("\nIngrese mes - Segunda fecha: \n\n");
  25.  scanf("%d",&fecha2.mes);
  26.  printf("\nIngrese año - Segunda fecha: \n\n");
  27.  scanf("%d",&fecha2.ano);
  28.  
  29.  fecha1.mes -= 1;
  30.  fecha1.dias_conv = fecha1.ano*365.24 + 30*fecha1.mes + ajuste[fecha1.mes] + fecha1.dia;
  31.  fecha1.mes += 1;
  32.  
  33.  fecha2.mes -= 1;
  34.  fecha2.dias_conv = fecha2.ano*365.24 + 30*fecha2.mes + ajuste[fecha2.mes] + fecha2.dia;
  35.  fecha2.mes += 1;
  36.  
  37.  printf("\ndias entre fechas: %d", fecha2.dias_conv -fecha1.dias_conv );
  38.  return 0;
  39. }
  40.  

da la fecha con erro de 1 dia pero me da pereza depurar
En línea

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.
MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Programas para calcular fechas
« Respuesta #9 en: 24 Mayo 2017, 22:49 pm »

Ala pues. Aquí va el de la fecha del día siguiente:
Código
  1. void obtener_siguiente_fecha(tFecha *fecha) {
  2.    switch(fecha->mes) {
  3.        case 1:
  4.        case 3:
  5.        case 5:
  6.        case 7:
  7.        case 8:
  8.        case 10:
  9.        case 12:
  10.            if(fecha->dia == 31)
  11.                fecha->dia = 0;
  12.            break;
  13.  
  14.        case 4:
  15.        case 6:
  16.        case 9:
  17.        case 11:
  18.            if(fecha->dia == 30)
  19.                fecha->dia = 0;
  20.            break;
  21.  
  22.        case 2:
  23.            if(fecha->dia == 28 + (!(fecha->anyo%4) && fecha->anyo%100) || !(fecha->anyo%400))
  24.                fecha->dia = 0;
  25.            break;
  26.    }
  27.    if(fecha->dia == 0)
  28.        ++fecha->mes;
  29.    if(fecha->mes == 13) {
  30.        fecha->mes = 1;
  31.        ++fecha->anyo;
  32.    }
  33.  
  34.    ++fecha->dia;
  35. }

Evitando que se repita código ;D
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Calcular % con fechas
Programación Visual Basic
Mr.Chispa 2 1,584 Último mensaje 6 Septiembre 2006, 09:05 am
por Mr.Chispa
Calcular Diferencia de Fechas
Programación C/C++
barbara87 4 11,146 Último mensaje 16 Junio 2012, 17:17 pm
por david_BS
Calcular días entre dos fechas...
Ejercicios
*-.Sub-Vorbio.-* 0 4,838 Último mensaje 13 Noviembre 2008, 00:51 am
por *-.Sub-Vorbio.-*
Calcular numero de días entre dos fechas!
Java
*-.Sub-Vorbio.-* 9 39,549 Último mensaje 26 Marzo 2009, 23:34 pm
por Choclito
[Resuelto] ¿Existe librería para calcular el tiempo pasado entre dos fechas?
PHP
Leguim 1 2,311 Último mensaje 7 Febrero 2020, 16:19 pm
por EdePC
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines