From 94d15cb8410463db30c8a20d63ab1d045b4c33cc Mon Sep 17 00:00:00 2001 From: omar-kabbani <78552622+omar-kabbani@users.noreply.github.com> Date: Thu, 4 Aug 2022 19:20:43 -0400 Subject: [PATCH 1/2] Added timeframes --- gtfs/spec/en/reference.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index b3c39ec39..b7e08a3dd 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -17,6 +17,7 @@ This document defines the format and structure of the files that comprise a GTFS - [stop\_times.txt](#stop_timestxt) - [calendar.txt](#calendartxt) - [calendar\_dates.txt](#calendar_datestxt) + - [timeframes.txt](#timeframestxt) - [fare\_attributes.txt](#fare_attributestxt) - [fare\_rules.txt](#fare_rulestxt) - [fare\_products.txt](#fare_productstxt) @@ -300,6 +301,18 @@ The [calendar_dates.txt](#calendar_datestxt) table explicitly activates or disab | `date` | Date | **Required** | Date when service exception occurs. | | `exception_type` | Enum | **Required** | Indicates whether service is available on the date specified in the date field. Valid options are:

`1` - Service has been added for the specified date.
`2` - Service has been removed for the specified date.
*Example: Suppose a route has one set of trips available on holidays and another set of trips available on all other days. One `service_id` could correspond to the regular service schedule and another `service_id` could correspond to the holiday schedule. For a particular holiday, the [calendar_dates.txt](#calendar_datestxt) file could be used to add the holiday to the holiday `service_id` and to remove the holiday from the regular `service_id` schedule.* | +### timeframes.txt + +File: **Optional** + +Primary key (`timeframe_id`, `start_time`, `end_time`) + +| Field Name | Type | Presence | Description | +| ------ | ------ | ------ | ------ | +| `timeframe_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | +| `start_time` | Time | **Required** | Defines the beginning of a timeframe. | +| `end_time` | Time | **Required** | Defines the end of a timeframe. | + ### fare_attributes.txt File: **Optional** @@ -362,7 +375,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_id, to_timeframe_id, fare_product_id`) Fare rules for individual legs of travel. @@ -373,14 +386,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`
+ - `fare_leg_rules.to_area_id` + - `fare_leg_rules.from_timeframe_id` + - `fare_leg_rules.to_timeframe_id`

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. -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: +3. If no exact matches are found, then empty entries in `fare_leg_rules.network_id`, `fare_leg_rules.from_area_id`, `fare_leg_rules.to_area_id`, `fare_leg_rules.from_timeframe_id`, and `fare_leg_rules.to_timeframe_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`
+ - 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` + - An empty entry in `fare_leg_rules.from_timeframe_id` corresponds to all timeframes defined in `timeframes.timeframe_id` excluding the ones listed under `fare_leg_rules.from_timeframe_id` + - An empty entry in `fare_leg_rules.to_timeframe_id` corresponds to all timeframes defined in `timeframes.timeframe_id` excluding the ones listed under `fare_leg_rules.to_timeframe_id`

4. If the leg does not match any of the rules described above, then the fare is unknown. @@ -393,6 +410,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.

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.

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.

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.

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.

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.

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_id` | Foreign ID referencing `timeframes.timeframe_id` | Optional | Defines a departure timeframe for the fare leg rule.

If there are no matching `fare_leg_rules.from_timeframe_id` values to the `timeframe_id` being filtered, empty `fare_leg_rules.from_timeframe_id` will be matched by default.

An empty entry in `fare_leg_rules.from_timeframe_id` corresponds to all timeframes defined in `timeframes.timeframe_id` excluding the ones listed under `fare_leg_rules.from_timeframe_id` | +| `to_timeframe_id` | Foreign ID referencing `timeframes.timeframe_id` | Optional | Defines an arrival timeframe for the fare leg rule.

If there are no matching `fare_leg_rules.to_timeframe_id` values to the `timeframe_id` being filtered, empty `fare_leg_rules.to_timeframe_id` will be matched by default.

An empty entry in `fare_leg_rules.to_timeframe_id` corresponds to all timeframes defined in `timeframes.timeframe_id` excluding the ones listed under `fare_leg_rules.to_timeframe_id` | | `fare_product_id` | Foreign ID referencing `fare_products.fare_product_id` | **Required** | The fare product required to travel the leg. | ### fare_transfer_rules.txt From bfc2b1224bf7b01cad83d36f3e8f709c199bdd60 Mon Sep 17 00:00:00 2001 From: omar-kabbani <78552622+omar-kabbani@users.noreply.github.com> Date: Fri, 5 Aug 2022 13:08:35 -0400 Subject: [PATCH 2/2] Add date-based fares --- gtfs/spec/en/reference.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index b7e08a3dd..4c34e8103 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -108,6 +108,7 @@ This specification defines the following files: | [stop_times.txt](#stop_timestxt) | **Required** | Times that a vehicle arrives at and departs from stops for each trip. | | [calendar.txt](#calendartxt) | **Conditionally Required** | Service dates specified using a weekly schedule with start and end dates.

Conditionally Required:
- **Required** unless all dates of service are defined in [calendar_dates.txt](#calendar_datestxt).
- Optional otherwise. | | [calendar_dates.txt](#calendar_datestxt) | **Conditionally Required** | Exceptions for the services defined in the [calendar.txt](#calendartxt).

Conditionally Required:
- **Required** if [calendar.txt](#calendartxt) is omitted. In which case [calendar_dates.txt](#calendar_datestxt) must contain all dates of service.
- Optional otherwise. | +| [timeframes.txt](#timeframestxt) | Optional | Service times specified using a 24-hour format with start and end times. | | [fare_attributes.txt](#fare_attributestxt) | Optional | Fare information for a transit agency's routes. | | [fare_rules.txt](#fare_rulestxt) | **Conditionally Required** | Rules to apply fares for itineraries.

Conditionally Required:
- **Required** if [fare_attributes.txt](#fare_attributestxt) is defined.
- **Forbidden** otherwise. | | [fare_products.txt](#fare_productstxt) | Optional | To describe the different types of tickets or fares that can be purchased by riders.

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). | @@ -375,7 +376,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, from_timeframe_id, to_timeframe_id, fare_product_id`) +Primary Key (`network_id, from_area_id, to_area_id, from_timeframe_id, to_timeframe_id, service_id, fare_product_id`) Fare rules for individual legs of travel. @@ -388,16 +389,18 @@ To process the cost of a leg: - `fare_leg_rules.from_area_id` - `fare_leg_rules.to_area_id` - `fare_leg_rules.from_timeframe_id` - - `fare_leg_rules.to_timeframe_id`
+ - `fare_leg_rules.to_timeframe_id` + - `fare_leg_rules.service_id`

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. -3. If no exact matches are found, then empty entries in `fare_leg_rules.network_id`, `fare_leg_rules.from_area_id`, `fare_leg_rules.to_area_id`, `fare_leg_rules.from_timeframe_id`, and `fare_leg_rules.to_timeframe_id` must be checked to process the cost of the leg: +3. If no exact matches are found, then empty entries in `fare_leg_rules.network_id`, `fare_leg_rules.from_area_id`, `fare_leg_rules.to_area_id`, `fare_leg_rules.from_timeframe_id`, `fare_leg_rules.to_timeframe_id`, and `fare_leg_rules.service_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` - An empty entry in `fare_leg_rules.from_timeframe_id` corresponds to all timeframes defined in `timeframes.timeframe_id` excluding the ones listed under `fare_leg_rules.from_timeframe_id` - - An empty entry in `fare_leg_rules.to_timeframe_id` corresponds to all timeframes defined in `timeframes.timeframe_id` excluding the ones listed under `fare_leg_rules.to_timeframe_id`
+ - An empty entry in `fare_leg_rules.to_timeframe_id` corresponds to all timeframes defined in `timeframes.timeframe_id` excluding the ones listed under `fare_leg_rules.to_timeframe_id` + - An empty entry in `fare_leg_rules.service_id` corresponds to all dates defined in `calendar.service_id` excluding the ones listed under `fare_leg_rules.service_id`

4. If the leg does not match any of the rules described above, then the fare is unknown. @@ -412,6 +415,7 @@ To process the cost of a leg: | `to_area_id` | Foreign ID referencing `areas.area_id` | Optional | Identifies an arrival area.

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.

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_id` | Foreign ID referencing `timeframes.timeframe_id` | Optional | Defines a departure timeframe for the fare leg rule.

If there are no matching `fare_leg_rules.from_timeframe_id` values to the `timeframe_id` being filtered, empty `fare_leg_rules.from_timeframe_id` will be matched by default.

An empty entry in `fare_leg_rules.from_timeframe_id` corresponds to all timeframes defined in `timeframes.timeframe_id` excluding the ones listed under `fare_leg_rules.from_timeframe_id` | | `to_timeframe_id` | Foreign ID referencing `timeframes.timeframe_id` | Optional | Defines an arrival timeframe for the fare leg rule.

If there are no matching `fare_leg_rules.to_timeframe_id` values to the `timeframe_id` being filtered, empty `fare_leg_rules.to_timeframe_id` will be matched by default.

An empty entry in `fare_leg_rules.to_timeframe_id` corresponds to all timeframes defined in `timeframes.timeframe_id` excluding the ones listed under `fare_leg_rules.to_timeframe_id` | +| `service_id` | Foreign ID referencing `calendar.service_id` | Optional | Identifies a set of dates that a fare leg rule is in effect.

If there are no matching `fare_leg_rules.service_id` values to the `service_id` being filtered, empty `fare_leg_rules.service_id` will be matched by default.

An empty entry in `fare_leg_rules.service_id` corresponds to all dates defined in `calendar.service_id` excluding the ones listed under `fare_leg_rules.service_id` | | `fare_product_id` | Foreign ID referencing `fare_products.fare_product_id` | **Required** | The fare product required to travel the leg. | ### fare_transfer_rules.txt