Understanding GTFS Calendars
Service calendars are one of the most nuanced parts of a GTFS feed. They control when transit services run — which days of the week, during what date ranges, and what happens on holidays. This guide explains how calendar.txt and calendar_dates.txt work together to define service schedules.
How service days work in GTFS
Every trip in a GTFS feed is assigned a service_id. This ID links the trip to a service calendar that defines which days the trip operates. Without this connection, a consumer application wouldn't know if a trip runs on weekdays, weekends, or only during special events.
GTFS provides two mechanisms for defining service days, and feeds can use either or both:
- calendar.txt — defines regular, repeating weekly patterns (e.g., "every Monday through Friday")
- calendar_dates.txt — defines individual date-level additions or removals (e.g., "no service on December 25" or "extra service on July 4")
A feed must include at least one of these files. Many feeds include both: calendar.txt for the base weekly pattern and calendar_dates.txt for exceptions.
Understanding calendar.txt
The calendar.txt file defines regular weekly service patterns. Each row specifies a service_id, which days of the week it operates, and the date range during which it is valid.
Structure
service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date
weekday,1,1,1,1,1,0,0,20260101,20261231
weekend,0,0,0,0,0,1,1,20260101,20261231
daily,1,1,1,1,1,1,1,20260101,20261231
Each day-of-week column uses 1 (service runs) or 0 (service does not run). In the example above:
- weekday — runs Monday through Friday, all year
- weekend — runs Saturday and Sunday only
- daily — runs every day of the week
Date ranges matter
The start_date and end_date fields define when this service pattern is active. A common pattern in GTFS feeds is to have multiple service periods — for example, a summer schedule and a winter schedule with different service IDs and date ranges. Trips reference the appropriate service ID for their season.
If today's date falls outside all start_date/end_date ranges, the feed effectively has no active service — which is a common issue with expired feeds.
Understanding calendar_dates.txt
The calendar_dates.txt file handles individual date exceptions. It either adds or removes service on specific dates, overriding the weekly pattern defined in calendar.txt.
Structure
service_id,date,exception_type
weekday,20260704,2
holiday_extra,20260704,1
weekday,20261225,2
weekday,20261226,2
The exception_type field has two values:
| Value | Meaning | Effect |
|---|---|---|
1 | Service added | Service runs on this date even if calendar.txt says it wouldn't |
2 | Service removed | Service does not run on this date even if calendar.txt says it would |
In the example above, the weekday service is removed on July 4th (Independence Day), December 25th, and December 26th. A separate holiday_extra service is added on July 4th — this might be a reduced holiday schedule with fewer trips.
Calendar_dates-only feeds
Some feeds skip calendar.txt entirely and define all service using only calendar_dates.txt with exception_type=1. Instead of saying "run every weekday," they explicitly list every individual date the service runs. This approach is common for agencies with irregular schedules or feeds generated by certain software tools.
While this works, it makes it harder to see the weekly pattern at a glance — which is one reason visualization tools are so valuable for understanding calendar data.
Service exceptions and holidays
Holidays and special events are the primary reason calendar_dates.txt exists. Here are common patterns you'll encounter:
Holiday service reductions
The most common exception: removing regular service and optionally replacing it with a reduced schedule. For example, a transit agency might cancel weekday service on Christmas Day and run a Sunday-level schedule instead:
# Remove regular weekday service on Christmas
weekday,20261225,2
# Add Sunday-level service on Christmas
sunday_service,20261225,1
Special event service
Agencies sometimes add extra service for large events — a stadium game, a parade, or a holiday fireworks show. This is handled by creating a service ID for the event and adding it via exception_type=1:
# Extra shuttle service for the marathon
marathon_shuttle,20260419,1
Seasonal schedule transitions
Feeds often have multiple service periods with overlapping or adjacent date ranges in calendar.txt. The transition between summer and fall schedules might look like this:
# Summer weekday service
summer_wd,1,1,1,1,1,0,0,20260601,20260831
# Fall weekday service
fall_wd,1,1,1,1,1,0,0,20260901,20261231
Different trips reference different service IDs, so the set of active trips changes automatically when the date moves from August 31 to September 1.
How service patterns appear in GTFS tools
Looking at raw calendar data in a spreadsheet tells you very little about the actual service patterns. Visualization tools transform this data into something meaningful:
Calendar heatmaps
A calendar heatmap displays every day in the feed's date range, colored by the amount of service running that day. You can immediately see:
- Weekday vs. weekend patterns — weekdays typically show higher service levels (darker colors) than weekends
- Holiday gaps — days with removed service stand out as lighter or empty cells
- Seasonal changes — gradual shifts in service intensity across months
- Feed validity — whether the feed covers the current date or has expired
In TransitLens, the calendar view shows a heatmap of service patterns across the entire feed date range. Each cell represents a day, and the color intensity reflects how many trips are scheduled. This makes it easy to spot anomalies — a single light-colored Tuesday in a sea of dark weekdays likely indicates a holiday exception.
Service ID breakdowns
Advanced GTFS tools let you inspect individual service IDs to understand which trips they control. This is useful when debugging feeds or verifying that a holiday schedule change was applied correctly. You can see exactly which service IDs are active on any given date and which trips belong to each one.
If you're working with a GTFS feed and want to understand its calendar structure visually, TransitLens can help you see the patterns in seconds. For more about calendar analysis alongside map views and data tables, see the GTFS Viewer page.
Visualize service calendars
Upload a GTFS feed to see calendar heatmaps, service patterns, and holiday exceptions at a glance.
Open TransitLens