Calcular la diferencia de meses en Python

PythonPythonBeginner
Practicar Ahora

This tutorial is from open-source community. Access the source code

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

Trabajar con fechas y horas es una tarea común en la programación. Python proporciona el potente módulo datetime para manejar operaciones de fecha y hora de manera eficiente. En este laboratorio (lab), aprenderás cómo calcular la diferencia entre dos fechas en términos de meses, lo cual es útil para cálculos financieros, cronogramas de proyectos y análisis de datos.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/FileHandlingGroup(["File Handling"]) python(("Python")) -.-> python/PythonStandardLibraryGroup(["Python Standard Library"]) python(("Python")) -.-> python/BasicConceptsGroup(["Basic Concepts"]) python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python(("Python")) -.-> python/ModulesandPackagesGroup(["Modules and Packages"]) python/BasicConceptsGroup -.-> python/type_conversion("Type Conversion") python/FunctionsGroup -.-> python/function_definition("Function Definition") python/FunctionsGroup -.-> python/arguments_return("Arguments and Return Values") python/ModulesandPackagesGroup -.-> python/standard_libraries("Common Standard Libraries") python/FileHandlingGroup -.-> python/file_opening_closing("Opening and Closing Files") python/PythonStandardLibraryGroup -.-> python/date_time("Date and Time") subgraph Lab Skills python/type_conversion -.-> lab-13696{{"Calcular la diferencia de meses en Python"}} python/function_definition -.-> lab-13696{{"Calcular la diferencia de meses en Python"}} python/arguments_return -.-> lab-13696{{"Calcular la diferencia de meses en Python"}} python/standard_libraries -.-> lab-13696{{"Calcular la diferencia de meses en Python"}} python/file_opening_closing -.-> lab-13696{{"Calcular la diferencia de meses en Python"}} python/date_time -.-> lab-13696{{"Calcular la diferencia de meses en Python"}} end

Comprender los objetos de fecha en Python

Antes de calcular la diferencia en meses entre fechas, necesitamos entender cómo trabajar con objetos de fecha en Python. En este paso, aprenderemos sobre el módulo datetime y crearemos algunos objetos de fecha.

Primero, creemos un nuevo archivo de Python en el directorio del proyecto. Abrir el WebIDE y hacer clic en el icono "Nuevo archivo" en el panel del explorador en el lado izquierdo. Nombrar el archivo month_difference.py y guardarlo en el directorio /home/labex/project.

Ahora, agreguemos el siguiente código para importar los módulos necesarios:

from datetime import date
from math import ceil

## Create example date objects
date1 = date(2023, 1, 15)  ## January 15, 2023
date2 = date(2023, 3, 20)  ## March 20, 2023

## Print the dates to see their format
print(f"Date 1: {date1}")
print(f"Date 2: {date2}")

## Calculate the difference in days
day_difference = (date2 - date1).days
print(f"Difference in days: {day_difference}")

Guardar el archivo y ejecutarlo utilizando la terminal:

python3 ~/project/month_difference.py

Deberías ver una salida similar a esta:

Date 1: 2023-01-15
Date 2: 2023-03-20
Difference in days: 64

La clase date del módulo datetime nos permite crear objetos de fecha especificando el año, el mes y el día. Cuando restamos una fecha de otra, Python devuelve un objeto timedelta. Podemos acceder al número de días en este objeto utilizando el atributo .days.

En este ejemplo, hay 64 días entre el 15 de enero de 2023 y el 20 de marzo de 2023.

Crear la función de diferencia en meses

Ahora que entendemos cómo trabajar con objetos de fecha y calcular la diferencia en días, creemos una función para calcular la diferencia en meses.

En muchas aplicaciones, un mes se aproxima a 30 días. Si bien esto no siempre es preciso (los meses pueden tener de 28 a 31 días), es una simplificación común que funciona bien para muchos cálculos comerciales.

Abre tu archivo month_difference.py y agrega esta función debajo de tu código existente:

def months_diff(start, end):
    """
    Calculate the difference in months between two dates.

    Args:
        start (date): The start date
        end (date): The end date

    Returns:
        int: The number of months between the dates (rounded up)
    """
    ## Calculate the difference in days
    days_difference = (end - start).days

    ## Convert days to months (assuming 30 days per month) and round up
    months = ceil(days_difference / 30)

    return months

Entendamos qué hace esta función:

  1. Toma dos parámetros: start y end, que son objetos de fecha.
  2. Calcula la diferencia en días entre estas fechas.
  3. Divide por 30 para convertir los días en meses.
  4. Utiliza ceil() para redondear hacia arriba al entero más cercano.
  5. Devuelve el resultado como un entero.

