# `calendar` --- 日曆相關函式

原始碼： Lib/calendar.py

這個模組讓你可以像 Unix 的 cal 程式一樣輸出日曆，並額外提供有用的日曆相關函式。這些日曆預設把週一當作一週的第一天，而週日當作最後一天（歐洲的慣例）。可以使用 `setfirstweekday()` 設定一週的第一天為週日 (6) 或一週的其它任一天，其中指定日期的參數是整數。相關功能參考 `datetime` 和 `time` 模組。

這個模組定義的函式和類別使用理想化的日曆，也就是公曆 (Gregorian calendar) 無限往前後兩個方向延伸。這符合 Dershowitz 和 Reingold 在「Calendrical Calculations」這本書定義的「逆推公曆」(proleptic Gregorian)，是做所有計算的基礎日曆。0 及負數年份的解讀跟 ISO 8601 標準裡規定的一樣，0 年是公元前 1 年，-1 年是公元前 2 年依此類推。

class calendar.Calendar(firstweekday=0)

  建立 `Calendar` 物件。firstweekday 是一個指定一週第一天的整數，`MONDAY` 是 `0`（預設值），`SUNDAY` 是 `6`。

  `Calendar` 物件提供一些方法來為日曆資料的格式化做準備。這個類別本身不做任何格式化，這是子類別的工作。

  `Calendar` 實例有以下方法：

  iterweekdays()

    回傳一個以數字代表一週的每一天的疊代器 (iterator)。疊代器的第一個值和 `firstweekday` 屬性的值一樣。

  itermonthdates(year, month)

    回傳一個在 year 年 month (1--12) 月的疊代器。這個疊代器會回傳該月的所有日期（`datetime.date` 物件）以及在該月之前及之後用來組成完整一週的日期。

  itermonthdays(year, month)

    類似 `itermonthdates()`，回傳一個在 year 年 month 月的疊代器，但不受限於 `datetime.date` 的範圍。回傳的日期單純是該月當日的數字，對於該月之外的日期數字會是 `0`。

  itermonthdays2(year, month)

    類似 `itermonthdates()`，回傳一個在 year 年 month 月的疊代器，但不受限於 `datetime.date` 的範圍。回傳的日期是一個由該月當日的數字及代表週幾的數字組成的元組。

  itermonthdays3(year, month)

    類似 `itermonthdates()`，回傳一個在 year 年 month 月的疊代器，但不受限於 `datetime.date` 的範圍。回傳的日期是一個由年、月、日的數字組成的元組。

    在 3.7 版被加入.

  itermonthdays4(year, month)

    類似 `itermonthdates()`，回傳一個在 year 年 month 月的疊代器，但不受限於 `datetime.date` 的範圍。回傳的日期是一個由年、月、日及代表週幾的數字組成的元組。

    在 3.7 版被加入.

  monthdatescalendar(year, month)

    回傳一個在 year 年 month 月每一週組成的串列。每一週是一個串列，包含七個 `datetime.date` 物件。

  monthdays2calendar(year, month)

    回傳一個在 year 年 month 月每一週組成的串列。每一週是一個串列，包含七個該月當日的數字及代表週幾的數字組成的元組。

  monthdayscalendar(year, month)

    回傳一個在 year 年 month 月每一週組成的串列。每一週是一個串列，包含七個該月當日的數字。

  yeardatescalendar(year, width=3)

    回傳用來格式化的指定年份的資料。回傳值是月份列的串列，每個月份列最多由 width 個月份組成（預設為 3）。每個月份包含四到六週，每一週包含一到七天，每一天則是一個 `datetime.date` 物件。

  yeardays2calendar(year, width=3)

    回傳用來格式化的指定年份的資料（類似 `yeardatescalendar()`）。每一天是一個該月當日的數字及代表週幾的數字組成的元組，該月外的日期的該月當日數字為 0。

  yeardayscalendar(year, width=3)

    回傳用來格式化的指定年份的資料（類似 `yeardatescalendar()`）。每一天是一個該月當日的數字，該月外的日期的該月當日數字為 0。

