14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport calendar
24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport unittest
34adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom test import test_support
54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport locale
64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport datetime
74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoresult_2004_text = """
104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                  2004
114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao      January                   February                   March
134adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoMo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao          1  2  3  4                         1       1  2  3  4  5  6  7
154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5  6  7  8  9 10 11       2  3  4  5  6  7  8       8  9 10 11 12 13 14
164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao12 13 14 15 16 17 18       9 10 11 12 13 14 15      15 16 17 18 19 20 21
174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao19 20 21 22 23 24 25      16 17 18 19 20 21 22      22 23 24 25 26 27 28
184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao26 27 28 29 30 31         23 24 25 26 27 28 29      29 30 31
194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao       April                      May                       June
214adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoMo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao          1  2  3  4                      1  2          1  2  3  4  5  6
234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5  6  7  8  9 10 11       3  4  5  6  7  8  9       7  8  9 10 11 12 13
244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao12 13 14 15 16 17 18      10 11 12 13 14 15 16      14 15 16 17 18 19 20
254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao19 20 21 22 23 24 25      17 18 19 20 21 22 23      21 22 23 24 25 26 27
264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao26 27 28 29 30            24 25 26 27 28 29 30      28 29 30
274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                          31
284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        July                     August                  September
304adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoMo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao          1  2  3  4                         1             1  2  3  4  5
324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 5  6  7  8  9 10 11       2  3  4  5  6  7  8       6  7  8  9 10 11 12
334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao12 13 14 15 16 17 18       9 10 11 12 13 14 15      13 14 15 16 17 18 19
344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao19 20 21 22 23 24 25      16 17 18 19 20 21 22      20 21 22 23 24 25 26
354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao26 27 28 29 30 31         23 24 25 26 27 28 29      27 28 29 30
364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                          30 31
374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao      October                   November                  December
394adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoMo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao             1  2  3       1  2  3  4  5  6  7             1  2  3  4  5
414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 4  5  6  7  8  9 10       8  9 10 11 12 13 14       6  7  8  9 10 11 12
424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao11 12 13 14 15 16 17      15 16 17 18 19 20 21      13 14 15 16 17 18 19
434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao18 19 20 21 22 23 24      22 23 24 25 26 27 28      20 21 22 23 24 25 26
444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao25 26 27 28 29 30 31      29 30                     27 28 29 30 31
454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao"""
464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoresult_2004_html = """
484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<?xml version="1.0" encoding="ascii"?>
494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<html>
514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<head>
524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<meta http-equiv="Content-Type" content="text/html; charset=ascii" />
534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<link rel="stylesheet" type="text/css" href="calendar.css" />
544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<title>Calendar for 2004</title>
554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</head>
564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<body>
574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<table border="0" cellpadding="0" cellspacing="0" class="year">
584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th colspan="3" class="year">2004</th></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th colspan="7" class="month">January</th></tr>
604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="thu">1</td><td class="fri">2</td><td class="sat">3</td><td class="sun">4</td></tr>
624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">5</td><td class="tue">6</td><td class="wed">7</td><td class="thu">8</td><td class="fri">9</td><td class="sat">10</td><td class="sun">11</td></tr>
634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">12</td><td class="tue">13</td><td class="wed">14</td><td class="thu">15</td><td class="fri">16</td><td class="sat">17</td><td class="sun">18</td></tr>
644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">19</td><td class="tue">20</td><td class="wed">21</td><td class="thu">22</td><td class="fri">23</td><td class="sat">24</td><td class="sun">25</td></tr>
654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">26</td><td class="tue">27</td><td class="wed">28</td><td class="thu">29</td><td class="fri">30</td><td class="sat">31</td><td class="noday">&nbsp;</td></tr>
664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</table>
674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th colspan="7" class="month">February</th></tr>
694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="sun">1</td></tr>
714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">2</td><td class="tue">3</td><td class="wed">4</td><td class="thu">5</td><td class="fri">6</td><td class="sat">7</td><td class="sun">8</td></tr>
724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">9</td><td class="tue">10</td><td class="wed">11</td><td class="thu">12</td><td class="fri">13</td><td class="sat">14</td><td class="sun">15</td></tr>
734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">16</td><td class="tue">17</td><td class="wed">18</td><td class="thu">19</td><td class="fri">20</td><td class="sat">21</td><td class="sun">22</td></tr>
744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">23</td><td class="tue">24</td><td class="wed">25</td><td class="thu">26</td><td class="fri">27</td><td class="sat">28</td><td class="sun">29</td></tr>
754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</table>
764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th colspan="7" class="month">March</th></tr>
784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">1</td><td class="tue">2</td><td class="wed">3</td><td class="thu">4</td><td class="fri">5</td><td class="sat">6</td><td class="sun">7</td></tr>
804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">8</td><td class="tue">9</td><td class="wed">10</td><td class="thu">11</td><td class="fri">12</td><td class="sat">13</td><td class="sun">14</td></tr>
814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">15</td><td class="tue">16</td><td class="wed">17</td><td class="thu">18</td><td class="fri">19</td><td class="sat">20</td><td class="sun">21</td></tr>
824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">22</td><td class="tue">23</td><td class="wed">24</td><td class="thu">25</td><td class="fri">26</td><td class="sat">27</td><td class="sun">28</td></tr>
834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">29</td><td class="tue">30</td><td class="wed">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</table>
854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th colspan="7" class="month">April</th></tr>
874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="thu">1</td><td class="fri">2</td><td class="sat">3</td><td class="sun">4</td></tr>
894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">5</td><td class="tue">6</td><td class="wed">7</td><td class="thu">8</td><td class="fri">9</td><td class="sat">10</td><td class="sun">11</td></tr>
904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">12</td><td class="tue">13</td><td class="wed">14</td><td class="thu">15</td><td class="fri">16</td><td class="sat">17</td><td class="sun">18</td></tr>
914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">19</td><td class="tue">20</td><td class="wed">21</td><td class="thu">22</td><td class="fri">23</td><td class="sat">24</td><td class="sun">25</td></tr>
924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">26</td><td class="tue">27</td><td class="wed">28</td><td class="thu">29</td><td class="fri">30</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</table>
944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th colspan="7" class="month">May</th></tr>
964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="sat">1</td><td class="sun">2</td></tr>
984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">3</td><td class="tue">4</td><td class="wed">5</td><td class="thu">6</td><td class="fri">7</td><td class="sat">8</td><td class="sun">9</td></tr>
994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">10</td><td class="tue">11</td><td class="wed">12</td><td class="thu">13</td><td class="fri">14</td><td class="sat">15</td><td class="sun">16</td></tr>
1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">17</td><td class="tue">18</td><td class="wed">19</td><td class="thu">20</td><td class="fri">21</td><td class="sat">22</td><td class="sun">23</td></tr>
1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">24</td><td class="tue">25</td><td class="wed">26</td><td class="thu">27</td><td class="fri">28</td><td class="sat">29</td><td class="sun">30</td></tr>
1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</table>
1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th colspan="7" class="month">June</th></tr>
1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="noday">&nbsp;</td><td class="tue">1</td><td class="wed">2</td><td class="thu">3</td><td class="fri">4</td><td class="sat">5</td><td class="sun">6</td></tr>
1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">7</td><td class="tue">8</td><td class="wed">9</td><td class="thu">10</td><td class="fri">11</td><td class="sat">12</td><td class="sun">13</td></tr>
1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">14</td><td class="tue">15</td><td class="wed">16</td><td class="thu">17</td><td class="fri">18</td><td class="sat">19</td><td class="sun">20</td></tr>
1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">21</td><td class="tue">22</td><td class="wed">23</td><td class="thu">24</td><td class="fri">25</td><td class="sat">26</td><td class="sun">27</td></tr>
1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">28</td><td class="tue">29</td><td class="wed">30</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</table>
1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th colspan="7" class="month">July</th></tr>
1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="thu">1</td><td class="fri">2</td><td class="sat">3</td><td class="sun">4</td></tr>
1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">5</td><td class="tue">6</td><td class="wed">7</td><td class="thu">8</td><td class="fri">9</td><td class="sat">10</td><td class="sun">11</td></tr>
1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">12</td><td class="tue">13</td><td class="wed">14</td><td class="thu">15</td><td class="fri">16</td><td class="sat">17</td><td class="sun">18</td></tr>
1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">19</td><td class="tue">20</td><td class="wed">21</td><td class="thu">22</td><td class="fri">23</td><td class="sat">24</td><td class="sun">25</td></tr>
1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">26</td><td class="tue">27</td><td class="wed">28</td><td class="thu">29</td><td class="fri">30</td><td class="sat">31</td><td class="noday">&nbsp;</td></tr>
1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</table>
1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th colspan="7" class="month">August</th></tr>
1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="sun">1</td></tr>
1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">2</td><td class="tue">3</td><td class="wed">4</td><td class="thu">5</td><td class="fri">6</td><td class="sat">7</td><td class="sun">8</td></tr>
1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">9</td><td class="tue">10</td><td class="wed">11</td><td class="thu">12</td><td class="fri">13</td><td class="sat">14</td><td class="sun">15</td></tr>
1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">16</td><td class="tue">17</td><td class="wed">18</td><td class="thu">19</td><td class="fri">20</td><td class="sat">21</td><td class="sun">22</td></tr>
1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">23</td><td class="tue">24</td><td class="wed">25</td><td class="thu">26</td><td class="fri">27</td><td class="sat">28</td><td class="sun">29</td></tr>
1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">30</td><td class="tue">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</table>
1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th colspan="7" class="month">September</th></tr>
1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="wed">1</td><td class="thu">2</td><td class="fri">3</td><td class="sat">4</td><td class="sun">5</td></tr>
1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">6</td><td class="tue">7</td><td class="wed">8</td><td class="thu">9</td><td class="fri">10</td><td class="sat">11</td><td class="sun">12</td></tr>
1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">13</td><td class="tue">14</td><td class="wed">15</td><td class="thu">16</td><td class="fri">17</td><td class="sat">18</td><td class="sun">19</td></tr>
1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">20</td><td class="tue">21</td><td class="wed">22</td><td class="thu">23</td><td class="fri">24</td><td class="sat">25</td><td class="sun">26</td></tr>
1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">27</td><td class="tue">28</td><td class="wed">29</td><td class="thu">30</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</table>
1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th colspan="7" class="month">October</th></tr>
1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="fri">1</td><td class="sat">2</td><td class="sun">3</td></tr>
1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">4</td><td class="tue">5</td><td class="wed">6</td><td class="thu">7</td><td class="fri">8</td><td class="sat">9</td><td class="sun">10</td></tr>
1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">11</td><td class="tue">12</td><td class="wed">13</td><td class="thu">14</td><td class="fri">15</td><td class="sat">16</td><td class="sun">17</td></tr>
1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">18</td><td class="tue">19</td><td class="wed">20</td><td class="thu">21</td><td class="fri">22</td><td class="sat">23</td><td class="sun">24</td></tr>
1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">25</td><td class="tue">26</td><td class="wed">27</td><td class="thu">28</td><td class="fri">29</td><td class="sat">30</td><td class="sun">31</td></tr>
1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</table>
1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th colspan="7" class="month">November</th></tr>
1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">1</td><td class="tue">2</td><td class="wed">3</td><td class="thu">4</td><td class="fri">5</td><td class="sat">6</td><td class="sun">7</td></tr>
1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">8</td><td class="tue">9</td><td class="wed">10</td><td class="thu">11</td><td class="fri">12</td><td class="sat">13</td><td class="sun">14</td></tr>
1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">15</td><td class="tue">16</td><td class="wed">17</td><td class="thu">18</td><td class="fri">19</td><td class="sat">20</td><td class="sun">21</td></tr>
1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">22</td><td class="tue">23</td><td class="wed">24</td><td class="thu">25</td><td class="fri">26</td><td class="sat">27</td><td class="sun">28</td></tr>
1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">29</td><td class="tue">30</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</table>
1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th colspan="7" class="month">December</th></tr>
1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
1624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="wed">1</td><td class="thu">2</td><td class="fri">3</td><td class="sat">4</td><td class="sun">5</td></tr>
1634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">6</td><td class="tue">7</td><td class="wed">8</td><td class="thu">9</td><td class="fri">10</td><td class="sat">11</td><td class="sun">12</td></tr>
1644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">13</td><td class="tue">14</td><td class="wed">15</td><td class="thu">16</td><td class="fri">17</td><td class="sat">18</td><td class="sun">19</td></tr>
1654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">20</td><td class="tue">21</td><td class="wed">22</td><td class="thu">23</td><td class="fri">24</td><td class="sat">25</td><td class="sun">26</td></tr>
1664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao<tr><td class="mon">27</td><td class="tue">28</td><td class="wed">29</td><td class="thu">30</td><td class="fri">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
1674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</table>
1684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</td></tr></table></body>
1694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao</html>
1704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao"""
1714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass OutputTestCase(unittest.TestCase):
1744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def normalize_calendar(self, s):
1754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Filters out locale dependent strings
1764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def neitherspacenordigit(c):
1774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return not c.isspace() and not c.isdigit()
1784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        lines = []
1804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for line in s.splitlines(False):
1814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # Drop texts, as they are locale dependent
1824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if line and not filter(neitherspacenordigit, line):
1834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                lines.append(line)
1844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return lines
1854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_output(self):
1874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(
1884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.normalize_calendar(calendar.calendar(2004)),
1894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.normalize_calendar(result_2004_text)
1904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        )
1914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_output_textcalendar(self):
1934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(
1944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            calendar.TextCalendar().formatyear(2004).strip(),
1954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            result_2004_text.strip()
1964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        )
1974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_output_htmlcalendar(self):
1994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(
2004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            calendar.HTMLCalendar().formatyearpage(2004).strip(),
2014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            result_2004_html.strip()
2024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        )
2034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass CalendarTestCase(unittest.TestCase):
2064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_isleap(self):
2074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Make sure that the return is right for a few years, and
2084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # ensure that the return values are 1 or 0, not just true or
2094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # false (see SF bug #485794).  Specific additional tests may
2104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # be appropriate; this tests a single "cycle".
2114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.isleap(2000), 1)
2124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.isleap(2001), 0)
2134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.isleap(2002), 0)
2144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.isleap(2003), 0)
2154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_setfirstweekday(self):
2174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(ValueError, calendar.setfirstweekday, 'flabber')
2184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(ValueError, calendar.setfirstweekday, -1)
2194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(ValueError, calendar.setfirstweekday, 200)
2204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        orig = calendar.firstweekday()
2214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        calendar.setfirstweekday(calendar.SUNDAY)
2224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.firstweekday(), calendar.SUNDAY)
2234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        calendar.setfirstweekday(calendar.MONDAY)
2244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.firstweekday(), calendar.MONDAY)
2254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        calendar.setfirstweekday(orig)
2264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_enumerateweekdays(self):
2284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(IndexError, calendar.day_abbr.__getitem__, -10)
2294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(IndexError, calendar.day_name.__getitem__, 10)
2304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(len([d for d in calendar.day_abbr]), 7)
2314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_days(self):
2334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for attr in "day_name", "day_abbr":
2344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            value = getattr(calendar, attr)
2354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(len(value), 7)
2364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(len(value[:]), 7)
2374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # ensure they're all unique
2384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(len(set(value)), 7)
2394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # verify it "acts like a sequence" in two forms of iteration
2404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(value[::-1], list(reversed(value)))
2414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_months(self):
2434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for attr in "month_name", "month_abbr":
2444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            value = getattr(calendar, attr)
2454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(len(value), 13)
2464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(len(value[:]), 13)
2474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(value[0], "")
2484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # ensure they're all unique
2494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(len(set(value)), 13)
2504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # verify it "acts like a sequence" in two forms of iteration
2514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(value[::-1], list(reversed(value)))
2524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_localecalendars(self):
2544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # ensure that Locale{Text,HTML}Calendar resets the locale properly
2554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # (it is still not thread-safe though)
2564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
2574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        try:
2584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            cal = calendar.LocaleTextCalendar(locale='')
2594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            local_weekday = cal.formatweekday(1, 10)
2604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            local_month = cal.formatmonthname(2010, 10, 10)
2614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        except locale.Error:
2624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # cannot set the system default locale -- skip rest of test
2634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            raise unittest.SkipTest('cannot set the system default locale')
2644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # should be encodable
2654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        local_weekday.encode('utf-8')
2664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        local_month.encode('utf-8')
2674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(len(local_weekday), 10)
2684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertGreaterEqual(len(local_month), 10)
2694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        cal = calendar.LocaleHTMLCalendar(locale='')
2704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        local_weekday = cal.formatweekday(1)
2714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        local_month = cal.formatmonthname(2010, 10)
2724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # should be encodable
2734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        local_weekday.encode('utf-8')
2744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        local_month.encode('utf-8')
2754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
2764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(old_october, new_october)
2774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_itermonthdates(self):
2794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # ensure itermonthdates doesn't overflow after datetime.MAXYEAR
2804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # see #15421
2814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        list(calendar.Calendar().itermonthdates(datetime.MAXYEAR, 12))
2824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MonthCalendarTestCase(unittest.TestCase):
2854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def setUp(self):
2864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.oldfirstweekday = calendar.firstweekday()
2874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        calendar.setfirstweekday(self.firstweekday)
2884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def tearDown(self):
2904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        calendar.setfirstweekday(self.oldfirstweekday)
2914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def check_weeks(self, year, month, weeks):
2934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        cal = calendar.monthcalendar(year, month)
2944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(len(cal), len(weeks))
2954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for i in xrange(len(weeks)):
2964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(weeks[i], sum(day != 0 for day in cal[i]))
2974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MondayTestCase(MonthCalendarTestCase):
3004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    firstweekday = calendar.MONDAY
3014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_february(self):
3034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 28-day february starting on monday (7+7+7+7 days)
3044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1999, 2, (7, 7, 7, 7))
3054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 28-day february starting on tuesday (6+7+7+7+1 days)
3074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(2005, 2, (6, 7, 7, 7, 1))
3084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 28-day february starting on sunday (1+7+7+7+6 days)
3104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1987, 2, (1, 7, 7, 7, 6))
3114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 29-day february starting on monday (7+7+7+7+1 days)
3134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1988, 2, (7, 7, 7, 7, 1))
3144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 29-day february starting on tuesday (6+7+7+7+2 days)
3164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1972, 2, (6, 7, 7, 7, 2))
3174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 29-day february starting on sunday (1+7+7+7+7 days)
3194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(2004, 2, (1, 7, 7, 7, 7))
3204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_april(self):
3224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 30-day april starting on monday (7+7+7+7+2 days)
3234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1935, 4, (7, 7, 7, 7, 2))
3244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 30-day april starting on tuesday (6+7+7+7+3 days)
3264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1975, 4, (6, 7, 7, 7, 3))
3274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 30-day april starting on sunday (1+7+7+7+7+1 days)
3294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1945, 4, (1, 7, 7, 7, 7, 1))
3304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 30-day april starting on saturday (2+7+7+7+7 days)
3324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1995, 4, (2, 7, 7, 7, 7))
3334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 30-day april starting on friday (3+7+7+7+6 days)
3354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1994, 4, (3, 7, 7, 7, 6))
3364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_december(self):
3384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 31-day december starting on monday (7+7+7+7+3 days)
3394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1980, 12, (7, 7, 7, 7, 3))
3404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 31-day december starting on tuesday (6+7+7+7+4 days)
3424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1987, 12, (6, 7, 7, 7, 4))
3434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 31-day december starting on sunday (1+7+7+7+7+2 days)
3454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1968, 12, (1, 7, 7, 7, 7, 2))
3464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 31-day december starting on thursday (4+7+7+7+6 days)
3484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1988, 12, (4, 7, 7, 7, 6))
3494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 31-day december starting on friday (3+7+7+7+7 days)
3514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(2017, 12, (3, 7, 7, 7, 7))
3524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 31-day december starting on saturday (2+7+7+7+7+1 days)
3544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(2068, 12, (2, 7, 7, 7, 7, 1))
3554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass SundayTestCase(MonthCalendarTestCase):
3584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    firstweekday = calendar.SUNDAY
3594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_february(self):
3614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 28-day february starting on sunday (7+7+7+7 days)
3624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(2009, 2, (7, 7, 7, 7))
3634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 28-day february starting on monday (6+7+7+7+1 days)
3654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1999, 2, (6, 7, 7, 7, 1))
3664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 28-day february starting on saturday (1+7+7+7+6 days)
3684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1997, 2, (1, 7, 7, 7, 6))
3694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 29-day february starting on sunday (7+7+7+7+1 days)
3714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(2004, 2, (7, 7, 7, 7, 1))
3724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 29-day february starting on monday (6+7+7+7+2 days)
3744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1960, 2, (6, 7, 7, 7, 2))
3754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 29-day february starting on saturday (1+7+7+7+7 days)
3774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1964, 2, (1, 7, 7, 7, 7))
3784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_april(self):
3804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 30-day april starting on sunday (7+7+7+7+2 days)
3814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1923, 4, (7, 7, 7, 7, 2))
3824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 30-day april starting on monday (6+7+7+7+3 days)
3844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1918, 4, (6, 7, 7, 7, 3))
3854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 30-day april starting on saturday (1+7+7+7+7+1 days)
3874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1950, 4, (1, 7, 7, 7, 7, 1))
3884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 30-day april starting on friday (2+7+7+7+7 days)
3904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1960, 4, (2, 7, 7, 7, 7))
3914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 30-day april starting on thursday (3+7+7+7+6 days)
3934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1909, 4, (3, 7, 7, 7, 6))
3944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_december(self):
3964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 31-day december starting on sunday (7+7+7+7+3 days)
3974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(2080, 12, (7, 7, 7, 7, 3))
3984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 31-day december starting on monday (6+7+7+7+4 days)
4004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1941, 12, (6, 7, 7, 7, 4))
4014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 31-day december starting on saturday (1+7+7+7+7+2 days)
4034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1923, 12, (1, 7, 7, 7, 7, 2))
4044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 31-day december starting on wednesday (4+7+7+7+6 days)
4064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1948, 12, (4, 7, 7, 7, 6))
4074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 31-day december starting on thursday (3+7+7+7+7 days)
4094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1927, 12, (3, 7, 7, 7, 7))
4104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # A 31-day december starting on friday (2+7+7+7+7+1 days)
4124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_weeks(1995, 12, (2, 7, 7, 7, 7, 1))
4134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass MonthRangeTestCase(unittest.TestCase):
4164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_january(self):
4174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Tests valid lower boundary case.
4184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.monthrange(2004,1), (3,31))
4194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_february_leap(self):
4214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Tests February during leap year.
4224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.monthrange(2004,2), (6,29))
4234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_february_nonleap(self):
4254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Tests February in non-leap year.
4264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.monthrange(2010,2), (0,28))
4274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_december(self):
4294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Tests valid upper boundary case.
4304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.monthrange(2004,12), (2,31))
4314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_zeroth_month(self):
4334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Tests low invalid boundary case.
4344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        with self.assertRaises(calendar.IllegalMonthError):
4354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            calendar.monthrange(2004, 0)
4364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_thirteenth_month(self):
4384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Tests high invalid boundary case.
4394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        with self.assertRaises(calendar.IllegalMonthError):
4404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            calendar.monthrange(2004, 13)
4414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass LeapdaysTestCase(unittest.TestCase):
4434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_no_range(self):
4444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # test when no range i.e. two identical years as args
4454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.leapdays(2010,2010), 0)
4464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_no_leapdays(self):
4484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # test when no leap years in range
4494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.leapdays(2010,2011), 0)
4504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_no_leapdays_upper_boundary(self):
4524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # test no leap years in range, when upper boundary is a leap year
4534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.leapdays(2010,2012), 0)
4544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_one_leapday_lower_boundary(self):
4564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # test when one leap year in range, lower boundary is leap year
4574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.leapdays(2012,2013), 1)
4584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_several_leapyears_in_range(self):
4604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(calendar.leapdays(1997,2020), 5)
4614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef test_main():
4644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    test_support.run_unittest(
4654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        OutputTestCase,
4664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        CalendarTestCase,
4674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        MondayTestCase,
4684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        SundayTestCase,
4694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        MonthRangeTestCase,
4704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        LeapdaysTestCase,
4714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    )
4724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif __name__ == "__main__":
4754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    test_main()
476