""" 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