La función ceil() se utiliza porque en muchos escenarios comerciales, incluso un mes parcial se cuenta como un mes completo con fines de facturación.

Para probar nuestra función, agrega el siguiente código al final de tu archivo:

## Test the months_diff function with our example dates
print(f"Months between {date1} and {date2}: {months_diff(date1, date2)}")

## Test with some other date pairs
print(f"Months between 2020-10-28 and 2020-11-25: {months_diff(date(2020, 10, 28), date(2020, 11, 25))}")
print(f"Months between 2020-12-15 and 2021-01-10: {months_diff(date(2020, 12, 15), date(2021, 01, 10))}")

Guarda tu archivo y ejecútalo nuevamente:

python3 ~/project/month_difference.py

Deberías ver una salida como esta:

Date 1: 2023-01-15
Date 2: 2023-03-20
Difference in days: 64
Months between 2023-01-15 and 2023-03-20: 3
Months between 2020-10-28 and 2020-11-25: 1
Months between 2020-12-15 and 2021-01-10: 1

Observa que:

  • Los 64 días entre el 15 de enero de 2023 y el 20 de marzo de 2023 se calculan como 3 meses (64/30 = 2.13, redondeado hacia arriba a 3).
  • La diferencia entre el 28 de octubre y el 25 de noviembre se calcula como 1 mes.
  • La diferencia entre el 15 de diciembre y el 10 de enero (a través de un límite de año) también se calcula como 1 mes.

Pruebas con diversos escenarios de fechas

Para entender mejor cómo funciona nuestra función months_diff con diferentes escenarios de fechas, creemos un archivo de prueba separado. Este enfoque es común en el desarrollo de software para verificar que nuestro código funcione como se espera.

Crea un nuevo archivo llamado month_diff_test.py en el directorio /home/labex/project:

from datetime import date
from month_difference import months_diff

## Test scenario 1: Dates in the same month
date1 = date(2023, 5, 5)
date2 = date(2023, 5, 25)
print(f"Same month: {months_diff(date1, date2)} month(s)")

## Test scenario 2: Consecutive months
date3 = date(2023, 6, 28)
date4 = date(2023, 7, 15)
print(f"Consecutive months: {months_diff(date3, date4)} month(s)")

## Test scenario 3: Dates crossing year boundary
date5 = date(2023, 12, 20)
date6 = date(2024, 1, 10)
print(f"Across years: {months_diff(date5, date6)} month(s)")

## Test scenario 4: Several months apart
date7 = date(2023, 3, 10)
date8 = date(2023, 9, 20)
print(f"Several months: {months_diff(date7, date8)} month(s)")

## Test scenario 5: Dates in reverse order (negative result)
print(f"Reverse order: {months_diff(date8, date7)} month(s)")

## Test scenario 6: Exact multiples of 30 days
date9 = date(2023, 1, 1)
date10 = date(2023, 1, 31)  ## 30 days
date11 = date(2023, 3, 2)   ## 60 days
print(f"30 days exactly: {months_diff(date9, date10)} month(s)")
print(f"60 days exactly: {months_diff(date9, date11)} month(s)")

Guarda este archivo y ejecútalo:

python3 ~/project/month_diff_test.py

Deberías ver una salida similar a:

Same month: 1 month(s)
Consecutive months: 1 month(s)
Across years: 1 month(s)
Several months: 7 month(s)
Reverse order: -7 month(s)
30 days exactly: 1 month(s)
60 days exactly: 2 month(s)

Analicemos estos resultados:

  1. Mismo mes: Incluso dentro del mismo mes, nuestra función devuelve 1 mes. Esto se debe a que incluso un mes parcial se cuenta como un mes completo.

  2. Meses consecutivos: Para fechas en meses consecutivos, la función devuelve 1 mes.

  3. A través de años: Para fechas que cruzan el límite del año, la función sigue calculando correctamente.

  4. Varios meses: Para fechas que están separadas por varios meses, la función calcula el número adecuado de meses.

  5. Orden inverso: Cuando la fecha final es anterior a la fecha inicial, obtenemos un resultado negativo, lo cual tiene sentido para escenarios como el cálculo del tiempo restante.

  6. Múltiplos exactos: Para exactamente 30 días, obtenemos 1 mes. Para 60 días, obtenemos 2 meses. Esto confirma que nuestra función funciona como se espera con múltiplos exactos de nuestra definición de mes.

Nuestra función months_diff maneja todos estos casos de prueba de acuerdo con nuestra definición de un mes como 30 días.

Crear una aplicación práctica: Calculadora de suscripciones

