diff --git a/app/scodoc/sco_liste_notes.py b/app/scodoc/sco_liste_notes.py
index 733536c877ac2f9ac0cfcff88e49ff5f92df3915..b955814225fb60fcb68a0b9367227bb72665c167 100644
--- a/app/scodoc/sco_liste_notes.py
+++ b/app/scodoc/sco_liste_notes.py
@@ -310,10 +310,14 @@ def _make_table_notes(
     rows = []
 
     class KeyManager(dict):
-        "comment : key (pour regrouper les comments a la fin)"
+        """(comment, date_saisie_iso) : key (pour regrouper les comments a la fin)
+        La date_saisie_iso est tronquée à la minute.
+        """
 
         def __init__(self):
             self.lastkey = 1
+            self.comment_to_idx = {}
+            self.sorted_keys = []
 
         def nextkey(self) -> str:
             "get new key (int)"
@@ -322,6 +326,20 @@ def _make_table_notes(
             # self.lastkey = chr(ord(self.lastkey)+1)
             return str(r)
 
+        def sort_keys(self):
+            "sort keys"
+            keys = sorted(self.keys(), key=lambda x: x[1])  # tri sur date
+            self.sorted_keys = keys
+            self.comment_to_idx = {k: i for i, k in enumerate(keys, start=1)}
+
+        def remplace_rows(self, rows):
+            "remplace les keys dans les rows"
+            for row in rows:
+                key = row.get("expl_key")
+                if key:
+                    i = self.comment_to_idx[key]
+                    row["expl_key"] = f"({i})"
+
     key_mgr = KeyManager()
 
     # code pour listings anonyme, à la place du nom
@@ -338,9 +356,7 @@ def _make_table_notes(
     for etudid, etat in etudid_etats:
         css_row_class = None
         # infos identite etudiant
-        etud: Identite = Identite.query.filter_by(
-            id=etudid, dept_id=g.scodoc_dept_id
-        ).first()
+        etud = Identite.get_etud(etudid, accept_none=True)
         if etud is None:
             continue
 
@@ -448,7 +464,11 @@ def _make_table_notes(
             fmt=fmt,
         )
         columns_ids.append(e.id)
-    #
+    # Renumerote les commentaires pour tri
+    # la colonne est 'expl_key' qui (explanation, date_saisie)
+    # on remplace par le numero
+    key_mgr.sort_keys()
+    key_mgr.remplace_rows(rows)
     if args["anonymous_listing"]:
         rows.sort(key=lambda x: x["code"] or "")
     else:
@@ -669,22 +689,21 @@ def _make_table_notes(
         <td style="padding-left: 50px; vertical-align: top;"><p>
         """
     ]
-    commentkeys = list(key_mgr.items())  # [ (comment, key), ... ]
-    commentkeys.sort(key=lambda x: int(x[1]))
-    for comment, key in commentkeys:
+    for key in key_mgr.sorted_keys:
         section_basse_html.append(
-            f"""<span class="colcomment">({key})</span> <em>{comment}</em><br>"""
+            f"""<span class="colcomment">({key_mgr.comment_to_idx[key]})</span> <em>{key[0]}</em><br>"""
         )
-    if commentkeys:
+    if key_mgr.sorted_keys:
         section_basse_html.append(
             f"""<span><a class=stdlink" href="{ url_for(
-                    'notes.evaluation_list_operations', scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id )
+                    'notes.evaluation_list_operations',
+                    scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id )
                 }">Gérer les opérations</a></span><br>
             """
         )
     eval_info = ""
     if evals_state[evaluation.id]["evalcomplete"]:
-        eval_info = '<span class="eval_info eval_complete">Evaluation prise en compte dans les moyennes</span>'
+        eval_info = '<span class="eval_info eval_complete">Évaluation prise en compte dans les moyennes</span>'
     elif evals_state[evaluation.id]["evalattente"]:
         eval_info = '<span class="eval_info eval_attente">Il y a des notes en attente (les autres sont prises en compte)</span>'
     else:
@@ -712,7 +731,7 @@ def _add_eval_columns(
     row_note_max,
     row_moys,
     is_apc,
-    K,
+    key_mgr,
     note_sur_20,
     keep_numeric,
     fmt="html",
@@ -776,7 +795,11 @@ def _add_eval_columns(
                 sco_users.user_info(notes_db[etudid]["uid"])["nomcomplet"],
                 comment,
             )
+            date_saisie = (
+                notes_db[etudid]["date"].replace(second=0, microsecond=0).isoformat()
+            )
         else:
+            date_saisie = ""
             if (etudid in etudids_actifs) and evaluation.publish_incomplete:
                 # Note manquante mais prise en compte immédiate: affiche ATT
                 val = scu.NOTES_ATTENTE
@@ -799,11 +822,9 @@ def _add_eval_columns(
             row[f"_{evaluation.id}_td_attrs"] = f'class="{cell_class}" '
         # regroupe les commentaires
         if explanation:
-            if explanation in K:
-                expl_key = "(%s)" % K[explanation]
-            else:
-                K[explanation] = K.nextkey()
-                expl_key = "(%s)" % K[explanation]
+            if (explanation, date_saisie) not in key_mgr:
+                key_mgr[(explanation, date_saisie)] = key_mgr.nextkey()
+            expl_key = (explanation, date_saisie)
         else:
             expl_key = ""