USPTO Maintenance Fee Grace-Period Calculation

USPTO maintenance-fee grace-period calculation is the deterministic derivation of five dates from one grant date: the day the payment window opens six months before the anniversary, the due date at 3.5/7.5/11.5 years, the last day of the six-month grace period, the surcharge that applies during it, and the day the patent is treated as expired if still unpaid. Every one of these is fixed by rule, and every one can shift forward when it lands on a weekend or a District-of-Columbia federal holiday, so the arithmetic has to be exact and the roll rule has to be built in — not applied by hand.

This page gives the precise offsets and a single focused function that computes them, including the 37 CFR § 1.7 roll. It is the calculation detail behind the Maintenance Fee Docketing specification, and it uses the same relativedelta-based, holiday-aware conventions established in Core Docketing Architecture & Deadline Types.

Derivation of USPTO maintenance-fee dates from the grant date, with the weekend/holiday roll A vertical derivation chain of five stages down the left. Stage 1 is the input grant date. Stage 2 adds thirty-six months to open the payment window. Stage 3 adds six more months to reach the due date at 3.5, 7.5, or 11.5 years. Stage 4 adds a further six months to reach the end of the grace period at 4, 8, or 12 years. Stage 5 adds one day to reach the expiration date on which the patent is treated as expired if still unpaid. To the right, a roll-rule box applies 37 CFR 1.7(b): dashed arrows from the due-date stage and the grace-end stage feed the box, which shifts any operative date landing on a Saturday, Sunday, or District-of-Columbia federal holiday forward to the next business day, producing the effective payment dates. 1 INPUT Grant date the single base date 2 GRANT + 36 MONTHS Window opens 3 / 7 / 11 yr — 37 CFR 1.362(d) 3 + 6 MONTHS Due date 3.5 / 7.5 / 11.5 yr — no surcharge 4 + 6 MONTHS (GRACE) Grace period ends 4 / 8 / 12 yr — surcharge 1.20(h) 5 + 1 DAY Patent expires if still unpaid — 35 U.S.C. 41(b)(2) +36 mo +6 mo +6 mo +1 day ROLL RULE — 37 CFR 1.7(b) If an operative date falls on a Saturday, Sunday, or DC federal holiday, it shifts forward to the next business day (effective date). test test

The five dates, precisely

Every maintenance-fee date derives from the grant date by adding whole months, then, for the operative payment dates, applying the roll rule. Using whole-month arithmetic — not a fixed number of days — is mandatory, because months are unequal and leap years exist; dateutil.relativedelta guarantees that 31 August plus six months is 28 (or 29) February rather than an invalid date.

  • Window opens — grant + 36 / 84 / 132 months. The payment window opens six months before the due date, i.e. at exactly 3, 7, and 11 years after grant, under 37 CFR § 1.362(d). Before this date the office will not accept the fee.
  • Due date — grant + 42 / 90 / 138 months. The fee is payable without surcharge on the 3.5-, 7.5-, and 11.5-year anniversaries under 35 U.S.C. § 41(b). This is the end of the surcharge-free window, not the start.
  • Grace period ends — grant + 48 / 96 / 144 months. A six-month grace period follows the due date under 37 CFR § 1.362(e), closing at exactly 4, 8, and 12 years. The fee is still accepted here, but only with the surcharge in 37 CFR § 1.20(h).
  • Surcharge applies — throughout the grace period. Any payment made after the due date and on or before the grace deadline must include the § 1.20(h) surcharge; the base fee alone is insufficient and the payment will be treated as incomplete.
  • Expiration — the day after the last day to pay. If the fee and any surcharge are not received by the close of the (rolled) grace period, the patent is treated as expired for docketing purposes the following day, and only a petition under 37 CFR § 1.378 can revive it.

Operational Action: Compute all five dates from the single grant date with whole-month offsets, and store the nominal grace-end and the day-after expiration as distinct fields so the “still recoverable with surcharge” state is never confused with the “lapsed” state.

