Claude Code for calendar: Python Calendar Utilities — Claude Skills 360 Blog
Blog / AI / Claude Code for calendar: Python Calendar Utilities
AI

Claude Code for calendar: Python Calendar Utilities

Published: August 19, 2028
Read time: 5 min read
By: Claude Skills 360

Python’s calendar module provides calendar computations and text/HTML rendering. import calendar. month: calendar.month(year, month, w=0, l=0) → text calendar string for one month. monthcalendar: calendar.monthcalendar(year, month) → list of weeks; each week is a list of 7 ints (0 = day outside month). monthrange: calendar.monthrange(year, month)(weekday_of_first, num_days); weekday 0=Monday…6=Sunday. isleap: calendar.isleap(year) → bool. leapdays: calendar.leapdays(y1, y2) → count of leap years in [y1, y2). weekday: calendar.weekday(year, month, day) → 0=Monday…6=Sunday. weekheader: calendar.weekheader(n) → abbreviated weekday header string of width n. calendar func: calendar.calendar(year) → full year as text. HTMLCalendar: calendar.HTMLCalendar(firstweekday=0).formatmonth(year, month) / .formatyear(year). TextCalendar: calendar.TextCalendar(firstweekday=0). setfirstweekday: calendar.setfirstweekday(6) — set Sunday as first day. timegm: calendar.timegm(struct_time) → UTC epoch (unlike time.mktime which uses local time). day_name: list(calendar.day_name) → [‘Monday’, …, ‘Sunday’]. day_abbr: abbreviated 3-letter names. month_name: list(calendar.month_name)['', 'January', ..., 'December'] (index 0 is empty string). month_abbr: abbreviated. Claude Code generates appointment calendars, fiscal week analyzers, availability grids, and date range iterators.

CLAUDE.md for calendar

## calendar Stack
- Stdlib: import calendar
- Range:   first_wd, ndays = calendar.monthrange(year, month)
- Weeks:   calendar.monthcalendar(year, month)  # list of 7-item week rows
- Leap:    calendar.isleap(year)
- WkDay:   calendar.weekday(y, m, d)  # 0=Mon…6=Sun
- Epoch:   calendar.timegm(struct_time)  # UTC (not local)
- Names:   calendar.day_name[0]   # "Monday"
-          calendar.month_name[1] # "January"

calendar Date and Calendar Pipeline

# app/calutil.py — month grids, ranges, availability, fiscal, holidays
from __future__ import annotations

import calendar
import datetime
from dataclasses import dataclass
from typing import Iterator


# Alias Weekday constants for readability
MON, TUE, WED, THU, FRI, SAT, SUN = range(7)
WEEKDAYS = {MON, TUE, WED, THU, FRI}
WEEKEND  = {SAT, SUN}


# ─────────────────────────────────────────────────────────────────────────────
# 1. Month and year metadata
# ─────────────────────────────────────────────────────────────────────────────

def month_days(year: int, month: int) -> int:
    """
    Return the number of days in a given month.

    Example:
        month_days(2024, 2)  # 29 (leap year)
        month_days(2025, 2)  # 28
    """
    _, n = calendar.monthrange(year, month)
    return n


def first_weekday(year: int, month: int) -> int:
    """
    Return the weekday of the 1st of the month (0=Monday, 6=Sunday).

    Example:
        first_weekday(2025, 1)  # 2  (Wednesday)
    """
    wd, _ = calendar.monthrange(year, month)
    return wd


def is_leap(year: int) -> bool:
    """Return True if year is a leap year."""
    return calendar.isleap(year)


def leap_years(start: int, end: int) -> list[int]:
    """
    Return list of leap years in [start, end] inclusive.

    Example:
        leap_years(2020, 2032)  # [2020, 2024, 2028, 2032]
    """
    return [y for y in range(start, end + 1) if calendar.isleap(y)]


def weekday_name(wd: int, abbr: bool = False) -> str:
    """
    Return the name for a weekday integer (0=Monday).

    Example:
        weekday_name(0)          # "Monday"
        weekday_name(4, abbr=True) # "Fri"
    """
    seq = calendar.day_abbr if abbr else calendar.day_name
    return seq[wd]


