diff --git a/app/but/bulletin_but.py b/app/but/bulletin_but.py
index 8eec9ba6a87256374ea95e007b6f0029d749b4a3..ab4227b0d2a664415cde6122003c8d5d07856f8e 100644
--- a/app/but/bulletin_but.py
+++ b/app/but/bulletin_but.py
@@ -393,7 +393,7 @@ class BulletinBUT:
         else:
             etud_ues_ids = res.etud_ues_ids(etud.id)
 
-        nbabs, nbabsjust = formsemestre.get_abs_count(etud.id)
+        nbabsnj, nbabsjust, nbabs = formsemestre.get_abs_count(etud.id)
         etud_groups = sco_groups.get_etud_formsemestre_groups(
             etud, formsemestre, only_to_show=True
         )
@@ -408,7 +408,7 @@ class BulletinBUT:
         }
         if self.prefs["bul_show_abs"]:
             semestre_infos["absences"] = {
-                "injustifie": nbabs - nbabsjust,
+                "injustifie": nbabsnj,
                 "total": nbabs,
                 "metrique": {
                     "H.": "Heure(s)",
@@ -525,7 +525,7 @@ class BulletinBUT:
             d["demission"] = ""
 
         # --- Absences
-        d["nbabs"], d["nbabsjust"] = self.res.formsemestre.get_abs_count(etud.id)
+        _, d["nbabsjust"], d["nbabs"] = self.res.formsemestre.get_abs_count(etud.id)
 
         # --- Decision Jury
         infos, _ = sco_bulletins.etud_descr_situation_semestre(
@@ -540,9 +540,9 @@ class BulletinBUT:
 
         d.update(infos)
         # --- Rangs
-        d["rang_nt"] = (
-            f"{d['semestre']['rang']['value']} / {d['semestre']['rang']['total']}"
-        )
+        d[
+            "rang_nt"
+        ] = f"{d['semestre']['rang']['value']} / {d['semestre']['rang']['total']}"
         d["rang_txt"] = "Rang " + d["rang_nt"]
 
         d.update(sco_bulletins.make_context_dict(self.res.formsemestre, d["etud"]))
diff --git a/app/but/bulletin_but_xml_compat.py b/app/but/bulletin_but_xml_compat.py
index 07522f80cf64292dd36472926118574586ea049f..fb9af205681f9f88f3a89126f5135001b3ca1e6a 100644
--- a/app/but/bulletin_but_xml_compat.py
+++ b/app/but/bulletin_but_xml_compat.py
@@ -241,7 +241,7 @@ def bulletin_but_xml_compat(
 
     # --- Absences
     if sco_preferences.get_preference("bul_show_abs", formsemestre_id):
-        nbabs, nbabsjust = formsemestre.get_abs_count(etud.id)
+        _, nbabsjust, nbabs = formsemestre.get_abs_count(etud.id)
         doc.append(Element("absences", nbabs=str(nbabs), nbabsjust=str(nbabsjust)))
 
     # -------- LA SUITE EST COPIEE SANS MODIF DE sco_bulletins_xml.py ---------
diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py
index 09c1d3056dbe3d6fb1a08989783e32f4de14028e..5541d178074ac64600d64a71dc1fb02af2c2395f 100644
--- a/app/models/formsemestre.py
+++ b/app/models/formsemestre.py
@@ -875,7 +875,7 @@ class FormSemestre(db.Model):
 
     def get_abs_count(self, etudid):
         """Les comptes d'absences de cet étudiant dans ce semestre:
-        tuple (nb abs, nb abs justifiées)
+        tuple (nb abs non just, nb abs justifiées, nb abs total)
         Utilise un cache.
         """
         from app.scodoc import sco_assiduites
diff --git a/app/scodoc/html_sidebar.py b/app/scodoc/html_sidebar.py
index f1c8f8356890a2ab95737b2fd11ecd7ed91febb9..2d351e628f240c34f6e13c9c03731b9f6c1334aa 100755
--- a/app/scodoc/html_sidebar.py
+++ b/app/scodoc/html_sidebar.py
@@ -175,10 +175,9 @@ def sidebar(etudid: int = None):
         inscription = etud.inscription_courante()
         if inscription:
             formsemestre = inscription.formsemestre
-            nbabs, nbabsjust = sco_assiduites.formsemestre_get_assiduites_count(
+            nbabsnj, nbabsjust, _ = sco_assiduites.formsemestre_get_assiduites_count(
                 etudid, formsemestre
             )
-            nbabsnj = nbabs - nbabsjust
             H.append(
                 f"""<span title="absences du {
                     formsemestre.date_debut.strftime("%d/%m/%Y")
diff --git a/app/scodoc/sco_abs_notification.py b/app/scodoc/sco_abs_notification.py
index ba729e2784cce89c0f4ee7d163f83d790143504a..54a645e38c025a6d8a96b05798415fc92435b801 100644
--- a/app/scodoc/sco_abs_notification.py
+++ b/app/scodoc/sco_abs_notification.py
@@ -67,7 +67,7 @@ def abs_notify(etudid: int, date: str | datetime.datetime):
     if not formsemestre:
         return  # non inscrit a la date, pas de notification
 
-    nbabs, nbabsjust = sco_assiduites.get_assiduites_count_in_interval(
+    _, nbabsjust, nbabs = sco_assiduites.get_assiduites_count_in_interval(
         etudid,
         metrique=scu.translate_assiduites_metric(
             sco_preferences.get_preference(
diff --git a/app/scodoc/sco_assiduites.py b/app/scodoc/sco_assiduites.py
index 597accb988b8e9e2fa4e88493e11885870d88384..b9b650eaffa63a5696e307fb775eb50e99a5d084 100644
--- a/app/scodoc/sco_assiduites.py
+++ b/app/scodoc/sco_assiduites.py
@@ -671,7 +671,7 @@ def create_absence_billet(
 # Gestion du cache
 def get_assiduites_count(etudid: int, sem: dict) -> tuple[int, int]:
     """Les comptes d'absences de cet étudiant dans ce semestre:
-    tuple (nb abs non justifiées, nb abs justifiées)
+    tuple (nb abs non justifiées, nb abs justifiées, nb abs total)
     Utilise un cache.
     """
     metrique = sco_preferences.get_preference("assi_metrique", sem["formsemestre_id"])
@@ -687,17 +687,17 @@ def formsemestre_get_assiduites_count(
     etudid: int, formsemestre: FormSemestre, moduleimpl_id: int = None
 ) -> tuple[int, int]:
     """Les comptes d'absences de cet étudiant dans ce semestre:
-    tuple (nb abs non justifiées, nb abs justifiées)
+    tuple (nb abs non justifiées, nb abs justifiées, nb abs total)
     Utilise un cache.
     """
     metrique = sco_preferences.get_preference("assi_metrique", formsemestre.id)
     return get_assiduites_count_in_interval(
         etudid,
         date_debut=scu.localize_datetime(
-            datetime.combine(formsemestre.date_debut, time(8, 0))
+            datetime.combine(formsemestre.date_debut, time(0, 0))
         ),
         date_fin=scu.localize_datetime(
-            datetime.combine(formsemestre.date_fin, time(18, 0))
+            datetime.combine(formsemestre.date_fin, time(23, 0))
         ),
         metrique=scu.translate_assiduites_metric(metrique),
         moduleimpl_id=moduleimpl_id,
@@ -714,12 +714,12 @@ def get_assiduites_count_in_interval(
     moduleimpl_id: int = None,
 ):
     """Les comptes d'absences de cet étudiant entre ces deux dates, incluses:
-    tuple (nb abs, nb abs justifiées)
+    tuple (nb abs non justifiées, nb abs justifiées, nb abs total)
     On peut spécifier les dates comme datetime ou iso.
     Utilise un cache.
     """
-    date_debut_iso = date_debut_iso or date_debut.isoformat()
-    date_fin_iso = date_fin_iso or date_fin.isoformat()
+    date_debut_iso = date_debut_iso or date_debut.strftime("%Y-%m-%d")
+    date_fin_iso = date_fin_iso or date_fin.strftime("%Y-%m-%d")
     key = f"{etudid}_{date_debut_iso}_{date_fin_iso}_assiduites"
 
     r = sco_cache.AbsSemEtudCache.get(key)
@@ -744,9 +744,10 @@ def get_assiduites_count_in_interval(
             if not ans:
                 log("warning: get_assiduites_count failed to cache")
 
-    nb_abs: dict = r["absent"][metrique]
-    nb_abs_just: dict = r["absent_just"][metrique]
-    return (nb_abs, nb_abs_just)
+    nb_abs: int = r["absent"][metrique]
+    nb_abs_nj: int = r["absent_non_just"][metrique]
+    nb_abs_just: int = r["absent_just"][metrique]
+    return (nb_abs_nj, nb_abs_just, nb_abs)
 
 
 def invalidate_assiduites_count(etudid: int, sem: dict):
diff --git a/app/scodoc/sco_bulletins.py b/app/scodoc/sco_bulletins.py
index 1b70d385800e6ba1fdac570f2f3b809be1eb4f13..d1c32795da4368b0176ad459a3bf40fdb3db1587 100644
--- a/app/scodoc/sco_bulletins.py
+++ b/app/scodoc/sco_bulletins.py
@@ -196,7 +196,7 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"):
         pid = partition["partition_id"]
         partitions_etud_groups[pid] = sco_groups.get_etud_groups_in_partition(pid)
     # --- Absences
-    I["nbabs"], I["nbabsjust"] = sco_assiduites.get_assiduites_count(etudid, nt.sem)
+    _, I["nbabsjust"], I["nbabs"] = sco_assiduites.get_assiduites_count(etudid, nt.sem)
 
     # --- Decision Jury
     infos, dpv = etud_descr_situation_semestre(
@@ -471,7 +471,7 @@ def _ue_mod_bulletin(
         )  # peut etre 'NI'
         is_malus = mod["module"]["module_type"] == ModuleType.MALUS
         if bul_show_abs_modules:
-            nbabs, nbabsjust = sco_assiduites.get_assiduites_count(etudid, sem)
+            _, nbabsjust, nbabs = sco_assiduites.get_assiduites_count(etudid, sem)
             mod_abs = [nbabs, nbabsjust]
             mod["mod_abs_txt"] = scu.fmt_abs(mod_abs)
         else:
diff --git a/app/scodoc/sco_bulletins_json.py b/app/scodoc/sco_bulletins_json.py
index 0481e6f9c94d383ac4d4f5ca1cc29c917bbb5a53..a7848b39e172557ac08a5fba5e673348eee2ed4c 100644
--- a/app/scodoc/sco_bulletins_json.py
+++ b/app/scodoc/sco_bulletins_json.py
@@ -296,7 +296,7 @@ def formsemestre_bulletinetud_published_dict(
 
     # --- Absences
     if prefs["bul_show_abs"]:
-        nbabs, nbabsjust = sco_assiduites.get_assiduites_count(etudid, sem)
+        _, nbabsjust, nbabs = sco_assiduites.get_assiduites_count(etudid, sem)
         d["absences"] = dict(nbabs=nbabs, nbabsjust=nbabsjust)
 
     # --- Décision Jury
diff --git a/app/scodoc/sco_bulletins_xml.py b/app/scodoc/sco_bulletins_xml.py
index 25f2cfa64726aace0675317d2d6a7b3c5245ac54..77f95ac28ec9afd13a9d2a58a3970309a9a2b48f 100644
--- a/app/scodoc/sco_bulletins_xml.py
+++ b/app/scodoc/sco_bulletins_xml.py
@@ -260,7 +260,7 @@ def make_xml_formsemestre_bulletinetud(
                 numero=str(mod["numero"]),
                 titre=quote_xml_attr(mod["titre"]),
                 abbrev=quote_xml_attr(mod["abbrev"]),
-                code_apogee=quote_xml_attr(mod["code_apogee"])
+                code_apogee=quote_xml_attr(mod["code_apogee"]),
                 # ects=ects ects des modules maintenant inutilisés
             )
             x_ue.append(x_mod)
@@ -347,7 +347,7 @@ def make_xml_formsemestre_bulletinetud(
 
     # --- Absences
     if sco_preferences.get_preference("bul_show_abs", formsemestre_id):
-        nbabs, nbabsjust = sco_assiduites.get_assiduites_count(etudid, sem)
+        _, nbabsjust, nbabs = sco_assiduites.get_assiduites_count(etudid, sem)
         doc.append(Element("absences", nbabs=str(nbabs), nbabsjust=str(nbabsjust)))
     # --- Decision Jury
     if (
diff --git a/app/scodoc/sco_formsemestre_validation.py b/app/scodoc/sco_formsemestre_validation.py
index df4770fa3c4a7d540aeecfd4c14150ef67886dd9..27d99fffd9819da3a36b9f330356a456d0c73bf9 100644
--- a/app/scodoc/sco_formsemestre_validation.py
+++ b/app/scodoc/sco_formsemestre_validation.py
@@ -722,8 +722,8 @@ def formsemestre_recap_parcours_table(
             f"""<td class="rcp_moy">{scu.fmt_note(nt.get_etud_moy_gen(etudid))}</td>"""
         )
         # Absences (nb d'abs non just. dans ce semestre)
-        nbabs, nbabsjust = sco_assiduites.get_assiduites_count(etudid, sem)
-        H.append(f"""<td class="rcp_abs">{nbabs - nbabsjust}</td>""")
+        nbabsnj = sco_assiduites.get_assiduites_count(etudid, sem)[0]
+        H.append(f"""<td class="rcp_abs">{nbabsnj}</td>""")
 
         # UEs
         for ue in ues:
diff --git a/app/scodoc/sco_poursuite_dut.py b/app/scodoc/sco_poursuite_dut.py
index c271628a2bb89e91f1010f5516dd044eeeb774fb..475d59808d7d0b998bfc77c01db7786d49b8941b 100644
--- a/app/scodoc/sco_poursuite_dut.py
+++ b/app/scodoc/sco_poursuite_dut.py
@@ -105,7 +105,9 @@ def etud_get_poursuite_info(sem: dict, etud: dict) -> dict:
                                 rangs.append(["rang_" + code_module, rang_module])
 
                 # Absences
-                nbabs, nbabsjust = sco_assiduites.get_assiduites_count(etudid, nt.sem)
+                nbabsnj, nbabsjust, _ = sco_assiduites.get_assiduites_count(
+                    etudid, nt.sem
+                )
                 # En BUT, prend tout, sinon ne prend que les semestre validés par le jury
                 if nt.is_apc or (
                     dec
@@ -125,7 +127,7 @@ def etud_get_poursuite_info(sem: dict, etud: dict) -> dict:
                         ("date_debut", s["date_debut"]),
                         ("date_fin", s["date_fin"]),
                         ("periode", "%s - %s" % (s["mois_debut"], s["mois_fin"])),
-                        ("AbsNonJust", nbabs - nbabsjust),
+                        ("AbsNonJust", nbabsnj),
                         ("AbsJust", nbabsjust),
                     ]
                     # ajout des 2 champs notes des modules et classement dans chaque module
diff --git a/app/tables/recap.py b/app/tables/recap.py
index f26535edc0afeb7d19ad1264a68b98c5678a0109..0c853c3525b98a0b5a3290352584d5b4d0fd33fd 100644
--- a/app/tables/recap.py
+++ b/app/tables/recap.py
@@ -620,7 +620,7 @@ class RowRecap(tb.Row):
     def add_abs(self):
         "Ajoute les colonnes absences"
         # Absences (nb d'abs non just. dans ce semestre)
-        nbabs, nbabsjust = self.table.res.formsemestre.get_abs_count(self.etud.id)
+        _, nbabsjust, nbabs = self.table.res.formsemestre.get_abs_count(self.etud.id)
         self.add_cell("nbabs", "Abs", f"{nbabs:1.0f}", "abs", raw_content=nbabs)
         self.add_cell(
             "nbabsjust", "Just.", f"{nbabsjust:1.0f}", "abs", raw_content=nbabsjust
@@ -691,9 +691,9 @@ class RowRecap(tb.Row):
                 self.add_ue_modimpls_cols(ue, ue_status["is_capitalized"])
 
         self.nb_ues_etud_parcours = len(res.etud_parcours_ues_ids(etud.id))
-        ue_valid_txt = ue_valid_txt_html = (
-            f"{self.nb_ues_validables}/{self.nb_ues_etud_parcours}"
-        )
+        ue_valid_txt = (
+            ue_valid_txt_html
+        ) = f"{self.nb_ues_validables}/{self.nb_ues_etud_parcours}"
         if self.nb_ues_warning:
             ue_valid_txt_html += " " + scu.EMO_WARNING
         cell_class = ""
@@ -717,9 +717,9 @@ class RowRecap(tb.Row):
         # sous-classé par JuryRow pour ajouter les codes
         table: TableRecap = self.table
         formsemestre: FormSemestre = table.res.formsemestre
-        table.group_titles["col_ue"] = (
-            f"UEs du S{formsemestre.semestre_id} {formsemestre.annee_scolaire()}"
-        )
+        table.group_titles[
+            "col_ue"
+        ] = f"UEs du S{formsemestre.semestre_id} {formsemestre.annee_scolaire()}"
         col_id = f"moy_ue_{ue.id}"
         val = (
             ue_status["moy"]
diff --git a/app/views/__init__.py b/app/views/__init__.py
index 890fb63ebc5157cb15b2cfc9c653dd5de44c756c..b28a4e57c5b34966646d89d407b8098417ba3bec 100644
--- a/app/views/__init__.py
+++ b/app/views/__init__.py
@@ -74,8 +74,9 @@ class ScoData:
             if ins:
                 self.etud_cur_sem = ins.formsemestre
                 (
-                    self.nbabs,
+                    self.nbabsnj,
                     self.nbabsjust,
+                    self.nbabs,
                 ) = sco_assiduites.get_assiduites_count_in_interval(
                     etud.id,
                     self.etud_cur_sem.date_debut.isoformat(),
@@ -84,7 +85,6 @@ class ScoData:
                         sco_preferences.get_preference("assi_metrique")
                     ),
                 )
-                self.nbabsnj = self.nbabs - self.nbabsjust
             else:
                 self.etud_cur_sem = None
         else:
diff --git a/app/views/notes.py b/app/views/notes.py
index 717131db305482ebe139d814f2b5221deeed3328..570b64f520eb6163b59dab20763bb68e7639af63 100644
--- a/app/views/notes.py
+++ b/app/views/notes.py
@@ -1187,14 +1187,18 @@ def view_module_abs(moduleimpl_id, fmt="html"):
 
     rows = []
     for etud in inscrits:
-        nb_abs, nb_abs_just = sco_assiduites.formsemestre_get_assiduites_count(
+        (
+            nb_abs_nj,
+            nb_abs_just,
+            nb_abs,
+        ) = sco_assiduites.formsemestre_get_assiduites_count(
             etud.id, modimpl.formsemestre, moduleimpl_id=modimpl.id
         )
         rows.append(
             {
                 "nomprenom": etud.nomprenom,
                 "just": nb_abs_just,
-                "nojust": nb_abs - nb_abs_just,
+                "nojust": nb_abs_nj,
                 "total": nb_abs,
                 "_nomprenom_target": url_for(
                     "scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id