Ultron/ultron/tools/date_week_transition.py

131 lines
4.5 KiB
Python
Raw Normal View History

2022-10-06 11:04:27 +02:00
""" 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