def month_name(month: int, abbr: bool = False) -> str:
    """
    Return the name for a month integer (1=January).

    Example:
        month_name(1)         # "January"
        month_name(12, True)  # "Dec"
    """
    seq = calendar.month_abbr if abbr else calendar.month_name
    return seq[month]


# ─────────────────────────────────────────────────────────────────────────────
# 2. Date iteration
# ─────────────────────────────────────────────────────────────────────────────

def iter_month_dates(year: int, month: int) -> Iterator[datetime.date]:
    """
    Yield every date in the given month as datetime.date objects.

    Example:
        fridays = [d for d in iter_month_dates(2025, 3) if d.weekday() == FRI]
    """
    _, n = calendar.monthrange(year, month)
    for day in range(1, n + 1):
        yield datetime.date(year, month, day)


def iter_weekdays_in_month(year: int, month: int, weekday: int) -> list[datetime.date]:
    """
    Return all dates in the month that fall on the given weekday.

    Example:
        mondays = iter_weekdays_in_month(2025, 1, MON)
    """
    return [d for d in iter_month_dates(year, month) if d.weekday() == weekday]


def iter_date_range(start: datetime.date, end: datetime.date) -> Iterator[datetime.date]:
    """
    Yield each date from start to end inclusive.

    Example:
        for d in iter_date_range(datetime.date(2025,1,1), datetime.date(2025,1,7)):
            print(d)
    """
    current = start
    step = datetime.timedelta(days=1)
    while current <= end:
        yield current
        current += step


def business_days_in_month(year: int, month: int, holidays: set[datetime.date] | None = None) -> int:
    """
    Count Mon–Fri days in a month, excluding any provided holiday dates.

    Example:
        business_days_in_month(2025, 1)   # 23
    """
    skip = holidays or set()
    return sum(
        1 for d in iter_month_dates(year, month)
        if d.weekday() in WEEKDAYS and d not in skip
    )


def nth_weekday_of_month(year: int, month: int, weekday: int, n: int) -> datetime.date:
    """
    Return the nth occurrence (1-based) of `weekday` in the given month.
    Use n=-1 for the last occurrence.

    Example:
        # 3rd Monday in January 2025
        nth_weekday_of_month(2025, 1, MON, 3)
        # Last Friday in December 2025
        nth_weekday_of_month(2025, 12, FRI, -1)
    """
    days = iter_weekdays_in_month(year, month, weekday)
    if not days:
        raise ValueError(f"No weekday {weekday} in {year}-{month:02d}")
    if n == -1:
        return days[-1]
    if n < 1 or n > len(days):
        raise IndexError(f"Only {len(days)} occurrences of weekday {weekday}")
    return days[n - 1]


# ─────────────────────────────────────────────────────────────────────────────
# 3. Week grid
# ─────────────────────────────────────────────────────────────────────────────

@dataclass
class MonthGrid:
    """
    A structured representation of a month's calendar, week by week.

    Attributes:
        year, month: integers
        weeks: list of 7-int lists; 0 means padding outside the month
    """
    year:  int
    month: int
    weeks: list[list[int]]

    @classmethod
    def build(cls, year: int, month: int, firstweekday: int = MON) -> "MonthGrid":
        """
        Build a MonthGrid for the given year/month.

        Example:
            grid = MonthGrid.build(2025, 2)
            for week in grid.weeks:
                print(week)
        """
        cal = calendar.Calendar(firstweekday)
        return cls(year=year, month=month, weeks=cal.monthdayscalendar(year, month))

    def all_days(self) -> list[int]:
        """Return a flat list of all day numbers (0 = outside month)."""
        return [d for week in self.weeks for d in week]

    def real_days(self) -> list[int]:
        """Return only the non-zero day numbers."""
        return [d for d in self.all_days() if d]

    def week_of(self, day: int) -> int:
        """Return 0-based week index containing the given day number."""
        for i, week in enumerate(self.weeks):
            if day in week:
                return i
        raise ValueError(f"Day {day} not in {self.year}-{self.month:02d}")

    def to_text(self) -> str:
        """Return a simple text representation of the grid."""
        header = calendar.weekheader(3)
        lines = [f"{month_name(self.month)} {self.year}", header]
        for week in self.weeks:
            lines.append(" ".join(f"{d:3d}" if d else "   " for d in week))
        return "\n".join(lines)


