# `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` 實例有以下方法與屬性：

  firstweekday

    The first weekday as an integer (0--6).

    This property can also be set and read using `setfirstweekday()` and `getfirstweekday()` respectively.

  getfirstweekday()

    Return an `int` for the current first weekday (0--6).

    Identical to reading the `firstweekday` property.

  setfirstweekday(firstweekday)

    Set the first weekday to firstweekday, passed as an `int` (0--6)

    Identical to setting the `firstweekday` property.

  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` 實例有以下方法：

  formatday(theday, weekday, width)

    Return a string representing a single day formatted with the given width. If theday is `0`, return a string of spaces of the specified width, representing an empty day. The weekday parameter is unused.

  formatweek(theweek, w=0)

    Return a single week in a string with no newline. If w is provided, it specifies the width of the date columns, which are centered. Depends on the first weekday as specified in the constructor or set by the `setfirstweekday()` method.

  formatweekday(weekday, width)

    Return a string representing the name of a single weekday formatted to the specified width. The weekday parameter is an integer representing the day of the week, where `0` is Monday and `6` is Sunday.

  formatweekheader(width)

    Return a string containing the header row of weekday names, formatted with the given width for each column. The names depend on the locale settings and are padded to the specified width.

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

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

  formatmonthname(theyear, themonth, width=0, withyear=True)

    Return a string representing the month's name centered within the specified width. If withyear is `True`, include the year in the output. The theyear and themonth parameters specify the year and month for the name to be formatted respectively.

  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

  以目前語系來表示的一週每一天名稱的序列，其中週一是第 0 天。

      >>> import calendar
      >>> list(calendar.day_name)
      ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

calendar.day_abbr

  以目前語系來表示的一週每一天縮寫名稱的序列，其中 Mon 是第 0 天。

      >>> import calendar
      >>> list(calendar.day_abbr)
      ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']

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]` 是空字串。

      >>> import calendar
      >>> list(calendar.month_name)
      ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']

calendar.month_abbr

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

      >>> import calendar
      >>> list(calendar.month_abbr)
      ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

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` 是 `1` 而 `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]
                       [-f FIRST_WEEKDAY] [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 文件的形式印出到終端機。

--first-weekday FIRST_WEEKDAY, -f FIRST_WEEKDAY

  一週起始的日子。必須是 0（週一）到 6（週日）之間的數字。預設為 0。

  在 3.13 版被加入.

year

  印出日曆的年份。預設為目前年份。

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。

在 3.14 版的變更: By default, today's date is highlighted in color and can be controlled using environment variables.

HTML 模式選項：

--css CSS, -c CSS

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