The weekend and holiday roll

The offsets above give nominal dates. The dates a paralegal actually works to are the effective dates after the roll rule. Under 37 CFR § 1.7(b), which restates the general principle of 35 U.S.C. § 21(b) for fee periods, if the last day of the window or the last day of the grace period falls on a Saturday, Sunday, or a federal holiday within the District of Columbia, the fee and any surcharge may be paid on the next succeeding business day.

Three details make this trickier than a naive “skip weekends” loop:

  1. DC federal holidays, not state holidays. The relevant calendar is federal holidays as observed in the District of Columbia, so a state-specific holiday does not extend a fee deadline while a federal one does.
  2. Observed dates matter. When a federal holiday falls on a Saturday it is typically observed on the preceding Friday, and when it falls on a Sunday it is observed on the following Monday. The roll must test the observed date, which a good holiday library resolves automatically.
  3. Chained shifts. Rolling off a Sunday can land on a Monday holiday, which must roll again to Tuesday. The roll therefore loops until it reaches a genuine business day, rather than stepping a single day.

Operational Action: Apply the roll only to the operative payment dates (due date and grace end), preserve the nominal date alongside the effective one for the audit record, and drive the roll from a version-pinned DC federal-holiday dataset rather than a hard-coded list.

One function that computes them all

The routine below is deliberately self-contained: given a grant date and a stage in months, it returns the nominal and effective dates for a single fee, with the roll built in. It uses the standard-library zoneinfo for a definite reference day, dateutil.relativedelta for the month offsets, and the holidays package for the DC-observed federal calendar. The roll loops so chained shifts resolve correctly.

from __future__ import annotations

from dataclasses import dataclass
from datetime import date, timedelta

import holidays
from dateutil.relativedelta import relativedelta

# Months from the grant date to each maintenance-fee due date.
VALID_STAGES: frozenset[int] = frozenset({42, 90, 138})  # 3.5 / 7.5 / 11.5 yr


def _roll_forward(d: date, cal: holidays.HolidayBase) -> date:
    """Shift a date off Saturdays, Sundays, and DC federal holidays.

    Loops so a Sunday that rolls onto a Monday holiday shifts again
    (37 CFR 1.7(b); 35 U.S.C. 21(b))."""
    while d.weekday() >= 5 or d in cal:  # 5 = Saturday, 6 = Sunday
        d += timedelta(days=1)
    return d


@dataclass(frozen=True)
class FeeDates:
    window_opens: date          # grant + 36 months (37 CFR 1.362(d))
    due_date: date              # nominal 3.5 / 7.5 / 11.5 yr
    due_date_effective: date    # after the 37 CFR 1.7(b) roll
    grace_ends: date            # nominal 4 / 8 / 12 yr
    grace_ends_effective: date  # after the roll — the true last day to pay
    expiration: date            # day after the effective grace deadline


def maintenance_fee_dates(grant_date: date, stage_months: int) -> FeeDates:
    """Compute every date for one USPTO maintenance fee, roll included."""
    if stage_months not in VALID_STAGES:
        raise ValueError("stage_months must be 42, 90, or 138 (3.5/7.5/11.5 yr)")

    due = grant_date + relativedelta(months=stage_months)
    opens = due - relativedelta(months=6)      # window opens six months earlier
    grace_ends = due + relativedelta(months=6)  # grace closes six months later

    # Bound the holiday lookup to every year a date can land in.
    dc = holidays.US(years=range(grant_date.year, grace_ends.year + 2))

    grace_effective = _roll_forward(grace_ends, dc)
    return FeeDates(
        window_opens=opens,
        due_date=due,
        due_date_effective=_roll_forward(due, dc),
        grace_ends=grace_ends,
        grace_ends_effective=grace_effective,
        # The patent is treated as expired the day after the last day to pay.
        expiration=grace_effective + timedelta(days=1),
    )