# ─────────────────────────────────────────────────────────────────────────────
# 4. Fiscal calendar helpers
# ─────────────────────────────────────────────────────────────────────────────

def fiscal_quarter(month: int, fiscal_year_start: int = 1) -> int:
    """
    Return fiscal quarter (1–4) for a calendar month number.
    fiscal_year_start: 1=Jan (default), 4=Apr (UK), 7=Jul (Australia), 10=Oct (US federal).

    Example:
        fiscal_quarter(3, fiscal_year_start=1)   # 1 (Q1 Jan–Mar)
        fiscal_quarter(3, fiscal_year_start=10)  # 2 (Q2 Jan–Mar in Oct FY)
    """
    offset = (month - fiscal_year_start) % 12
    return offset // 3 + 1


def quarter_months(quarter: int, fiscal_year_start: int = 1) -> list[int]:
    """
    Return the three month numbers in a given fiscal quarter.

    Example:
        quarter_months(1)               # [1, 2, 3]
        quarter_months(1, fiscal_year_start=4)  # [4, 5, 6]
    """
    start_offset = (quarter - 1) * 3
    return [((fiscal_year_start - 1 + start_offset + i) % 12) + 1 for i in range(3)]


def iso_week_number(d: datetime.date) -> int:
    """
    Return the ISO week number (1–53) for a date.

    Example:
        iso_week_number(datetime.date(2025, 1, 1))  # 1
    """
    return d.isocalendar()[1]


def months_between(start: datetime.date, end: datetime.date) -> int:
    """
    Return the number of complete calendar months from start to end.

    Example:
        months_between(datetime.date(2025,1,15), datetime.date(2025,6,15))  # 5
    """
    return (end.year - start.year) * 12 + (end.month - start.month)


# ─────────────────────────────────────────────────────────────────────────────
# 5. Availability and schedule
# ─────────────────────────────────────────────────────────────────────────────