class calendar.TextCalendar(firstweekday=0)

  這個類別用來產生純文字的日曆。

  `TextCalendar` 實例有以下方法：

  formatmonth(theyear, themonth, w=0, l=0)

    以多行字串的形式回傳一個月份的日曆。如果給定 w，它會指定置中的日期欄的寬度。如果給定 l，它會指定每一週使用的行數。這個日曆會依據在建構函式中指定或者透過 `setfirstweekday()` 方法設定的一週的第一天來輸出。

  prmonth(theyear, themonth, w=0, l=0)

    印出一個月份的日曆，內容和 `formatmonth()` 回傳的一樣。

  formatyear(theyear, w=2, l=1, c=6, m=3)

    以多行字串的形式回傳有 m 欄的一整年的日曆。可選的參數 w、l 及 c 分別是日期欄寬度、每週行數及月份欄中間的空白數。這個日曆會依據在建構函式中指定或者透過 `setfirstweekday()` 方法設定的一週的第一天來輸出。最早可以產生日曆的年份會依據平台而不同。

  pryear(theyear, w=2, l=1, c=6, m=3)

    印出一整年的日曆，內容和 `formatyear()` 回傳的一樣。

class calendar.HTMLCalendar(firstweekday=0)

  這個類別用來產生 HTML 日曆。

  `HTMLCalendar` 實例有以下方法：

  formatmonth(theyear, themonth, withyear=True)

    以 HTML 表格的形式回傳一個月份的日曆。如果 withyear 是 true 則標題會包含年份，否則只會有月份名稱。

  formatyear(theyear, width=3)

    以 HTML 表格的形式回傳一整年的日曆。width（預設為 3）指定一列有幾個月。

  formatyearpage(theyear, width=3, css='calendar.css', encoding=None)

    以完整 HTML 頁面的形式回傳一整年的日曆。width（預設為 3）指定一列有幾個月。css 是要使用的 CSS (cascading style sheet) 名稱，可以給 `None` 表示不使用任何 CSS。encoding 指定輸出使用的編碼（預設使用系統預設編碼）。

  formatmonthname(theyear, themonth, withyear=True)

    以 HTML 表列的形式回傳一個月份的名稱。如果 withyear 是 true 則該列會包含年份，否則只會有月份名稱。

  `HTMLCalendar` 可以覆寫以下屬性來客製日曆所使用的 CSS 類別：

  cssclasses

    對應一週每一天 CSS 類別的串列。預設的串列內容為：

        cssclasses = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]

    可以針對每一天增加更多樣式：

        cssclasses = ["mon text-bold", "tue", "wed", "thu", "fri", "sat", "sun red"]

    注意這個串列的長度必須是七個項目。

  cssclass_noday

    跟當月為同一週且屬於前一個或下一個月份的日期使用的 CSS 類別。

    在 3.7 版被加入.

  cssclasses_weekday_head

    在標題列中一週每一天名稱的 CSS 類別的串列。預設內容和 `cssclasses` 相同。

    在 3.7 版被加入.

  cssclass_month_head

    月份標題的 CSS 類別（由 `formatmonthname()` 所使用），預設值是 `"month"`。

    在 3.7 版被加入.

  cssclass_month

    整個月份表格的 CSS 類別（由 `formatmonth()` 所使用），預設值是 `"month"`。

    在 3.7 版被加入.

  cssclass_year

    整年表格的 CSS 類別（由 `formatyear()` 所使用），預設值是 `"year"`。

    在 3.7 版被加入.

  cssclass_year_head

    整年表格標題的 CSS 類別（由 `formatyear()` 所使用），預設值是 `"year"`。

    在 3.7 版被加入.

  注意雖然上面提到的 CSS 屬性名稱是單數（例如 `cssclass_month`、`cssclass_noday`），你可以使用多個以空格隔開的 CSS 類別取代單一 CSS 類別，例如：

      "text-bold text-red"

  以下是客製化 `HTMLCalendar` 的範例：

      class CustomHTMLCal(calendar.HTMLCalendar):
          cssclasses = [style + " text-nowrap" for style in
                        calendar.HTMLCalendar.cssclasses]
          cssclass_month_head = "text-center month-head"
          cssclass_month = "text-center month"
          cssclass_year = "text-italic lead"

class calendar.LocaleTextCalendar(firstweekday=0, locale=None)

  `TextCalendar` 的子類別，可以在建構函式傳入語系名稱，它會回傳指定語系的月份及一週每一天的名稱。

class calendar.LocaleHTMLCalendar(firstweekday=0, locale=None)

  `HTMLCalendar` 的子類別，可以在建構函式傳入語系名稱，它會回傳指定語系的月份及一週每一天的名稱。

備註

這兩個類別的建構函式、`formatweekday()` 及 `formatmonthname()` 方法會把 `LC_TIME` 語系暫時改成給定的 locale。因為目前的語系是屬於整個行程 (process-wide) 的設定，它們不是執行緒安全的。

