Jarvis/jarvis/tools/date_week_transition.py

216 lines
7.0 KiB
Python

""" Module de manipulation de dates/semaines.
Ce module contient un ensemble de fonction permettant de passer de date en numéro de semaine et
vice-versa (de numéro de semaine en date).
"""
import pendulum
def from_week_number_to_date(season, week_number):
"""Renvoie la date du début de semaine (lundi) et la date de fin de semaine (dimanche) à
partir d'une saison et d'un numéro de semaine.
Args:
season str saison (ex : "2022-2023")
week_number int numéro de semaine
Returns :
start_date Date du lundi de la semaine
end_date Date du dimanche de la semaine
Examples:
>>> from jarvis.tools.date_week_transition import from_week_number_to_date
>>> from_week_number_to_date("2022-2023", 6)
>>> (Date(2022, 10, 3), Date(2022, 10, 9))
>>> from_week_number_to_date("2022-2023", 22)
>>> (Date(2023, 1, 30), Date(2023, 2, 5))
>>> from_week_number_to_date("2022-2023", 44)
>>> (Date(2023, 7, 3), Date(2023, 7, 9))
"""
if week_number <= 0:
return None, None
dash = season.find("-")
first_year = str(season[:dash])
season_begin = pendulum.parse(str(first_year) + "09-01")
season_first_week = season_begin.week_of_year
rest_of_week = 52 - season_first_week
week_string = "-W"
if week_number <= rest_of_week:
week_number += season_first_week - 1
year = first_year
else:
week_number -= rest_of_week
year = str(season[dash + 1 :])
if week_number < 10:
week_string += "0"
start_date = pendulum.parse(year + week_string + str(week_number))
end_date = start_date.add(days=6)
return start_date.date(), end_date.date()
def from_month_number_to_date(season, month_number):
"""Renvoie la date du début du mois et la date de fin du mois à
partir d'une saison et d'un numéro de mois.
Args:
season str saison (ex : "2022-2023")
month_number int numéro du mois (ex : 9)
Returns :
start_date Date du 1 du mois
end_date Date du dernier jour du mois
Examples:
>>> from jarvis.tools.date_week_transition import from_month_number_to_date
>>> from_month_number_to_date("2022-2023", 9)
>>> (Date(2022, 9, 1), Date(2022, 9, 30))
>>> from_month_number_to_date("2022-2023", 2)
>>> (Date(2023, 2, 1), Date(2023, 2, 28))
>>> from_month_number_to_date("2023-2024", 2)
>>> (Date(2023, 2, 1), Date(2023, 2, 29))
"""
if month_number <= 0:
return None, None
dash = season.find("-")
if 8 >= month_number >= 1: # and month_number <= 8:
year = int(season[dash + 1 :])
else:
year = int(season[:dash])
start_date = pendulum.datetime(year, month_number, 1)
end_date = start_date.end_of("month")
return start_date.date(), end_date.date()
def from_season_to_date(season):
"""Renvoie la date du début du mois et la date de fin du mois à
partir d'une saison et d'un numéro de mois.
Args:
season str saison (ex : "2022-2023")
Returns :
start_date Date du premier jour de la saison (ex : 1-9-2022)
end_date Date du dernier jour de la saison (ex : 31-8-2023)
Examples:
>>> from jarvis.tools.date_week_transition import from_season_to_date
>>> from_season_to_date("2022-2023")
>>> (Date(2022, 9, 1), Date(2023, 8, 31))
>>> from_season_to_date("2023-2024")
>>> (Date(2023, 9, 1), Date(2022, 8, 31))
>>> from_season_to_date("2022-2024")
>>> (None, None)
"""
dash = season.find("-")
first_year = int(season[:dash])
second_year = int(season[dash + 1 :])
if second_year != first_year + 1:
return None, None
start_date = pendulum.datetime(first_year, 9, 1)
end_date = pendulum.datetime(second_year, 8, 31)
return start_date.date(), end_date.date()
def from_date_to_week_number(the_date=None):
"""Renvoie le numéro de la semaine depuis le début de la saison.
Une saison commence le 1er septembre.
La semaine contenant le 1er septembre est la semaine 1, même si le 1er septembre est un
diamnche.
Args:
date date date à convertir
Returns :
int nombre de semaine entre la date en paramètre et le début de la saison.
Examples:
>>> from jarvis.tools.date_week_transition import from_date_to_week_number
>>> import pendulum
>>> from_date_to_week_number(pendulum.date(2022, 9, 1))
>>> 1
>>> from_date_to_week_number(pendulum.date(2023, 2, 5))
>>> 22
>>> from_date_to_week_number(pendulum.date(2023, 7, 5))
>>> 44
"""
if the_date is None:
the_date = pendulum.today().date()
else:
the_date = pendulum.parse(the_date.strftime("%Y%m%d"))
number_of_year_week = the_date.week_of_year
if the_date.month >= 9: # nouvelle saison
season = str(the_date.year) + "-" + str(the_date.year + 1)
begin_season = pendulum.date(the_date.year, 9, 1)
season_first_week = begin_season.week_of_year
number_of_season_week = number_of_year_week + 1 - season_first_week
else: # "ancienne" saison
season = str(the_date.year - 1) + "-" + str(the_date.year)
begin_season = pendulum.date(the_date.year - 1, 9, 1)
season_first_week = begin_season.week_of_year
number_of_season_week = number_of_year_week + (52 - season_first_week)
return season, number_of_season_week
def get_number_of_weeks_between(first_date, second_date):
"""
Renvoie le nombre de semaines entre deux dates.
Par extension, cela permet de connaitre le nombre d'occurence d'un
évènement (entraînement, par exemple) hebdromadaire entre deux dates
et ainsi pouvoir plannifier.
Args:
first_date date date du premier évènement
second_date date date du second évènement
Returns :
int nombre de semaine entre les deux dates
Examples:
>>> from jarvis.tools.date_week_transition import get_number_of_weeks_between
>>> import pendulum
>>> get_number_of_weeks_between(pendulum.date(2022, 9, 1), pendulum.date(2022, 9, 4))
>>> 0
>>> get_number_of_weeks_between(pendulum.date(2022, 9, 1), pendulum.date(2023, 2, 5))
>>> 22
>>> get_number_of_weeks_between(pendulum.date(2022, 9, 1), pendulum.date(2023, 7, 5))
>>> 44
>>> get_number_of_weeks_between(pendulum.date(2023, 2, 5), pendulum.date(2023, 7, 5))
>>> 22
"""
first = pendulum.parse(first_date.strftime("%Y%m%d"))
second = pendulum.parse(second_date.strftime("%Y%m%d"))
if first_date.year == second.year:
return second.week_of_year - first.week_of_year
if second_date.year > first_date.year:
return (52 - first.week_of_year) + second.week_of_year
return (52 - second.week_of_year) + first.week_of_year