Aller au contenu principal

Appendix B. Jour de la semaine

Cette annexe montre comment calculer le jour de la semaine à partir de n'importe quelle date du calendrier grégorien. Ceci est important pour comprendre pourquoi RFC 3339 n'inclut pas d'informations sur le jour de la semaine—parce qu'il peut être calculé précisément.

Congruence de Zeller

Un algorithme couramment utilisé pour calculer le jour de la semaine est la congruence de Zeller, inventée par Christian Zeller en 1882.

Formule

h = (q + ⌊13(m+1)/5⌋ + K + ⌊K/4⌋ + ⌊J/4⌋ - 2J) mod 7

Où :

  • h : Jour de la semaine (0 = samedi, 1 = dimanche, 2 = lundi, ..., 6 = vendredi)
  • q : Jour du mois (1-31)
  • m : Mois (3-14, où 3 = mars, 4 = avril, ..., 12 = décembre, 13 = janvier, 14 = février)
  • K : Année du siècle (year % 100)
  • J : Siècle (⌊year/100⌋)
  • ⌊x⌋ : Fonction plancher

Remarque : Janvier et février sont traités comme les 13e et 14e mois de l'année précédente.

Implémentation Python

def day_of_week_zeller(year, month, day):
"""
Calculer le jour de la semaine en utilisant la formule de Zeller
Retourne : 0=samedi, 1=dimanche, ..., 6=vendredi
"""
# Janvier et février sont traités comme mois 13 et 14 de l'année précédente
if month < 3:
month += 12
year -= 1

q = day
m = month
K = year % 100
J = year // 100

h = (q + (13 * (m + 1)) // 5 + K + K // 4 + J // 4 - 2 * J) % 7

# Convertir au format commun : 0=lundi, ..., 6=dimanche
# Zeller : 0=Sam, 1=Dim, 2=Lun, 3=Mar, 4=Mer, 5=Jeu, 6=Ven
# Ajuster à : 0=Lun, 1=Mar, 2=Mer, 3=Jeu, 4=Ven, 5=Sam, 6=Dim
return (h + 5) % 7

def day_name(year, month, day):
"""Retourner le nom du jour de la semaine"""
days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
'Friday', 'Saturday', 'Sunday']
return days[day_of_week_zeller(year, month, day)]

# Exemples
print(day_name(2002, 7, 15)) # Monday
print(day_name(2000, 1, 1)) # Saturday
print(day_name(1999, 12, 31)) # Friday

Algorithme plus simple

Pour les implémentations de programmation, un algorithme plus intuitif peut être utilisé :

def day_of_week_simple(year, month, day):
"""
Calcul simplifié du jour de la semaine
Retourne : 0=lundi, ..., 6=dimanche
"""
# Jours cumulés avant chaque mois (année non bissextile)
t = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]

if month < 3:
year -= 1

y = year % 100
c = year // 100

return (y + y // 4 + c // 4 - 2 * c + t[month - 1] + day) % 7

Implémentation JavaScript

function dayOfWeek(year, month, day) {
// L'objet Date JavaScript calcule automatiquement le jour de la semaine
const date = new Date(year, month - 1, day);
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday'];
return days[date.getDay()];
}

// Exemples
console.log(dayOfWeek(2002, 7, 15)); // Monday

Exemples de vérification

DateJour de la semaineVérifié
2002-07-15Lundi (Monday)
2000-01-01Samedi (Saturday)
1999-12-31Vendredi (Friday)
1985-04-12Vendredi (Friday)
1990-12-31Lundi (Monday)

Pourquoi RFC 3339 n'inclut pas le jour de la semaine

1. Information redondante

Le jour de la semaine peut être calculé précisément à partir de la date, donc l'inclure introduit des incohérences potentielles :

Exemple incorrect :
"Monday, 2002-07-16T10:00:00Z"

Problème : 2002-07-16 est en fait mardi, pas lundi
Auquel faut-il faire confiance ? Jour de la semaine ou date ?

2. Complexité accrue

Les analyseurs doivent gérer la validation et les incohérences entre le jour de la semaine et la date.

3. Problèmes de localisation

Les noms des jours de la semaine diffèrent selon les langues :

Anglais : Monday, Tuesday, Wednesday, ...
Français : Lundi, Mardi, Mercredi, ...
Chinois : 星期一, 星期二, 星期三, ...

4. N'affecte pas le point temporel

Le jour de la semaine n'affecte pas la détermination du point temporel, c'est seulement pour la lisibilité humaine.

Recommandation

Si vous devez afficher le jour de la semaine :

from datetime import datetime

# Analyser l'horodatage RFC 3339
timestamp = "2002-07-15T10:00:00Z"
dt = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))

# Calculer et afficher le jour de la semaine
day_name = dt.strftime('%A')
print(f"{timestamp} is a {day_name}")
# Sortie : 2002-07-15T10:00:00Z is a Monday

Conclusion : Puisque le jour de la semaine peut être calculé précisément et de manière déterministe à partir de la date, l'inclure dans le format d'horodatage n'est pas seulement inutile mais nuisible.