pendulum tips

Comment écrire le nom des mois en français ?

current_date = pendulum.datetime(2023, 1, 1, tz='Europe/Paris')
for _ in range(1,13):
    str_month_fr = current_date.format("MMMM", locale="fr")
    print(f"{str_month_fr}")
    current_date = current_date.add(months=1)
janvier
février
mars
avril
mai
juin
juillet
août
septembre
octobre
novembre
décembre

from_date = pendulum.datetime(2023, 1, 1, tz=’Europe/Paris’)

from_date = pendulum.datetime(2023, 1, 1, tz='Europe/Paris')

to_date = from_date.end_of(“year”)

to_date = from_date.end_of("year")

pendulum tips ( set method )

set (hour=0, minute=0, second=0)

from_date = from_date.set(hour=0, minute=0, second=0)
to_date = to_date.set(hour=23, minute=59, second=59)

Modifiers (end_of, start_of)

start_of (“week”)

dt.start_of('week')

In [11]: dt = pendulum.now()
In [12]: start_week = dt.start_of("week")
In [13]: start_week
Out[13]: DateTime(2021, 1, 4, 0, 0, 0, tzinfo=Timezone('Europe/Paris'))
In [14]: start_week.day_of_week
Out[14]: 1
In [15]: week_prec = start_week.add(days=-7)
In [16]: week_prec
Out[16]: DateTime(2020, 12, 28, 0, 0, 0, tzinfo=Timezone('Europe/Paris'))
In [17]: week_prec.day_of_week
Out[17]: 1

end_of (“month”)

end_date = start_date.end_of("month")

start_of (“month”)

month_date = month_date.add(months=-1).start_of("month")

start_of (“day”)

Example 1

from django.conf import settings

...

today = pendulum.now(tz=settings.TIME_ZONE).start_of("day")

Example2 with Q Django selection ++++++++++=========================

 1 import pendulum
 2
 3 # https://github.com/andialbrecht/sqlparse
 4 import sqlparse
 5
 6 from django.conf import settings
 7 from django.db.models import Q
 8 from django.db import models, connection, reset_queries
 9 from tools.utils_time import id3_format_timedelta, log_sql_queries
10
11
12
13 @staticmethod
14 def get_weekly_hours_for_all_projects(employe: Employe, liste_jours: list[pendulum.datetime]) -> (str, QuerySet):
15     """Retourne la somme des heures pour tous les projets d'un employé
16        et une liste de jours donnée
17
18        Retourne:
19
20        - une chaine de caractères de la forme: (Ex:'9h30')
21        - le queryset correspondant
22     """
23     reset_queries()
24     select_datetime_begin = liste_jours[0].start_of("day")
25     select_datetime_end = liste_jours[-1].start_of("day")
26     liste_fiches = FicheTemps.objects.filter(
27         Q(created__gte=select_datetime_begin) & Q(created__lte=select_datetime_end),
28         employe__login=employe.login,
29     ).exclude(projet_id__in=PROJETS_CONGES_ID)
30     sql_query = sqlparse.format(str(liste_fiches.query), reindent=True)
31     # logger.info(f"\nSQL query:\n{sql_query}\n")
32     # calcul du total des temps
33     q_total_temps_impute = liste_fiches.aggregate(Sum("temps_impute"))
34     weekly_hours_for_all_projects = id3_format_timedelta(
35         q_total_temps_impute["temps_impute__sum"]
36     )
37     # logger.info(f"{weekly_hours_for_all_projects=}")
38     log_sql_queries(connection)
39
40     return weekly_hours_for_all_projects, liste_fiches
SQL query:
SELECT SUM("fiche_temps"."temps_impute") AS "temps_impute__sum"
FROM "fiche_temps"
INNER JOIN "employe" ON ("fiche_temps"."id_employe" = "employe"."id")
WHERE ("fiche_temps"."created" >= '2020-04-20T00:00:00+02:00'::timestamptz
       AND "fiche_temps"."created" <= '2020-04-28T00:00:00+02:00'::timestamptz
       AND "employe"."login" = 'pvergain'
       AND NOT ("fiche_temps"."id_projet" IN (6,
                                              9,
                                              14,
                                              13,
                                              12,
                                              10,
                                              15,
                                              8,
                                              5,
                                              4,
                                              3,
                                              2,
                                              1,
                                              11,
                                              7)))
time='0.037'

convert a datetime.datetime to pendulum.datetime

import pendulum
from django.conf import settings

from django.utils.dateparse import (
    parse_duration,
    parse_datetime,
)


created = parse_datetime(created_str)
created = pendulum.instance(created,tz=settings.TIME_ZONE)

Addition and Subtraction

Previous week

In [11]: dt = pendulum.now()
In [12]: start_week = dt.start_of("week")
In [13]: start_week
Out[13]: DateTime(2021, 1, 4, 0, 0, 0, tzinfo=Timezone('Europe/Paris'))
In [14]: start_week.day_of_week
Out[14]: 1
In [15]: week_prec = start_week.add(days=-7)
In [16]: week_prec
Out[16]: DateTime(2020, 12, 28, 0, 0, 0, tzinfo=Timezone('Europe/Paris'))

Previous month

In [6]: dt = pendulum.now()
In [7]: dt
Out[7]: DateTime(2021, 1, 8, 15, 15, 37, 792012, tzinfo=Timezone('Europe/Paris'))
In [9]: last_month = a.subtract(months=1)
In [10]: last_month
Out[10]: DateTime(2020, 12, 8, 15, 15, 37, 792012, tzinfo=Timezone('Europe/Paris'))

How to get monday and sunday drom the current day ?

import pendulum
today = pendulum.now(tz="Europe/Paris")
from_date = today.start_of("week")
to_date = today.end_of("week")

and for the next monday and sunday:

from_date_next_week = from_date.add(weeks=1)
to_date_next_week = to_date.add(weeks=1)
In [10]: print(f"{today=}\n{from_date=}\n{to_date=}\n{from_date_next_week=}\n{to_date_next_week=}")
today=DateTime(2023, 3, 31, 13, 26, 57, 405336, tzinfo=Timezone('Europe/Paris'))
from_date=DateTime(2023, 3, 27, 0, 0, 0, tzinfo=Timezone('Europe/Paris'))
to_date=DateTime(2023, 4, 2, 23, 59, 59, 999999, tzinfo=Timezone('Europe/Paris'))
from_date_next_week=DateTime(2023, 4, 3, 0, 0, 0, tzinfo=Timezone('Europe/Paris'))
to_date_next_week=DateTime(2023, 4, 9, 23, 59, 59, 999999, tzinfo=Timezone('Europe/Paris'))