這個模組提供以下函式給單純的文字日曆使用。

calendar.setfirstweekday(weekday)

  設定一週的第一天（`0` 是週一、`6` 是週日）。提供 `MONDAY`、`TUESDAY`、`WEDNESDAY`、`THURSDAY`、`FRIDAY`、`SATURDAY` 及 `SUNDAY` 可以方便設定。例如設定一週的第一天為週日：

      import calendar
      calendar.setfirstweekday(calendar.SUNDAY)

calendar.firstweekday()

  回傳目前設定的一週的第一天。

calendar.isleap(year)

  如果 year 是閏年回傳 `True`，否則回傳 `False`。

calendar.leapdays(y1, y2)

  回傳從 y1 到 y2（不包含）間有幾個閏年，其中 y1 和 y2 是年份。

  這個函式也適用在跨越世紀的時間範圍。

calendar.weekday(year, month, day)

  回傳 year 年 (`1970`--...) month 月 (`1`--`12`) day 日 (`1`--`31`) 是週幾（`0` 是星期一）。

calendar.weekheader(n)

  回傳包含一週每一天的名稱縮寫的標題。n 指定每一天的字元寬度。

calendar.monthrange(year, month)

  回傳指定 year 年 month 月該月第一天代表週幾的數字及該月有多少天。

calendar.monthcalendar(year, month)

  回傳代表一個月份日曆的矩陣。每一列為一週；該月以外的日期以 0 表示。每一週以週一開始，除非有使用 `setfirstweekday()` 改變設定。

calendar.prmonth(theyear, themonth, w=0, l=0)

  印出一個月份的日曆，跟 `month()` 回傳的內容一樣。

calendar.month(theyear, themonth, w=0, l=0)

  以多行字串的形式回傳一個月的日曆，使用 `TextCalendar` 類別的 `formatmonth()`。

calendar.prcal(year, w=0, l=0, c=6, m=3)

  印出一整年的日曆，跟 `calendar()` 回傳的內容一樣。

calendar.calendar(year, w=2, l=1, c=6, m=3)

  以多行字串回傳三欄形式的一整年日曆，使用 `TextCalendar` 類別的 `formatyear()`。

calendar.timegm(tuple)

  一個跟日曆無關但方便的函式，它接受一個像 `time` 模組裡的 `gmtime()` 函式回傳的元組，並回傳對應的 Unix 時間戳，假設從 1970 開始及 POSIX 編碼。事實上，`time.gmtime()` 和 `timegm()` 是彼此相反的。

`calendar` 模組匯出以下資料屬性：

calendar.day_name

  以目前語系來表示的一週每一天名稱的陣列。

calendar.day_abbr

  以目前語系來表示的一週每一天縮寫名稱的陣列。

calendar.MONDAY
calendar.TUESDAY
calendar.WEDNESDAY
calendar.THURSDAY
calendar.FRIDAY
calendar.SATURDAY
calendar.SUNDAY

  一週每一天的別名，其中 `MONDAY` 是 `0` 而 `SUNDAY` 是 `6`。

  在 3.12 版被加入.

class calendar.Day

  將一週中的幾天定義為整數常數的列舉。此列舉的成員將作為 `MONDAY` 到 `SUNDAY` 匯出到模組作用域。

  在 3.12 版被加入.

calendar.month_name

  以目前語系來表示的一年每個月份名稱的陣列。它按照一般慣例以數字 1 代表一月，因此它的長度為 13，而 `month_name[0]` 是空字串。

calendar.month_abbr

  以目前語系來表示的一年每個月份縮寫名稱的陣列。它按照一般慣例以數字 1 代表一月，因此它的長度為 13，而 `month_abbr[0]` 是空字串。

calendar.JANUARY
calendar.FEBRUARY
calendar.MARCH
calendar.APRIL
calendar.MAY
calendar.JUNE
calendar.JULY
calendar.AUGUST
calendar.SEPTEMBER
calendar.OCTOBER
calendar.NOVEMBER
calendar.DECEMBER

  一年內每個月的別名，其中 `JANUARY` 是 `ㄅ` 而 `DECEMBER` 是 `12`。

  在 3.12 版被加入.

class calendar.Month

  將一年中的月份定義為整數常數的列舉。此列舉的成員將作為 `JANUARY` 到 `DECEMBER` 匯出到模組作用域。

  在 3.12 版被加入.

