Skip to content
Merged
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
94d15cb
Added timeframes
omar-kabbani Aug 4, 2022
bfc2b12
Add date-based fares
omar-kabbani Aug 5, 2022
713e91c
Update timeframes.txt description
Nov 14, 2022
5a8ca38
Change end time from required to optional
Nov 14, 2022
0b7c9e2
Records with the same timeframe id must cover a 24h period
Nov 14, 2022
fd2eb13
no overlap
Nov 14, 2022
991ccba
remove requirement on 24h coverage and overlapping
Nov 15, 2022
d2e89a6
fix typo
isabelle-dr Nov 21, 2022
710be10
Revert changes in timeframes.end_time
isabelle-dr Nov 23, 2022
f9a4a1d
move service_id to timeframes.txt
Mar 10, 2023
84da99f
Move timeframes to the fares v2 section
Mar 10, 2023
b8aad98
rename timeframe_id to timeframe_group_id
Mar 10, 2023
438dbf2
Merge branch 'master' into GTFS-Fares-v2-time-variable-fares
Mar 15, 2023
d68c3fd
place timeframes.txt with other Fares v2 files
Mar 15, 2023
50e60c8
Rename from/to fields + change empty semantics
Mar 21, 2023
d42bfdf
add line break
Mar 21, 2023
50a080d
Add timeframes description
Mar 23, 2023
19dae72
Make timeframe fields required
Mar 23, 2023
0222fff
service_id references calendar or calendar_dates
Mar 23, 2023
27f5c06
Add requirements
Mar 23, 2023
9bd26d0
typo
Mar 23, 2023
acd9d0d
Update timeframe fields description
Apr 4, 2023
a182e6c
end time is not included in the interval
Apr 4, 2023
e8463ce
Add timeframe_type field
Apr 4, 2023
477ab30
Overlapping time frames must not be defined
Apr 5, 2023
c34bfed
introduce override
Apr 5, 2023
d4afc6e
improve override description
Apr 7, 2023
55679c9
Revert "improve override description"
Apr 7, 2023
189822f
improve override description
Apr 7, 2023
f0e18a8
update timeframe fields description
Apr 7, 2023
0aedadc
remove timeframe fields for no exact matched found
Apr 11, 2023
91bda27
Update descriptions for empty values:
Apr 11, 2023
af4b67b
Both values need to be empty or neither should be empty
May 24, 2023
fe45e7e
Change to local time semantics
May 24, 2023
045258f
Changed name start/end_timeframe_group_id
tzujenchanmbd May 24, 2023
ad54f36
Remove timeframe_type & priority fields
tzujenchanmbd May 24, 2023
518578b
revise "start" to "end"
tzujenchanmbd May 25, 2023
f33a935
Remove "initial" after Gavriel's comment
Jun 25, 2023
4bf749f
Remove unnecessary empty description
tzujenchanmbd Jul 19, 2023
0007c89
Changes based on Jeremy's feedback
tzujenchanmbd Jul 20, 2023
1a65d75
Modify empty wording
tzujenchanmbd Jul 20, 2023
12c3bb7
Move overlapping requirement out of service_id description
Jul 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions gtfs/spec/en/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ This document defines the format and structure of the files that comprise a GTFS
- [calendar\_dates.txt](#calendar_datestxt)
- [fare\_attributes.txt](#fare_attributestxt)
- [fare\_rules.txt](#fare_rulestxt)
- [timeframes.txt](#timeframestxt)
- [fare\_media.txt](#fare_mediatxt)
- [fare\_products.txt](#fare_productstxt)
- [fare\_leg\_rules.txt](#fare_leg_rulestxt)
Expand Down Expand Up @@ -110,6 +111,7 @@ This specification defines the following files:
| [calendar_dates.txt](#calendar_datestxt) | **Conditionally Required** | Exceptions for the services defined in the [calendar.txt](#calendartxt). <br><br>Conditionally Required:<br> - **Required** if [calendar.txt](#calendartxt) is omitted. In which case [calendar_dates.txt](#calendar_datestxt) must contain all dates of service. <br> - Optional otherwise. |
| [fare_attributes.txt](#fare_attributestxt) | Optional | Fare information for a transit agency's routes. |
| [fare_rules.txt](#fare_rulestxt) | Optional | Rules to apply fares for itineraries. |
| [timeframes.txt](#timeframestxt) | Optional | Date and time periods to use in fare rules for fares that depend on date and time factors. |
| [fare_media.txt](#fare_mediatxt) | Optional | To describe the fare media that can be employed to use fare products. <br><br>File [fare_media.txt](#fare_mediatxt) describes concepts that are not represented in [fare_attributes.txt](#fare_attributestxt) and [fare_rules.txt](#fare_rulestxt). As such, the use of [fare_media.txt](#fare_mediatxt) is entirely separate from files [fare_attributes.txt](#fare_attributestxt) and [fare_rules.txt](#fare_rulestxt). |
| [fare_products.txt](#fare_productstxt) | Optional | To describe the different types of tickets or fares that can be purchased by riders.<br><br>File [fare_products.txt](#fare_productstxt) describes fare products that are not represented in [fare_attributes.txt](#fare_attributestxt) and [fare_rules.txt](#fare_rulestxt). As such, the use of [fare_products.txt](#fare_productstxt) is entirely separate from files [fare_attributes.txt](#fare_attributestxt) and [fare_rules.txt](#fare_rulestxt). |
| [fare_leg_rules.txt](#fare_leg_rulestxt) | Optional | Fare rules for individual legs of travel.<br><br>File [fare_leg_rules.txt](#fare_leg_rulestxt) provides a more detailed method for modeling fare structures. As such, the use of [fare_leg_rules.txt](#fare_leg_rulestxt) is entirely separate from files [fare_attributes.txt](#fare_attributestxt) and [fare_rules.txt](#fare_rulestxt). |
Expand Down Expand Up @@ -345,6 +347,27 @@ For examples that demonstrate how to specify a fare structure with [fare_rules.t
| `destination_id` | Foreign ID referencing `stops.zone_id` | Optional | Identifies a destination zone. If a fare class has multiple destination zones, create a record in [fare_rules.txt](#fare_rules.txt) for each `destination_id`.<hr>*Example: The `origin_id` and `destination_id` fields could be used together to specify that fare class "b" is valid for travel between zones 3 and 4, and for travel between zones 3 and 5, the [fare_rules.txt](#fare_rules.txt) file would contain these records for the fare class:* <br>`fare_id,...,origin_id,destination_id` <br>`b,...,3,4`<br> `b,...,3,5` |
| `contains_id` | Foreign ID referencing `stops.zone_id` | Optional | Identifies the zones that a rider will enter while using a given fare class. Used in some systems to calculate correct fare class. <hr>*Example: If fare class "c" is associated with all travel on the GRT route that passes through zones 5, 6, and 7 the [fare_rules.txt](#fare_rules.txt) would contain these records:* <br> `fare_id,route_id,...,contains_id` <br> `c,GRT,...,5` <br>`c,GRT,...,6` <br>`c,GRT,...,7` <br> *Because all `contains_id` zones must be matched for the fare to apply, an itinerary that passes through zones 5 and 6 but not zone 7 would not have fare class "c". For more detail, see [https://code.google.com/p/googletransitdatafeed/wiki/FareExamples](https://code.google.com/p/googletransitdatafeed/wiki/FareExamples) in the GoogleTransitDataFeed project wiki.* |

### timeframes.txt

File: **Optional**

Primary key (*)

Used to describe fares that can vary based on the time of day, the day of the week, or a particular day in the year. Timeframes can be associated with fare products in `fare_leg_rules.txt`. <br>
There must not be overlapping time intervals for the same `timeframe_group_id` and `service_id` values.

| Field Name | Type | Presence | Description |
| ------ | ------ | ------ | ------ |
| `timeframe_group_id` | ID | **Required** | Identifies a timeframe or set of timeframes. |
| `start_time` | Time | **Conditionally Required** | Defines the beginning of a timeframe. The interval includes the start time.<br> Values greater than `24:00:00` are forbidden. An empty value in `start_time` is considered `00:00:00`. <br><br> Conditionally Required:<br> - **Required** if `timeframes.end_time` is defined.<br> - **Forbidden** otherwise |
| `end_time` | Time | **Conditionally Required** | Defines the end of a timeframe. The interval does not include the end time.<br> Values greater than `24:00:00` are forbidden. An empty value in `end_time` is considered `24:00:00`. <br><br> Conditionally Required:<br> - **Required** if `timeframes.start_time` is defined.<br> - **Forbidden** otherwise |
| `service_id` | Foreign ID referencing `calendar.service_id` or `calendar_dates.service_id` | **Required** | Identifies a set of dates that a timeframe is in effect. |

#### Timeframe Local Time Semantics
- When evaluating a fare event’s time against `timeframes.txt`, the event time is computed in local time using the local timezone, as determined by the `stop_timezone`, if specified, of the stop or parent station for the fare event. If not specified, the feed’s agency timezone should be used instead.
- The “current day” is the current date of the fare event’s time, computed relative to the local timezone. The “current day” may be different from the service day of a fare leg’s trip, especially for trips that extend past midnight.
- The “time-of-day” for the fare event is computed relative to “current day” using GTFS Time field-type semantics.

### fare_media.txt

File: **Optional**
Expand Down Expand Up @@ -380,7 +403,7 @@ To describe the different types of tickets or fares that can be purchased by rid

File: **Optional**

Primary Key (`network_id, from_area_id, to_area_id, fare_product_id`)
Primary Key (`network_id, from_area_id, to_area_id, from_timeframe_group_id, to_timeframe_group_id, fare_product_id`)

Fare rules for individual legs of travel.

Expand All @@ -391,14 +414,18 @@ To process the cost of a leg:
1. The file `fare_leg_rules.txt` must be filtered by the fields that define the characteristics of travel, these fields are:
- `fare_leg_rules.network_id`
- `fare_leg_rules.from_area_id`
- `fare_leg_rules.to_area_id`<br/>
- `fare_leg_rules.to_area_id`
- `fare_leg_rules.from_timeframe_group_id`
- `fare_leg_rules.to_timeframe_group_id`<br/>
<br/>

2. If the leg exactly matches a record in `fare_leg_rules.txt` based on the characteristics of travel, that record must be processed to determine the cost of the leg.
<br/>

3. If no exact matches are found, then empty entries in `fare_leg_rules.network_id`, `fare_leg_rules.from_area_id`, and `fare_leg_rules.to_area_id` must be checked to process the cost of the leg:
- An empty entry in `fare_leg_rules.network_id` corresponds to all networks defined in `routes.txt` excluding the ones listed under `fare_leg_rules.network_id`
- An empty entry in `fare_leg_rules.from_area_id` corresponds to all areas defined in `areas.area_id` excluding the ones listed under `fare_leg_rules.from_area_id`
- An empty entry in `fare_leg_rules.to_area_id` corresponds to all areas defined in `areas.area_id` excluding the ones listed under `fare_leg_rules.to_area_id`<br/>
- An empty entry in `fare_leg_rules.to_area_id` corresponds to all areas defined in `areas.area_id` excluding the ones listed under `fare_leg_rules.to_area_id`
<br/>

4. If the leg does not match any of the rules described above, then the fare is unknown.
Expand All @@ -411,6 +438,8 @@ To process the cost of a leg:
| `network_id` | Foreign ID referencing `routes.network_id` | Optional | Identifies a route network that applies for the fare leg rule.<br><br>If there are no matching `fare_leg_rules.network_id` values to the `network_id` being filtered, empty `fare_leg_rules.network_id` will be matched by default.<br><br> An empty entry in `fare_leg_rules.network_id` corresponds to all networks defined in `routes.txt` excluding the ones listed under `fare_leg_rules.network_id` |
| `from_area_id` | Foreign ID referencing `areas.area_id` | Optional | Identifies a departure area.<br><br>If there are no matching `fare_leg_rules.from_area_id` values to the `area_id` being filtered, empty `fare_leg_rules.from_area_id` will be matched by default. <br><br>An empty entry in `fare_leg_rules.from_area_id` corresponds to all areas defined in `areas.area_id` excluding the ones listed under `fare_leg_rules.from_area_id` |
| `to_area_id` | Foreign ID referencing `areas.area_id` | Optional | Identifies an arrival area.<br><br>If there are no matching `fare_leg_rules.to_area_id` values to the `area_id` being filtered, empty `fare_leg_rules.to_area_id` will be matched by default.<br><br> An empty entry in `fare_leg_rules.to_area_id` corresponds to all areas defined in `areas.area_id` excluding the ones listed under `fare_leg_rules.to_area_id` |
| `from_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the fare validation event at the start of the fare leg.<br><br>The “start time” of the fare leg is the time at which the event is scheduled to occur. For example, the time could be the scheduled departure time of a bus at the start of a fare leg where the rider boards and validates their fare. For the rule matching semantics below, the start time is computed in local time, as determined by [Local Time Semantics](#localtimesemantics) of [timeframes.txt](#timeframestxt). The stop or station of the fare leg’s departure event should be used for timezone resolution, where appropriate.<br><br>For a fare leg rule that specifies a `from_timeframe_group_id`, that rule will match a particular leg if there exists at least one record in `timeframes.txt` where all of the following conditions are true<br>- The value of `timeframe_group_id` is equal to the `from_timeframe_group_id` value.<br>- The set of days identified by the record’s `service_id` contains the “current day” of the fare leg’s start time.<br>- The “time-of-day” of the fare leg's start time is greater than or equal to the record’s `timeframes.start_time` value and less than the `timeframes.end_time` value.<br><br>An empty `fare_leg_rules.from_timeframe_group_id` indicates that the start time of the leg does not affect the matching of this rule. |
| `to_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the fare validation event at the end of the fare leg.<br><br>The “end time” of the fare leg is the time at which the event is scheduled to occur. For example, the time could be the scheduled arrival time of a bus at the end of a fare leg where the rider gets off and validates their fare. For the rule matching semantics below, the end time is computed in local time, as determined by [Local Time Semantics](#localtimesemantics) of [timeframes.txt](#timeframestxt). The stop or station of the fare leg’s arrival event should be used for timezone resolution, where appropriate.<br><br>For a fare leg rule that specifies a `to_timeframe_group_id`, that rule will match a particular leg if there exists at least one record in `timeframes.txt` where all of the following conditions are true<br>- The value of `timeframe_group_id` is equal to the `to_timeframe_group_id` value.<br>- The set of days identified by the record’s `service_id` contains the “current day” of the fare leg’s end time.<br>- The “time-of-day” of the fare leg's end time is greater than or equal to the record’s `timeframes.start_time` value and less than the `timeframes.end_time` value.<br><br>An empty `fare_leg_rules.to_timeframe_group_id` indicates that the end time of the leg does not affect the matching of this rule. |
| `fare_product_id` | Foreign ID referencing `fare_products.fare_product_id` | **Required** | The fare product required to travel the leg. |

### fare_transfer_rules.txt
Expand Down