@dataclass
class Availability:
    """
    Track which days of a month are available (True) or blocked (False).

    Example:
        avail = Availability.full_month(2025, 3)
        avail.block_weekends()
        avail.block_day(datetime.date(2025, 3, 17))  # block a holiday
        free = avail.free_days()
    """
    year:  int
    month: int
    days:  dict[int, bool]  # day_number → available

    @classmethod
    def full_month(cls, year: int, month: int) -> "Availability":
        _, n = calendar.monthrange(year, month)
        return cls(year=year, month=month, days={d: True for d in range(1, n + 1)})

    def block_weekends(self) -> None:
        for d in list(self.days):
            date = datetime.date(self.year, self.month, d)
            if date.weekday() in WEEKEND:
                self.days[d] = False

    def block_day(self, date: datetime.date) -> None:
        if date.year == self.year and date.month == self.month:
            self.days[date.day] = False

    def free_days(self) -> list[int]:
        return [d for d, avail in sorted(self.days.items()) if avail]

    def free_count(self) -> int:
        return sum(1 for v in self.days.values() if v)

    def utilization(self) -> float:
        total = len(self.days)
        return (total - self.free_count()) / total if total else 0.0


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    print("=== calendar demo ===")

    print("\n--- month metadata ---")
    print(f"  month_days(2024, 2)     = {month_days(2024, 2)}")
    print(f"  month_days(2025, 2)     = {month_days(2025, 2)}")
    print(f"  is_leap(2024)           = {is_leap(2024)}")
    print(f"  first_weekday(2025, 1)  = {first_weekday(2025, 1)} ({weekday_name(first_weekday(2025,1))})")
    print(f"  leap_years(2020,2032)   = {leap_years(2020, 2032)}")

    print("\n--- day/month names ---")
    print(f"  day_name                = {list(calendar.day_name)}")
    print(f"  month_name(6)           = {month_name(6)}")
    print(f"  month_name(6, abbr=True)= {month_name(6, abbr=True)}")

    print("\n--- iter_weekdays_in_month ---")
    mondays_jan = iter_weekdays_in_month(2025, 1, MON)
    print(f"  Mondays in Jan 2025: {[d.day for d in mondays_jan]}")

    print("\n--- nth_weekday_of_month ---")
    thanks = nth_weekday_of_month(2025, 11, THU, 4)
    print(f"  4th Thursday Nov 2025 (US Thanksgiving): {thanks}")
    last_fri = nth_weekday_of_month(2025, 12, FRI, -1)
    print(f"  Last Friday Dec 2025: {last_fri}")

    print("\n--- business_days_in_month ---")
    print(f"  Business days Jan 2025: {business_days_in_month(2025, 1)}")
    print(f"  Business days Feb 2025: {business_days_in_month(2025, 2)}")

    print("\n--- MonthGrid ---")
    grid = MonthGrid.build(2025, 2)
    print(grid.to_text())
    print(f"  real_days count: {len(grid.real_days())}")
    print(f"  week_of(14): {grid.week_of(14)}")

    print("\n--- fiscal_quarter ---")
    for m in range(1, 13):
        print(f"  month {m:2d}: Q{fiscal_quarter(m)}  Oct-FY Q{fiscal_quarter(m, 10)}")

    print("\n--- quarter_months ---")
    for q in range(1, 5):
        print(f"  Q{q}: {quarter_months(q)}")

    print("\n--- iso_week_number ---")
    d = datetime.date(2025, 12, 31)
    print(f"  ISO week of {d}: {iso_week_number(d)}")

    print("\n--- months_between ---")
    start = datetime.date(2025, 1, 15)
    end   = datetime.date(2025, 8, 14)
    print(f"  months_between({start}, {end}) = {months_between(start, end)}")

    print("\n--- Availability ---")
    avail = Availability.full_month(2025, 3)
    avail.block_weekends()
    avail.block_day(datetime.date(2025, 3, 17))
    print(f"  free days in Mar 2025 (no weekends, -Mar17): {avail.free_days()}")
    print(f"  free count: {avail.free_count()}")
    print(f"  utilization (blocked): {avail.utilization():.0%}")

    print("\n--- calendar.timegm (UTC epoch) ---")
    import time
    st = time.strptime("2025-01-01 00:00:00", "%Y-%m-%d %H:%M:%S")
    print(f"  calendar.timegm('2025-01-01') = {calendar.timegm(st)}")

    print("\n=== done ===")

For the datetime alternative — datetime.date provides rich date objects with timedelta arithmetic, ISO formatting, and strptime/strftime; the calendar module provides calendar-grid computations (week arrays, weekday offsets, leap logic, month ranges) that would be tedious with datetime alone — use datetime as the primary date type for comparisons, arithmetic, and ISO formatting; use calendar functions like monthrange(), monthcalendar(), and timegm() for grid layout, iteration scaffolding, and the UTC-correct epoch conversion that time.mktime() cannot provide. For the dateutil alternative — dateutil (PyPI) adds recurrence rules (rrule), fuzzy date parsing, relativedelta for month/year arithmetic, and full IANA timezone database support; calendar covers only the built-in stdlib subset with no external dependencies — use dateutil for advanced scheduling (every third Tuesday, monthly on the last day), fuzzy natural-language date parsing, or IANA timezone handling in production applications; use calendar for lightweight calendar grid rendering, fiscal quarter math, and scripts where adding a PyPI dependency is undesirable. The Claude Skills 360 bundle includes calendar skill sets covering month_days()/first_weekday()/is_leap()/leap_years()/weekday_name()/month_name() metadata helpers, iter_month_dates()/iter_weekdays_in_month()/iter_date_range()/business_days_in_month()/nth_weekday_of_month() date iteration tools, MonthGrid.build() with to_text()/week_of()/real_days(), fiscal_quarter()/quarter_months()/iso_week_number()/months_between() fiscal helpers, and Availability class with block_weekends()/block_day()/free_days()/utilization(). Start with the free tier to try calendar grid generation patterns and calendar module pipeline code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free