`calendar` 模組定義了以下例外：

exception calendar.IllegalMonthError(month)

  `ValueError` 的子類別，當給定的月份數字超出 1-12 範圍（含）時引發。

  month

    無效的月份號。

exception calendar.IllegalWeekdayError(weekday)

  `ValueError` 的子類別，當給定的週幾的數字超出 0-6（含）範圍時引發。

  weekday

    無效的週幾編號。

也參考

`datetime` 模組

  日期與時間的物件導向介面，和 `time` 模組有相似的功能。

`time` 模組

  底層的時間相關函式。

## 命令列用法

在 2.5 版被加入.

`calendar` 模組可以作為腳本從命令列執行，並以互動方式列印日曆。

    python -m calendar [-h] [-L LOCALE] [-e ENCODING] [-t {text,html}]
                       [-w WIDTH] [-l LINES] [-s SPACING] [-m MONTHS] [-c CSS]
                       [year] [month]

例如，要列印 2000 年的日曆：

    $ python -m calendar 2000
                                      2000

          January                   February                   March
    Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
                    1  2          1  2  3  4  5  6             1  2  3  4  5
     3  4  5  6  7  8  9       7  8  9 10 11 12 13       6  7  8  9 10 11 12
    10 11 12 13 14 15 16      14 15 16 17 18 19 20      13 14 15 16 17 18 19
    17 18 19 20 21 22 23      21 22 23 24 25 26 27      20 21 22 23 24 25 26
    24 25 26 27 28 29 30      28 29                     27 28 29 30 31
    31

           April                      May                       June
    Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
                    1  2       1  2  3  4  5  6  7                1  2  3  4
     3  4  5  6  7  8  9       8  9 10 11 12 13 14       5  6  7  8  9 10 11
    10 11 12 13 14 15 16      15 16 17 18 19 20 21      12 13 14 15 16 17 18
    17 18 19 20 21 22 23      22 23 24 25 26 27 28      19 20 21 22 23 24 25
    24 25 26 27 28 29 30      29 30 31                  26 27 28 29 30

            July                     August                  September
    Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
                    1  2          1  2  3  4  5  6                   1  2  3
     3  4  5  6  7  8  9       7  8  9 10 11 12 13       4  5  6  7  8  9 10
    10 11 12 13 14 15 16      14 15 16 17 18 19 20      11 12 13 14 15 16 17
    17 18 19 20 21 22 23      21 22 23 24 25 26 27      18 19 20 21 22 23 24
    24 25 26 27 28 29 30      28 29 30 31               25 26 27 28 29 30
    31

          October                   November                  December
    Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
                       1             1  2  3  4  5                   1  2  3
     2  3  4  5  6  7  8       6  7  8  9 10 11 12       4  5  6  7  8  9 10
     9 10 11 12 13 14 15      13 14 15 16 17 18 19      11 12 13 14 15 16 17
    16 17 18 19 20 21 22      20 21 22 23 24 25 26      18 19 20 21 22 23 24
    23 24 25 26 27 28 29      27 28 29 30               25 26 27 28 29 30 31
    30 31

接受以下選項：

--help, -h

  顯示幫助訊息並退出。

--locale LOCALE, -L LOCALE

  用於月份和週幾名稱的語系。預設為英語。

--encoding ENCODING, -e ENCODING

  用於輸出的編碼。如有設定 `--locale` 則必須給定 `--encoding`。

--type {text,html}, -t {text,html}

  將日曆以文字或 HTML 文件的形式印出到終端機。

year

  印出日曆的年份。必須是 1 到 9999 之間的數字。預設為當前年份。

month

  要列印日曆的指定 `year` 的月份。必須是 1 到 12 之間的數字，並且只能在文字模式下使用。預設列印全年日曆。

文字模式選項：

--width WIDTH, -w WIDTH

  終端機行中日期行的寬度。日期印出在行的中央。任何小於 2 的值都會被忽略。預設為 2。

--lines LINES, -l LINES

  終端機列中每週的列數。日期印出時頂部會對齊。任何小於 1 的值都會被忽略。預設為 1。

--spacing SPACING, -s SPACING

  行中月份之間的間距。任何小於 2 的值都會被忽略。預設為 6。

--months MONTHS, -m MONTHS

  每列印出的月份數量。預設為 3。

HTML 模式選項：

--css CSS, -c CSS

  用於日曆的 CSS 樣式表路徑。這必須是相對於產生之 HTML 的，或者為絕對的 HTTP 或 `file:///` URL。