Skip to main content

Appendix B. Day of the Week

This appendix shows how to calculate the day of the week from any Gregorian calendar date. This is important for understanding why RFC 3339 does not include day-of-week information—because it can be precisely calculated.

Zeller's Congruence

A commonly used algorithm for calculating the day of the week is Zeller's Congruence, invented by Christian Zeller in 1882.

Formula

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

Where:

  • h: Day of week (0 = Saturday, 1 = Sunday, 2 = Monday, ..., 6 = Friday)
  • q: Day of month (1-31)
  • m: Month (3-14, where 3 = March, 4 = April, ..., 12 = December, 13 = January, 14 = February)
  • K: Year of century (year % 100)
  • J: Century (⌊year/100⌋)
  • ⌊x⌋: Floor function

Note: January and February are treated as the 13th and 14th months of the previous year.

Python Implementation

def day_of_week_zeller(year, month, day):
"""
Calculate day of week using Zeller's formula
Returns: 0=Saturday, 1=Sunday, ..., 6=Friday
"""
# January and February are treated as months 13 and 14 of previous year
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

# Convert to common format: 0=Monday, ..., 6=Sunday
# Zeller: 0=Sat, 1=Sun, 2=Mon, 3=Tue, 4=Wed, 5=Thu, 6=Fri
# Adjust to: 0=Mon, 1=Tue, 2=Wed, 3=Thu, 4=Fri, 5=Sat, 6=Sun
return (h + 5) % 7

def day_name(year, month, day):
"""Return name of day of week"""
days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
'Friday', 'Saturday', 'Sunday']
return days[day_of_week_zeller(year, month, day)]

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

Simpler Algorithm

For programming implementations, a more intuitive algorithm can be used:

def day_of_week_simple(year, month, day):
"""
Simplified day of week calculation
Returns: 0=Monday, ..., 6=Sunday
"""
# Cumulative days before each month (non-leap year)
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

JavaScript Implementation

function dayOfWeek(year, month, day) {
// JavaScript Date object automatically calculates day of week
const date = new Date(year, month - 1, day);
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday'];
return days[date.getDay()];
}

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

Verification Examples

DateDay of WeekVerified
2002-07-15Monday
2000-01-01Saturday
1999-12-31Friday
1985-04-12Friday
1990-12-31Monday

Why RFC 3339 Doesn't Include Day of Week

1. Redundant Information

Day of week can be precisely calculated from the date, so including it introduces potential inconsistencies:

Incorrect example:
"Monday, 2002-07-16T10:00:00Z"

Problem: 2002-07-16 is actually Tuesday, not Monday
Which should be trusted? Day of week or date?

2. Increased Complexity

Parsers need to handle validation and inconsistencies between day of week and date.

3. Localization Issues

Day of week names differ across languages:

English: Monday, Tuesday, Wednesday, ...
French: Lundi, Mardi, Mercredi, ...
Chinese: 星期一, 星期二, 星期三, ...

4. Doesn't Affect Time Point

Day of week doesn't affect determination of the time point, it's only for human readability.

Recommendation

If you need to display day of week:

from datetime import datetime

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

# Calculate and display day of week
day_name = dt.strftime('%A')
print(f"{timestamp} is a {day_name}")
# Output: 2002-07-15T10:00:00Z is a Monday

Conclusion: Since day of week can be calculated precisely and deterministically from the date, including it in the timestamp format is not only unnecessary but harmful.