pandas_market_calendars provides exchange schedules for pandas-based trading and time-series workflows. The official pandas_market_calendars documentation describes calendars for exchange holidays, late opens, early closes, breaks, and open-market date ranges.
Quick Answer
Use pandas_market_calendars when weekday-only date logic is not enough. Select an exchange with get_calendar(), create a schedule with start and end dates, and inspect the resulting market_open and market_close columns before generating a date range.

The current PyPI package page lists the project as a market and exchange trading-calendar package for pandas and requires modern Python. The documentation also notes that calendar rules ship with the installed package; it does not request live market hours from a server at runtime.
Use this package when regular business-day logic is not enough. A generic weekday calendar does not know about exchange holidays, early closes, lunch breaks, or futures-market sessions.
Always treat the installed package version as part of the analysis. If an exchange updates a holiday or special session rule, you may need a newer package release or a project-specific override.
This is especially important for backtests, reports, and compliance workflows. Two analysts can get different answers if they generate sessions from different package versions or different exchange calendars.
Install And Import The Package
The package is installed with pip and imported as pandas_market_calendars. Most examples shorten it to mcal.
import pandas_market_calendars as mcal
calendar_names = mcal.get_calendar_names()
print("NYSE" in calendar_names)
print(len(calendar_names))
get_calendar_names() is a quick way to confirm that the calendar you plan to use is available in the installed version.
Calendar names are identifiers, not investment recommendations. Choose the calendar that matches the data source and trading venue used in your analysis.
If a data vendor uses a custom session calendar, compare it against the package calendar before assuming both use the same holidays and close times.

Get An Exchange Schedule
A calendar object can produce a schedule with market open and market close timestamps for a date range.
import pandas_market_calendars as mcal
nyse = mcal.get_calendar("NYSE")
schedule = nyse.schedule(start_date="2026-01-02", end_date="2026-01-09")
print(schedule[["market_open", "market_close"]])
The schedule index contains trading dates, and the columns contain timezone-aware open and close times. This is more precise than assuming every weekday is open.
Use a short date range while checking a new calendar, then expand the range after the output shape and timezone behavior are clear.
Schedules are usually best kept as source data in the pipeline. Downstream joins, resampling, and missing-session checks can all reuse the same schedule.
Create Open-Market Date Ranges
The package includes date_range() for generating timestamps during market-open periods from a schedule.
import pandas_market_calendars as mcal
nyse = mcal.get_calendar("NYSE")
schedule = nyse.schedule(start_date="2026-01-02", end_date="2026-01-05")
timestamps = mcal.date_range(schedule, frequency="1H")
print(timestamps[:5])
This is useful when resampling intraday data or building a timeline that should avoid closed sessions.
Check the resulting timezone before joining with price, order, or event data. Timezone mismatches are a common source of off-by-one-session errors.
When building bars, make sure the timestamp convention matches your data. Some datasets label bars by open time, while others use close time.

Check Holidays And Valid Sessions
The calendar can expose holidays and valid trading days for a range. This helps when validating input data before backtesting or reporting. Use valid_days() to identify expected sessions, not to infer future exchange decisions beyond the package rules you have installed. Trading calendars define valid sessions; Zipline Python Guide for Backtesting Strategies shows how Zipline uses market data, calendars, pipelines, and backtests without implying live-trading readiness.
If your workflow depends on corrected market hours, record the package version beside the generated schedule.
Valid-session checks are also useful for quality control. A price row on a non-session date may be a holiday adjustment, bad input, or data from another venue.

Handle Early Closes
Early closes appear in the schedule as different close times. You can compare each close against the usual close for your analysis.
import pandas_market_calendars as mcal
nyse = mcal.get_calendar("NYSE")
schedule = nyse.schedule(start_date="2026-11-20", end_date="2026-11-30")
close_times = schedule["market_close"]
print(close_times)
The exact early-close dates depend on the calendar rules in the package version. Do not hard-code early closes if the calendar can provide them.
When combining multiple exchanges, keep each exchange schedule separate until you intentionally merge them.
Early-close logic is easy to miss in daily systems because the date still appears as a valid session. Inspect the open and close columns, not only the index.
Compare Two Calendars
Different exchanges may have different holidays, timezones, and session structures. Compare valid days before joining datasets from multiple venues.
import pandas_market_calendars as mcal
nyse = mcal.get_calendar("NYSE")
lse = mcal.get_calendar("LSE")
nyse_days = set(nyse.valid_days("2026-01-01", "2026-01-15").date)
lse_days = set(lse.valid_days("2026-01-01", "2026-01-15").date)
print(sorted(nyse_days - lse_days))
print(sorted(lse_days - nyse_days))
This kind of check prevents silent gaps when one market is open and another is closed.
If the analysis uses one calendar as the master timeline, document that choice. A master calendar can drop sessions from the other market if the join is not designed carefully.

Store Schedules For Reproducibility
For repeatable analysis, generate schedules once, inspect them, and store the package version with the output.
from importlib.metadata import version
import pandas_market_calendars as mcal
nyse = mcal.get_calendar("NYSE")
schedule = nyse.schedule("2026-01-01", "2026-01-31")
print(version("pandas_market_calendars"))
print(schedule.shape)
The key point is that exchange calendars are data as well as code. Keep the version, calendar name, date range, timezone handling, and any local overrides close to the results they produce.
For one-off notebooks, printing the version may be enough. For automated jobs, write it into logs or output metadata so later reviews can reproduce the same session list.
Version, Timezone, and Reproducibility Checks
Trading schedules are data, not just formatting. Record the package version, calendar name, date range, and timezone with every generated schedule so a backtest or report can be reproduced later.
import pandas_market_calendars as mcal
from importlib.metadata import version
calendar_name = "NYSE"
calendar = mcal.get_calendar(calendar_name)
schedule = calendar.schedule(
start_date="2025-01-01",
end_date="2025-01-10",
)
print("package", version("pandas_market_calendars"))
print("calendar", calendar_name)
print(schedule.tz_convert("America/New_York"))
Use the exchange timezone when presenting results to readers. A schedule stored in UTC can be correct while still looking confusing if it is displayed as local market time without conversion.
Frequently Asked Questions
What does pandas_market_calendars provide?
It provides exchange-aware calendars and schedules that account for market holidays, late opens, early closes, and some intraday breaks.
How do I create a market schedule?
Call mcal.get_calendar() with an exchange name such as NYSE, then call schedule() with a start_date and end_date.
Why not use pandas business days?
Generic business-day rules do not know the special holidays, half-days, or session breaks of a specific exchange.
Should I convert the schedule timezone?
Yes. Keep the library output consistent for calculations, then convert to the exchange or reader timezone when displaying or exporting results.