131 lines
4.5 KiB
Python
131 lines
4.5 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 ultron.tools.date_week_transition import from_week_number_to_date
|
||
|
>>> import pendulum
|
||
|
>>> from_week_number_to_date("2022-2023", 6)
|
||
|
>>> (DateTime(2022, 10, 3, 0, 0, 0, tzinfo=Timezone('UTC')), DateTime(2022, 10, 9, 0, 0, 0, tzinfo=Timezone('UTC')))
|
||
|
|
||
|
>>> from_week_number_to_date("2022-2023", 22)
|
||
|
>>> (DateTime(2023, 1, 30, 0, 0, 0, tzinfo=Timezone('UTC')), DateTime(2023, 2, 5, 0, 0, 0, tzinfo=Timezone('UTC')))
|
||
|
|
||
|
>>> from_week_number_to_date("2022-2023", 44)
|
||
|
>>> (DateTime(2023, 7, 3, 0, 0, 0, tzinfo=Timezone('UTC')), DateTime(2023, 7, 9, 0, 0, 0, tzinfo=Timezone('UTC')))
|
||
|
"""
|
||
|
dash = season.find("-")
|
||
|
first_year = 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 - rest_of_week < 10:
|
||
|
week_string += "0"
|
||
|
|
||
|
start_date = pendulum.parse(year + week_string + str(week_number))
|
||
|
end_date = start_date.add(days=6)
|
||
|
return start_date, end_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 ultron.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()
|
||
|
|
||
|
number_of_year_week = the_date.week_of_year
|
||
|
if the_date.month >= 9: # nouvelle saison
|
||
|
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
|
||
|
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 number_of_season_week
|
||
|
|
||
|
|
||
|
def get_number_of_weeks_between(start, stop):
|
||
|
"""
|
||
|
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.
|
||
|
|
||
|
:param start: date de début de la période
|
||
|
:type start: datetime.date
|
||
|
:param stop: date de fin de la période
|
||
|
:type stop: datetime.date
|
||
|
:return: Le nombre de semaines entre les deux dates.
|
||
|
|
||
|
Remarks:
|
||
|
Proposition d'utiliser isocalendar() sur une date.
|
||
|
L'indice 1 de la valeur de retour donne la semaine correspondant.
|
||
|
|
||
|
Eg.
|
||
|
>>> from datetime import date
|
||
|
>>> d = date(2020, 9, 27)
|
||
|
>>> d.isocalendar()
|
||
|
(2020, 39, 7)
|
||
|
|
||
|
-> Est-ce qu'il ne suffirait pas de faire la différence ?
|
||
|
"""
|
||
|
|
||
|
delta = stop - start
|
||
|
number_of_days = abs(delta.days)
|
||
|
number_of_week = int((number_of_days + 1) / 7)
|
||
|
|
||
|
if ((number_of_days + 1) % 7) > 0:
|
||
|
number_of_week += 1
|
||
|
|
||
|
if delta.days < 0:
|
||
|
number_of_week *= -1
|
||
|
|
||
|
return number_of_week
|