Fechas como caso de estudio de structs

 Fechas como caso de estudio de structs


Estas funciones y programas de prueba se basan en el ejercicio 1 del práctico 6 para luego crear una pequeña librería de trabajo con fechas.


#include <stdio.h>

#include <stdlib.h> // para abs()


typedef struct {

    int dia;

    int mes;

    int anio;

} Fecha;


int esBisiesto(int anio) {

    return (anio % 4 == 0 && anio % 100 != 0) || (anio % 400 == 0);

}


int validarFecha(Fecha f) {

    if (f.anio < 1900) return 0;

    if (f.mes < 1 || f.mes > 12) return 0;


    int diasMes;

    switch (f.mes) {

        case 1: case 3: case 5: case 7: case 8: case 10: case 12:

            diasMes = 31; break;

        case 4: case 6: case 9: case 11:

            diasMes = 30; break;

        case 2:

            diasMes = esBisiesto(f.anio) ? 29 : 28;

            break;

        default:

            return 0;

    }

    return (f.dia >= 1 && f.dia <= diasMes);

}


Fecha leerFecha() {

    Fecha f;

    do {

        printf("Ingrese día: ");

        scanf("%d", &f.dia);

        printf("Ingrese mes: ");

        scanf("%d", &f.mes);

        printf("Ingrese año: ");

        scanf("%d", &f.anio);


        if (!validarFecha(f)) {

            printf("⚠️ Fecha inválida, intente nuevamente.\n");

        }

    } while (!validarFecha(f));

    return f;

}


void imprimirFecha(Fecha f) {

    printf("%02d/%02d/%04d", f.dia, f.mes, f.anio);

}


long dias_desde(Fecha f) {

    long total = 0;

    for (int anio = 1900; anio < f.anio; anio++) {

        total += esBisiesto(anio) ? 366 : 365;

    }

    int diasMes[] = {31,28,31,30,31,30,31,31,30,31,30,31};

    for (int mes = 1; mes < f.mes; mes++) {

        if (mes == 2 && esBisiesto(f.anio))

            total += 29;

        else

            total += diasMes[mes - 1];

    }

    total += f.dia;

    return total;

}


// Diferencia absoluta en días entre dos fechas válidas

long diasEntre(Fecha f1, Fecha f2) {

    return labs(dias_desde(f1) - dias_desde(f2));

}


Fecha fechaPosterior(Fecha f) {

    Fecha nueva = f;

    nueva.dia++;

    if (!validarFecha(nueva)) {

        nueva.dia = 1;

        nueva.mes++;

        if (nueva.mes > 12) {

            nueva.mes = 1;

            nueva.anio++;

        }

    }

    return nueva;

}


Fecha fechaMasNDias(Fecha f, int n) {

    long totalDias = dias_desde(f) + n;

    Fecha nueva;

    nueva.anio = 1900;


    while (1) {

        int diasAnio = esBisiesto(nueva.anio) ? 366 : 365;

        if (totalDias > diasAnio) {

            totalDias -= diasAnio;

            nueva.anio++;

        } else break;

    }


    int diasMes[] = {31,28,31,30,31,30,31,31,30,31,30,31};

    nueva.mes = 1;

    while (1) {

        int diasEnMes = (nueva.mes == 2 && esBisiesto(nueva.anio)) ? 29 : diasMes[nueva.mes - 1];

        if (totalDias > diasEnMes) {

            totalDias -= diasEnMes;

            nueva.mes++;

        } else break;

    }


    nueva.dia = (int)totalDias;

    return nueva;

}


Fecha fechaMas7Dias(Fecha f) {

    return fechaMasNDias(f, 7);

}


int main() {

    Fecha fecha1, fecha2;


    printf("Ingrese la primera fecha:\n");

    fecha1 = leerFecha();


    printf("Ingrese la segunda fecha:\n");

    fecha2 = leerFecha();


    printf("Primera fecha: ");

    imprimirFecha(fecha1);

    printf(" -> Dias desde 1/1/1900: %ld\n", dias_desde(fecha1));


    printf("Segunda fecha: ");

    imprimirFecha(fecha2);

    printf(" -> Dias desde 1/1/1900: %ld\n", dias_desde(fecha2));


    printf("Diferencia en días entre ambas: %ld\n", diasEntre(fecha1, fecha2));


    Fecha siguiente = fechaPosterior(fecha1);

    printf("El día siguiente a la primera fecha es: ");

    imprimirFecha(siguiente);

    printf("\n");


    Fecha mas7 = fechaMas7Dias(fecha1);

    printf("La primera fecha + 7 días es: ");

    imprimirFecha(mas7);

    printf("\n");


    Fecha masN = fechaMasNDias(fecha1, 30);

    printf("La primera fecha + 30 días es: ");

    imprimirFecha(masN);

    printf("\n");


    return 0;

}


Comentarios

Entradas populares de este blog