The function returns both nominal and effective dates for the two operative deadlines so the audit record can show why an effective date moved. Note that holidays.US resolves observed dates automatically, so a Fourth of July that falls on a Saturday and is observed on the preceding Friday is handled without special-casing. The window-open date is left un-rolled because it only governs the earliest acceptance point, not a deadline a miss can forfeit.

Operational Action: Return nominal and effective dates as separate fields, feed the reminder cadence off grace_ends_effective, and pin the holidays dataset version in the audit record so a later library update cannot silently re-date a historical calculation.

Worked examples and edge cases

Concrete inputs expose the traps that abstract offsets hide:

Grant date Stage Nominal due Nominal grace end Note
2022-02-15 3.5 yr 2025-08-15 2026-02-15 Clean anniversary; roll only if either lands on a weekend/holiday
2021-08-31 3.5 yr 2025-02-28 2025-08-31 31 Aug + 6 months clamps to 28 Feb (non-leap); relativedelta handles it
2020-02-29 7.5 yr 2027-08-29 2028-02-29 Leap-day grant; grace end lands on a valid leap day in 2028
2023-01-04 3.5 yr 2026-07-04 2027-01-04 Nominal due 4 July is a federal holiday; effective due rolls forward

The 2021-08-31 row is the canonical reason a fixed-day offset fails: adding 182 or 183 days instead of six calendar months drifts the date and, across a portfolio, eventually mis-dates a fee by a day near a month boundary. The 2023-01-04 row shows the roll in action — a nominal 4 July due date is a federal holiday, so the effective date shifts to 5 July, or later if the 5th is a weekend. And a grace deadline that lands on a Sunday before a Monday federal holiday demonstrates the chained shift the loop exists to handle.

Operational Action: Seed the regression suite with a month-end clamp case, a leap-day case, a holiday-roll case, and a chained-shift case, asserting exact dates, so any change to the offset logic or holiday table is caught immediately.

Verification

A grace-period calculator is only trustworthy if it is pinned to known-good outputs. Assert the full FeeDates tuple for a fixed grant date, cross-check effective dates against the USPTO’s own fee-due display for a sample of real patents, and re-run the suite whenever the holiday dataset changes. Because the calculation is pure and deterministic, the same grant date and stage must always yield the same six dates — a property the audit ledger relies on when a computation is reconstructed years later. The classification of the resulting dates into deadline categories, and their sealing into the ledger, follow the conventions in Core Docketing Architecture & Deadline Types.

Frequently Asked Questions

Does the six-month payment window open before or after the due date?
Before. The window opens six months before the due date — at 3, 7, and 11 years after grant under 37 CFR § 1.362(d) — and the 3.5-, 7.5-, and 11.5-year anniversaries are the last day to pay without a surcharge, not the first. The six-month grace period then runs after the due date, so each fee has a full year in which some form of payment is accepted.
What happens if the last day of the grace period falls on a weekend or federal holiday?
Under 37 CFR § 1.7(b) the deadline rolls to the next succeeding business day, so a grace period ending on a Saturday can be met on the following Monday, or Tuesday if the Monday is a federal holiday. The roll uses federal holidays observed in the District of Columbia, resolves observed dates, and loops so a chained weekend-then-holiday shift lands on a genuine business day.
Why use relativedelta instead of adding a fixed number of days?
Because months are unequal and leap years exist. Adding a fixed 182 or 183 days drifts across month boundaries and mis-dates fees, while dateutil.relativedelta adds whole calendar months correctly — clamping 31 August plus six months to the last valid day of February, for example — so the anniversary logic the statute describes is reproduced exactly.
Is the patent expiration date the same as the grace period end date?
No. The grace period end is the last day the fee plus surcharge can be paid; if payment is not received, the patent is treated as expired the following day. Keeping the effective grace end and the day-after expiration as distinct fields prevents confusing the still-recoverable "grace" state with the "lapsed" state that requires a 37 CFR § 1.378 petition to escape.

↑ Back to Maintenance Fee Docketing