Skip to content

Commit 66c88ce

Browse files
authored
Closes bpo-28281: Remove year (1-9999) limits on the weekday() function. (python#4109)
Patch by Mark Gollahon.
1 parent 52ad72d commit 66c88ce

File tree

5 files changed

+74
-5
lines changed

5 files changed

+74
-5
lines changed

Doc/library/calendar.rst

+5-3
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ the week to Sunday (6) or to any other weekday. Parameters that specify dates
1919
are given as integers. For related
2020
functionality, see also the :mod:`datetime` and :mod:`time` modules.
2121

22-
Most of these functions and classes rely on the :mod:`datetime` module which
23-
uses an idealized calendar, the current Gregorian calendar extended
22+
The functions and classes defined in this module
23+
use an idealized calendar, the current Gregorian calendar extended indefinitely
2424
in both directions. This matches the definition of the "proleptic Gregorian"
2525
calendar in Dershowitz and Reingold's book "Calendrical Calculations", where
26-
it's the base calendar for all computations.
26+
it's the base calendar for all computations. Zero and negative years are
27+
interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is
28+
2 BC, and so on.
2729

2830

2931
.. class:: Calendar(firstweekday=0)

Lib/calendar.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,9 @@ def leapdays(y1, y2):
111111

112112

113113
def weekday(year, month, day):
114-
"""Return weekday (0-6 ~ Mon-Sun) for year (1970-...), month (1-12),
115-
day (1-31)."""
114+
"""Return weekday (0-6 ~ Mon-Sun) for year, month (1-12), day (1-31)."""
115+
if not datetime.MINYEAR <= year <= datetime.MAXYEAR:
116+
year = 2000 + year % 400
116117
return datetime.date(year, month, day).weekday()
117118

118119

Lib/test/test_calendar.py

+62
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,56 @@
99
import datetime
1010
import os
1111

12+
# From https://en.wikipedia.org/wiki/Leap_year_starting_on_Saturday
13+
result_0_02_text = """\
14+
February 0
15+
Mo Tu We Th Fr Sa Su
16+
1 2 3 4 5 6
17+
7 8 9 10 11 12 13
18+
14 15 16 17 18 19 20
19+
21 22 23 24 25 26 27
20+
28 29
21+
"""
22+
23+
result_0_text = """\
24+
0
25+
26+
January February March
27+
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
28+
1 2 1 2 3 4 5 6 1 2 3 4 5
29+
3 4 5 6 7 8 9 7 8 9 10 11 12 13 6 7 8 9 10 11 12
30+
10 11 12 13 14 15 16 14 15 16 17 18 19 20 13 14 15 16 17 18 19
31+
17 18 19 20 21 22 23 21 22 23 24 25 26 27 20 21 22 23 24 25 26
32+
24 25 26 27 28 29 30 28 29 27 28 29 30 31
33+
31
34+
35+
April May June
36+
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
37+
1 2 1 2 3 4 5 6 7 1 2 3 4
38+
3 4 5 6 7 8 9 8 9 10 11 12 13 14 5 6 7 8 9 10 11
39+
10 11 12 13 14 15 16 15 16 17 18 19 20 21 12 13 14 15 16 17 18
40+
17 18 19 20 21 22 23 22 23 24 25 26 27 28 19 20 21 22 23 24 25
41+
24 25 26 27 28 29 30 29 30 31 26 27 28 29 30
42+
43+
July August September
44+
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
45+
1 2 1 2 3 4 5 6 1 2 3
46+
3 4 5 6 7 8 9 7 8 9 10 11 12 13 4 5 6 7 8 9 10
47+
10 11 12 13 14 15 16 14 15 16 17 18 19 20 11 12 13 14 15 16 17
48+
17 18 19 20 21 22 23 21 22 23 24 25 26 27 18 19 20 21 22 23 24
49+
24 25 26 27 28 29 30 28 29 30 31 25 26 27 28 29 30
50+
31
51+
52+
October November December
53+
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
54+
1 1 2 3 4 5 1 2 3
55+
2 3 4 5 6 7 8 6 7 8 9 10 11 12 4 5 6 7 8 9 10
56+
9 10 11 12 13 14 15 13 14 15 16 17 18 19 11 12 13 14 15 16 17
57+
16 17 18 19 20 21 22 20 21 22 23 24 25 26 18 19 20 21 22 23 24
58+
23 24 25 26 27 28 29 27 28 29 30 25 26 27 28 29 30 31
59+
30 31
60+
"""
61+
1262
result_2004_01_text = """\
1363
January 2004
1464
Mo Tu We Th Fr Sa Su
@@ -343,12 +393,20 @@ def test_output(self):
343393
self.normalize_calendar(calendar.calendar(2004)),
344394
self.normalize_calendar(result_2004_text)
345395
)
396+
self.assertEqual(
397+
self.normalize_calendar(calendar.calendar(0)),
398+
self.normalize_calendar(result_0_text)
399+
)
346400

347401
def test_output_textcalendar(self):
348402
self.assertEqual(
349403
calendar.TextCalendar().formatyear(2004),
350404
result_2004_text
351405
)
406+
self.assertEqual(
407+
calendar.TextCalendar().formatyear(0),
408+
result_0_text
409+
)
352410

353411
def test_output_htmlcalendar_encoding_ascii(self):
354412
self.check_htmlcalendar_encoding('ascii', 'ascii')
@@ -393,6 +451,10 @@ def test_formatmonth(self):
393451
calendar.TextCalendar().formatmonth(2004, 1),
394452
result_2004_01_text
395453
)
454+
self.assertEqual(
455+
calendar.TextCalendar().formatmonth(0, 2),
456+
result_0_02_text
457+
)
396458

397459
def test_formatmonthname_with_year(self):
398460
self.assertEqual(

Misc/ACKS

+1
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ Karan Goel
545545
Jeroen Van Goey
546546
Christoph Gohlke
547547
Tim Golden
548+
Mark Gollahon
548549
Guilherme Gonçalves
549550
Tiago Gonçalves
550551
Chris Gonnerman
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Remove year (1-9999) limits on the Calendar.weekday() function.
2+
3+
Patch by Mark Gollahon.

0 commit comments

Comments
 (0)