Ahora que tenemos una función confiable para calcular la diferencia en meses, apliquémosla a un escenario del mundo real. Crearemos una calculadora de suscripciones que determine el costo de una suscripción a un servicio entre dos fechas.

Crea un nuevo archivo llamado subscription_calculator.py en el directorio /home/labex/project:

from datetime import date, timedelta
from month_difference import months_diff

def calculate_subscription_cost(start_date, end_date, monthly_fee):
    """
    Calculate the total cost of a subscription between two dates.

    Args:
        start_date (date): Subscription start date
        end_date (date): Subscription end date
        monthly_fee (float): Cost per month

    Returns:
        float: Total subscription cost
    """
    ## Calculate number of months
    months = months_diff(start_date, end_date)

    ## Calculate total cost
    total_cost = months * monthly_fee

    return total_cost

## Example: Calculate subscription cost for a streaming service
start = date(2023, 1, 15)  ## Subscription starts January 15, 2023
end = date(2023, 8, 20)    ## Ends August 20, 2023
monthly_cost = 9.99        ## $9.99 per month

total = calculate_subscription_cost(start, end, monthly_cost)
print(f"Subscription period: {start} to {end}")
print(f"Monthly fee: ${monthly_cost:.2f}")
print(f"Total cost: ${total:.2f}")

## Compare with an annual plan
annual_cost = 99.99  ## $99.99 per year
print(f"\nAnnual plan cost: ${annual_cost:.2f}")
print(f"Monthly plan for same period: ${total:.2f}")

if total > annual_cost:
    print(f"Savings with annual plan: ${total - annual_cost:.2f}")
else:
    print(f"Additional cost for annual plan: ${annual_cost - total:.2f}")

## Calculate cost for a trial period
today = date.today()
trial_end = today + timedelta(days=7)  ## 7-day trial
trial_cost = calculate_subscription_cost(today, trial_end, monthly_cost)
print(f"\nOne-week trial period: {today} to {trial_end}")
print(f"Trial period cost: ${trial_cost:.2f}")

Guarda el archivo y ejecútalo:

python3 ~/project/subscription_calculator.py

Deberías ver una salida similar a esta (las fechas de la prueba mostrarán tu fecha actual):

Subscription period: 2023-01-15 to 2023-08-20
Monthly fee: $9.99
Total cost: $79.92

Annual plan cost: $99.99
Monthly plan for same period: $79.92
Additional cost for annual plan: $20.07

One-week trial period: 2023-06-01 to 2023-06-08
Trial period cost: $9.99

Esta aplicación demuestra cómo se puede utilizar nuestra función months_diff en un escenario práctico:

  1. Calculamos el costo total de una suscripción en función del número de meses entre dos fechas.
  2. Comparamos este costo con un plan anual para ayudar a un usuario a decidir qué plan es más económico.
  3. Calculamos el costo de un período de prueba corto.

Observa cómo incluso la prueba de 7 días se cobra como un mes completo en nuestro modelo. Esto se debe a que nuestra función redondea cualquier mes parcial a un mes completo, lo cual es común en la facturación de suscripciones.

Este tipo de cálculo se utiliza con frecuencia en:

  • Servicios de suscripción (streaming, software, membresías)
  • Cálculos de préstamos y hipotecas
  • Contratos de alquiler
  • Facturación de proyectos

Resumen

En este laboratorio, aprendiste cómo calcular la diferencia en meses entre dos fechas en Python. Esto es lo que lograste:

  1. Aprendiste a trabajar con objetos de fecha del módulo datetime.
  2. Creaste una función months_diff que calcula la diferencia en meses utilizando una aproximación de mes de 30 días.
  3. Probaste la función con diversos escenarios de fechas para asegurarte de que funcione correctamente.
  4. Aplicaste la función a un escenario del mundo real creando una calculadora de suscripciones.

Estas habilidades son valiosas para muchas aplicaciones, incluyendo:

  • Cálculos financieros (préstamos, inversiones, facturación)
  • Planificación y gestión de proyectos
  • Servicios de suscripción
  • Análisis de datos basados en fechas

Para mejorar aún más tus habilidades al trabajar con fechas en Python, podrías explorar:

  • Trabajar con componentes de tiempo utilizando datetime.datetime.
  • Manejar diferentes zonas horarias utilizando la librería pytz.
  • Utilizar la librería dateutil para operaciones de fecha más avanzadas.
  • Implementar diferentes enfoques para calcular la diferencia en meses (por ejemplo, meses calendario en lugar de períodos de 30 días).

Los cálculos de fecha y hora son esenciales en muchas tareas de programación, y las técnicas que aprendiste en este laboratorio proporcionan una base sólida para manejar estos cálculos en tus proyectos de Python.