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 01/41] 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 02/41] 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 From 713e91cd6f60f9b75f7f98f9ee327c3e15bce693 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Mon, 14 Nov 2022 18:28:32 -0500 Subject: [PATCH 03/41] Update timeframes.txt description --- gtfs/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 4c34e8103..1f4ae9b47 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -108,7 +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. | +| [timeframes.txt](#timeframestxt) | Optional | Time periods used in fare rules for time-dependant fares. | | [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). | From 5a8ca388baeeb81cde059d18e76d12d8ef7210ca Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Mon, 14 Nov 2022 18:40:30 -0500 Subject: [PATCH 04/41] Change end time from required to optional --- gtfs/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 1f4ae9b47..6ae197475 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -312,7 +312,7 @@ Primary key (`timeframe_id`, `start_time`, `end_time`) | ------ | ------ | ------ | ------ | | `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. | +| `end_time` | Time | **Optional** | Defines the end of a timeframe. If empty, it is considered that the fare only depends on start time.| ### fare_attributes.txt From 0b7c9e28511e83254f81e2af8927a7d4ec5ae08e Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Mon, 14 Nov 2022 18:54:59 -0500 Subject: [PATCH 05/41] Records with the same timeframe id must cover a 24h period --- gtfs/spec/en/reference.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 6ae197475..2f4bd864c 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -310,9 +310,9 @@ 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 | **Optional** | Defines the end of a timeframe. If empty, it is considered that the fare only depends on start time.| +| `timeframe_id` | ID | **Required** | Identifies a timeframe or set of timeframes. All records with the same `timeframe_id` must cover a 24h period. | +| `start_time` | Time | **Required** | Start time for the interval. The start time is included in the interval. | +| `end_time` | Time | **Optional** | Start time for the interval. The end time is included in the interval. If empty, it is considered that the fare only depends on start time.| ### fare_attributes.txt From fd2eb134f95bbcb54320802c14bb8d4969e67856 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Mon, 14 Nov 2022 18:59:16 -0500 Subject: [PATCH 06/41] no overlap --- gtfs/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 2f4bd864c..9111779b9 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -310,7 +310,7 @@ Primary key (`timeframe_id`, `start_time`, `end_time`) | Field Name | Type | Presence | Description | | ------ | ------ | ------ | ------ | -| `timeframe_id` | ID | **Required** | Identifies a timeframe or set of timeframes. All records with the same `timeframe_id` must cover a 24h period. | +| `timeframe_id` | ID | **Required** | Identifies a timeframe or set of timeframes. All records with the same `timeframe_id` must cover a 24h period without overlap.| | `start_time` | Time | **Required** | Start time for the interval. The start time is included in the interval. | | `end_time` | Time | **Optional** | Start time for the interval. The end time is included in the interval. If empty, it is considered that the fare only depends on start time.| From 991ccbabc3a90567c4ae67e168b240c23429d0a8 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Tue, 15 Nov 2022 14:12:30 -0500 Subject: [PATCH 07/41] remove requirement on 24h coverage and overlapping --- gtfs/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 9111779b9..ff57a6554 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -310,7 +310,7 @@ Primary key (`timeframe_id`, `start_time`, `end_time`) | Field Name | Type | Presence | Description | | ------ | ------ | ------ | ------ | -| `timeframe_id` | ID | **Required** | Identifies a timeframe or set of timeframes. All records with the same `timeframe_id` must cover a 24h period without overlap.| +| `timeframe_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | | `start_time` | Time | **Required** | Start time for the interval. The start time is included in the interval. | | `end_time` | Time | **Optional** | Start time for the interval. The end time is included in the interval. If empty, it is considered that the fare only depends on start time.| From d2e89a6b6ffde7236a69feb9fb2f01b7a4436892 Mon Sep 17 00:00:00 2001 From: isabelle-dr <63653518+isabelle-dr@users.noreply.github.com> Date: Mon, 21 Nov 2022 11:34:23 -0500 Subject: [PATCH 08/41] fix typo --- gtfs/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index ff57a6554..5d052119e 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -312,7 +312,7 @@ Primary key (`timeframe_id`, `start_time`, `end_time`) | ------ | ------ | ------ | ------ | | `timeframe_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | | `start_time` | Time | **Required** | Start time for the interval. The start time is included in the interval. | -| `end_time` | Time | **Optional** | Start time for the interval. The end time is included in the interval. If empty, it is considered that the fare only depends on start time.| +| `end_time` | Time | **Optional** | End time for the interval. The end time is included in the interval. If empty, it is considered that the fare only depends on start time.| ### fare_attributes.txt From 710be109a154845d7c1795145425de8f5e274e1d Mon Sep 17 00:00:00 2001 From: isabelle-dr <63653518+isabelle-dr@users.noreply.github.com> Date: Wed, 23 Nov 2022 16:36:48 -0500 Subject: [PATCH 09/41] Revert changes in timeframes.end_time --- gtfs/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 5d052119e..370be4c4e 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -312,7 +312,7 @@ Primary key (`timeframe_id`, `start_time`, `end_time`) | ------ | ------ | ------ | ------ | | `timeframe_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | | `start_time` | Time | **Required** | Start time for the interval. The start time is included in the interval. | -| `end_time` | Time | **Optional** | End time for the interval. The end time is included in the interval. If empty, it is considered that the fare only depends on start time.| +| `end_time` | Time | **Required** | End time for the interval. The end time is included in the interval. | ### fare_attributes.txt From f9a4a1de0e9456786cf51961f1715af54f236dfa Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Fri, 10 Mar 2023 16:42:24 -0500 Subject: [PATCH 10/41] move service_id to timeframes.txt --- gtfs/spec/en/reference.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 370be4c4e..ae1fc6481 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -306,13 +306,14 @@ The [calendar_dates.txt](#calendar_datestxt) table explicitly activates or disab File: **Optional** -Primary key (`timeframe_id`, `start_time`, `end_time`) +Primary key (*) | Field Name | Type | Presence | Description | | ------ | ------ | ------ | ------ | | `timeframe_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | -| `start_time` | Time | **Required** | Start time for the interval. The start time is included in the interval. | -| `end_time` | Time | **Required** | End time for the interval. The end time is included in the interval. | +| `start_time` | Time | Optional | Start time for the interval. The start time is included in the interval. | +| `end_time` | Time | Optional | End time for the interval. The end time is included in the interval. | +| `service_id` | Foreign ID referencing `calendar.service_id` | Optional | Identifies a set of dates that a timeframe is in effect. | ### fare_attributes.txt @@ -376,7 +377,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, service_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. @@ -389,18 +390,16 @@ 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.service_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`, `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: +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.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.service_id` corresponds to all dates defined in `calendar.service_id` excluding the ones listed under `fare_leg_rules.service_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. @@ -415,7 +414,6 @@ 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 From 84da99f1a65a7bb7fd481646fed6677579dca46b Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Fri, 10 Mar 2023 16:44:42 -0500 Subject: [PATCH 11/41] Move timeframes to the fares v2 section --- gtfs/spec/en/reference.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index ae1fc6481..d20e5ef13 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -302,19 +302,6 @@ 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 (*) - -| Field Name | Type | Presence | Description | -| ------ | ------ | ------ | ------ | -| `timeframe_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | -| `start_time` | Time | Optional | Start time for the interval. The start time is included in the interval. | -| `end_time` | Time | Optional | End time for the interval. The end time is included in the interval. | -| `service_id` | Foreign ID referencing `calendar.service_id` | Optional | Identifies a set of dates that a timeframe is in effect. | - ### fare_attributes.txt File: **Optional** @@ -358,6 +345,19 @@ 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`.
*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:*
`fare_id,...,origin_id,destination_id`
`b,...,3,4`
`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.
*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:*
`fare_id,route_id,...,contains_id`
`c,GRT,...,5`
`c,GRT,...,6`
`c,GRT,...,7`
*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 (*) + +| Field Name | Type | Presence | Description | +| ------ | ------ | ------ | ------ | +| `timeframe_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | +| `start_time` | Time | Optional | Start time for the interval. The start time is included in the interval. | +| `end_time` | Time | Optional | End time for the interval. The end time is included in the interval. | +| `service_id` | Foreign ID referencing `calendar.service_id` | Optional | Identifies a set of dates that a timeframe is in effect. | + ### fare_products.txt File: **Optional** From b8aad98123b957139f61a9d29a158a85db3b3da0 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Fri, 10 Mar 2023 16:48:45 -0500 Subject: [PATCH 12/41] rename timeframe_id to timeframe_group_id --- gtfs/spec/en/reference.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index d20e5ef13..31df75de2 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -353,7 +353,7 @@ Primary key (*) | Field Name | Type | Presence | Description | | ------ | ------ | ------ | ------ | -| `timeframe_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | +| `timeframe_group_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | | `start_time` | Time | Optional | Start time for the interval. The start time is included in the interval. | | `end_time` | Time | Optional | End time for the interval. The end time is included in the interval. | | `service_id` | Foreign ID referencing `calendar.service_id` | Optional | Identifies a set of dates that a timeframe is in effect. | @@ -377,7 +377,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_group_id, to_timeframe_group_id, fare_product_id`) Fare rules for individual legs of travel. @@ -389,17 +389,17 @@ To process the cost of a leg: - `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`
+ - `fare_leg_rules.from_timeframe_group_id` + - `fare_leg_rules.to_timeframe_group_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_group_id`, and `fare_leg_rules.to_timeframe_group_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.from_timeframe_group_id` corresponds to all timeframes defined in `timeframes.timeframe_group_id` excluding the ones listed under `fare_leg_rules.from_timeframe_group_id` + - An empty entry in `fare_leg_rules.to_timeframe_group_id` corresponds to all timeframes defined in `timeframes.timeframe_group_id` excluding the ones listed under `fare_leg_rules.to_timeframe_group_id`

4. If the leg does not match any of the rules described above, then the fare is unknown. @@ -412,8 +412,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` | +| `from_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines a departure timeframe for the fare leg rule.

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

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

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

An empty entry in `fare_leg_rules.to_timeframe_group_id` corresponds to all timeframes defined in `timeframes.timeframe_group_id` excluding the ones listed under `fare_leg_rules.to_timeframe_group_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 d68c3fd7a9f11e7059f1f37177ccc5f1e1bf45c9 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Wed, 15 Mar 2023 12:23:58 -0400 Subject: [PATCH 13/41] place timeframes.txt with other Fares v2 files --- gtfs/spec/en/reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 2ae6ffe28..49a843f2c 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -17,9 +17,9 @@ 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) + - [timeframes.txt](#timeframestxt) - [fare\_media.txt](#fare_mediatxt) - [fare\_products.txt](#fare_productstxt) - [fare\_leg\_rules.txt](#fare_leg_rulestxt) @@ -109,9 +109,9 @@ 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 | Time periods used in fare rules for time-dependant fares. | | [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.

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.

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.

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). | From 50e60c89f2935d018b4ea5bba3db07e201a37dd8 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Tue, 21 Mar 2023 15:19:39 -0400 Subject: [PATCH 14/41] Rename from/to fields + change empty semantics - Rename from_timeframe_id and to_timeframe_id to start_timeframe_group_id and to_timeframe_group_id - Change empty semantics so that an empty entry means the fare isn't affected (as opposed to the "empty means everything except") --- gtfs/spec/en/reference.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 49a843f2c..8a84aa860 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -396,7 +396,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_group_id, to_timeframe_group_id, fare_product_id`) +Primary Key (`network_id, from_area_id, to_area_id, start_timeframe_group_id, end_timeframe_group_id, fare_product_id`) Fare rules for individual legs of travel. @@ -408,17 +408,15 @@ To process the cost of a leg: - `fare_leg_rules.network_id` - `fare_leg_rules.from_area_id` - `fare_leg_rules.to_area_id` - - `fare_leg_rules.from_timeframe_group_id` - - `fare_leg_rules.to_timeframe_group_id`
+ - `fare_leg_rules.start_timeframe_group_id` + - `fare_leg_rules.end_timeframe_group_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_group_id`, and `fare_leg_rules.to_timeframe_group_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.start_timeframe_group_id`, and `fare_leg_rules.end_timeframe_group_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_group_id` corresponds to all timeframes defined in `timeframes.timeframe_group_id` excluding the ones listed under `fare_leg_rules.from_timeframe_group_id` - - An empty entry in `fare_leg_rules.to_timeframe_group_id` corresponds to all timeframes defined in `timeframes.timeframe_group_id` excluding the ones listed under `fare_leg_rules.to_timeframe_group_id`

4. If the leg does not match any of the rules described above, then the fare is unknown. @@ -431,8 +429,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_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines a departure timeframe for the fare leg rule.

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

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

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

An empty entry in `fare_leg_rules.to_timeframe_group_id` corresponds to all timeframes defined in `timeframes.timeframe_group_id` excluding the ones listed under `fare_leg_rules.to_timeframe_group_id` | +| `start_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines a departure timeframe for the fare leg rule.

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

An empty `fare_leg_rules.start_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | +| `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines an arrival timeframe for the fare leg rule.

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

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `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 d42bfdf86644d0cb1712b2fe358277133cf5ec65 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Tue, 21 Mar 2023 15:20:15 -0400 Subject: [PATCH 15/41] add line break --- gtfs/spec/en/reference.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 8a84aa860..645d04d0d 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -413,6 +413,8 @@ To process the cost of a leg:
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.start_timeframe_group_id`, and `fare_leg_rules.end_timeframe_group_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` From 50a080dc9aca214a4aebe308830f24e5c642109e Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Thu, 23 Mar 2023 12:12:10 -0400 Subject: [PATCH 16/41] Add timeframes description --- gtfs/spec/en/reference.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 645d04d0d..51d600e27 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -353,6 +353,8 @@ 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`. + | Field Name | Type | Presence | Description | | ------ | ------ | ------ | ------ | | `timeframe_group_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | From 19dae726eff255501275cd7455cb5ea4ece38220 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Thu, 23 Mar 2023 12:14:30 -0400 Subject: [PATCH 17/41] Make timeframe fields required --- gtfs/spec/en/reference.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 51d600e27..88cb349d5 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -358,9 +358,9 @@ Used to describe fares that can vary based on the time of day, the day of the we | Field Name | Type | Presence | Description | | ------ | ------ | ------ | ------ | | `timeframe_group_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | -| `start_time` | Time | Optional | Start time for the interval. The start time is included in the interval. | -| `end_time` | Time | Optional | End time for the interval. The end time is included in the interval. | -| `service_id` | Foreign ID referencing `calendar.service_id` | Optional | Identifies a set of dates that a timeframe is in effect. | +| `start_time` | Time | **Required** | Start time for the interval. The start time is included in the interval. | +| `end_time` | Time | **Required** | End time for the interval. The end time is included in the interval. | +| `service_id` | Foreign ID referencing `calendar.service_id` | **Required** | Identifies a set of dates that a timeframe is in effect. | ### fare_media.txt From 0222fff0a5ce03369d4232f4fbcdf352638f89fe Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Thu, 23 Mar 2023 12:16:56 -0400 Subject: [PATCH 18/41] service_id references calendar or calendar_dates --- gtfs/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 88cb349d5..790cfc245 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -360,7 +360,7 @@ Used to describe fares that can vary based on the time of day, the day of the we | `timeframe_group_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | | `start_time` | Time | **Required** | Start time for the interval. The start time is included in the interval. | | `end_time` | Time | **Required** | End time for the interval. The end time is included in the interval. | -| `service_id` | Foreign ID referencing `calendar.service_id` | **Required** | Identifies a set of dates that a timeframe is in effect. | +| `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. | ### fare_media.txt From 27f5c065ff254c1a57d03d28289148f42820f513 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Thu, 23 Mar 2023 12:38:10 -0400 Subject: [PATCH 19/41] Add requirements - the whole day must be covered with timeframes if one is defined - there should not be overlapping time frames with the same timeframe_group_id and service_id --- gtfs/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 790cfc245..8dee818bb 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -360,7 +360,7 @@ Used to describe fares that can vary based on the time of day, the day of the we | `timeframe_group_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | | `start_time` | Time | **Required** | Start time for the interval. The start time is included in the interval. | | `end_time` | Time | **Required** | End time for the interval. The end time is included in the interval. | -| `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. | +| `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.
For each `service_id`, time intervals must be defined for the entire day (from `00:00:00` to `23:59:50`).
There should not be overlapping time intervals for the same `timeframe_group_id` and `service_id` values. | ### fare_media.txt From 9bd26d0581ea93c0e8d7eeead1e649690bd6b923 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Thu, 23 Mar 2023 16:53:42 -0400 Subject: [PATCH 20/41] typo --- gtfs/spec/en/reference.md | 1 - 1 file changed, 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 8dee818bb..3f4d08925 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -375,7 +375,6 @@ To describe the different fare media that can be employed to use fare products. | `fare_media_id` | Unique ID | **Required** | Identifies a fare media. | | `fare_media_name` | Text | Optional | Name of the fare media.

For fare media which are transit cards (`fare_media_type =2`) or mobile apps (`fare_media_type =4`), the `fare_media_name` should be included and should match the rider-facing name used by the organizations delivering them. | | `fare_media_type` | Enum | **Required** | The type of fare media. Valid options are:

`0` - None. Used when there is no fare media involved in purchasing or validating a fare product, such as paying cash to a driver or conductor with no physical ticket provided.
`2` - Physical transit card that has stored tickets, passes or monetary value.
`3` - cEMV (contactless Europay, Mastercard and Visa) as an open-loop token container for account-based ticketing.
`4` - Mobile app that have stored virtual transit cards, tickets, passes, or monetary value.| - master ### fare_products.txt From acd9d0d8698a466287db9f7b45e0d6ba0e49b000 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Tue, 4 Apr 2023 14:23:10 -0400 Subject: [PATCH 21/41] Update timeframe fields description --- gtfs/spec/en/reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 3f4d08925..0e793bf6c 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -432,8 +432,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` | -| `start_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines a departure timeframe for the fare leg rule.

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

An empty `fare_leg_rules.start_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | -| `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines an arrival timeframe for the fare leg rule.

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

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | +| `start_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the departure of the fare leg.

For a fare leg rule that specifies a `start_timeframe_group_id`, that rule will match a particular leg if there exists at least a row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `start_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The departure time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.start_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | +| `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the arrival of the fare leg.

For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if there exists at least a row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The arrival time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `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 a182e6ca2b9a34006f7a778562ce4b8782d86311 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Tue, 4 Apr 2023 14:29:47 -0400 Subject: [PATCH 22/41] end time is not included in the interval --- gtfs/spec/en/reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 0e793bf6c..474542612 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -358,8 +358,8 @@ Used to describe fares that can vary based on the time of day, the day of the we | Field Name | Type | Presence | Description | | ------ | ------ | ------ | ------ | | `timeframe_group_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | -| `start_time` | Time | **Required** | Start time for the interval. The start time is included in the interval. | -| `end_time` | Time | **Required** | End time for the interval. The end time is included in the interval. | +| `start_time` | Time | **Required** | Start time for the interval. The interval includes the start time. | +| `end_time` | Time | **Required** | End time for the interval. The interval does not include the end time. | | `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.
For each `service_id`, time intervals must be defined for the entire day (from `00:00:00` to `23:59:50`).
There should not be overlapping time intervals for the same `timeframe_group_id` and `service_id` values. | ### fare_media.txt From e8463ce36936ebfcf77db1f6ec4324e7016c8648 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Tue, 4 Apr 2023 15:06:51 -0400 Subject: [PATCH 23/41] Add timeframe_type field --- gtfs/spec/en/reference.md | 1 + 1 file changed, 1 insertion(+) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 474542612..31147fa26 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -434,6 +434,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` | | `start_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the departure of the fare leg.

For a fare leg rule that specifies a `start_timeframe_group_id`, that rule will match a particular leg if there exists at least a row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `start_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The departure time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.start_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | | `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the arrival of the fare leg.

For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if there exists at least a row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The arrival time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | +| `timeframe_type` | Enum | **Conditionally Required** | Defines the type of fare validation to be associated with `timeframes.start_time` and `timeframes.end_time`.

Valid options are:
`0` - In vehicle.
`1` - At fare gate or on platform.

Conditionally Required:
- **Required** if either `start_timeframe_group_id` or `end_timeframe_group_id` is defined.
- **Forbidden** otherwise.| | `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 477ab30a8521aedcf1c3a76eb933cac7e19ae2fb Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Wed, 5 Apr 2023 14:27:07 -0400 Subject: [PATCH 24/41] Overlapping time frames must not be defined for the same timeframe_group_id and service_id --- gtfs/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 31147fa26..17f1c1c56 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -360,7 +360,7 @@ Used to describe fares that can vary based on the time of day, the day of the we | `timeframe_group_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | | `start_time` | Time | **Required** | Start time for the interval. The interval includes the start time. | | `end_time` | Time | **Required** | End time for the interval. The interval does not include the end time. | -| `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.
For each `service_id`, time intervals must be defined for the entire day (from `00:00:00` to `23:59:50`).
There should not be overlapping time intervals for the same `timeframe_group_id` and `service_id` values. | +| `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.
For each `service_id`, time intervals must be defined for the entire day (from `00:00:00` to `23:59:50`).
There must not be overlapping time intervals for the same `timeframe_group_id` and `service_id` values. | ### fare_media.txt From c34bfed936560cab6f8dc29f1d4c28fc99696fc3 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Wed, 5 Apr 2023 14:46:41 -0400 Subject: [PATCH 25/41] introduce override Introduce an override field in fare_leg_rules and remove the requirement of needing the whole day covered with timeframes if one is defined. --- gtfs/spec/en/reference.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 17f1c1c56..d5c0b568c 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -360,7 +360,7 @@ Used to describe fares that can vary based on the time of day, the day of the we | `timeframe_group_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | | `start_time` | Time | **Required** | Start time for the interval. The interval includes the start time. | | `end_time` | Time | **Required** | End time for the interval. The interval does not include the end time. | -| `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.
For each `service_id`, time intervals must be defined for the entire day (from `00:00:00` to `23:59:50`).
There must not be overlapping time intervals for the same `timeframe_group_id` and `service_id` values. | +| `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.
There must not be overlapping time intervals for the same `timeframe_group_id` and `service_id` values. | ### fare_media.txt @@ -436,6 +436,7 @@ To process the cost of a leg: | `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the arrival of the fare leg.

For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if there exists at least a row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The arrival time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `timeframe_type` | Enum | **Conditionally Required** | Defines the type of fare validation to be associated with `timeframes.start_time` and `timeframes.end_time`.

Valid options are:
`0` - In vehicle.
`1` - At fare gate or on platform.

Conditionally Required:
- **Required** if either `start_timeframe_group_id` or `end_timeframe_group_id` is defined.
- **Forbidden** otherwise.| | `fare_product_id` | Foreign ID referencing `fare_products.fare_product_id` | **Required** | The fare product required to travel the leg. | +| `override` | Non-negative integer | Optional | When multiple entries in `fare_leg_rules.txt` match, the one with the highest `override` value will be selected.

An empty value for `override` is treated as zero.| ### fare_transfer_rules.txt From d4afc6ede5eae96567b373a9400d6f0c2e907442 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Fri, 7 Apr 2023 11:58:16 -0400 Subject: [PATCH 26/41] improve override description --- gtfs/spec/en/reference.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index d5c0b568c..29434ebca 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -436,7 +436,10 @@ To process the cost of a leg: | `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the arrival of the fare leg.

For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if there exists at least a row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The arrival time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `timeframe_type` | Enum | **Conditionally Required** | Defines the type of fare validation to be associated with `timeframes.start_time` and `timeframes.end_time`.

Valid options are:
`0` - In vehicle.
`1` - At fare gate or on platform.

Conditionally Required:
- **Required** if either `start_timeframe_group_id` or `end_timeframe_group_id` is defined.
- **Forbidden** otherwise.| | `fare_product_id` | Foreign ID referencing `fare_products.fare_product_id` | **Required** | The fare product required to travel the leg. | -| `override` | Non-negative integer | Optional | When multiple entries in `fare_leg_rules.txt` match, the one with the highest `override` value will be selected.

An empty value for `override` is treated as zero.| +| `override` | Non-negative integer | Optional | Allows certain rules to take precedence over others. When multiple entries in `fare_leg_rules.txt` match, the rule or set of rules with the highest value for `override` will be selected.

An empty value for `override` is treated as zero.| + +e third rule to take precedence +The same order value can be applied for multiple fare leg rules ### fare_transfer_rules.txt From 55679c95ddd2b1989aba55b022cd7f27dc43e715 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Fri, 7 Apr 2023 12:02:29 -0400 Subject: [PATCH 27/41] Revert "improve override description" This reverts commit d4afc6ede5eae96567b373a9400d6f0c2e907442. --- gtfs/spec/en/reference.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 29434ebca..d5c0b568c 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -436,10 +436,7 @@ To process the cost of a leg: | `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the arrival of the fare leg.

For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if there exists at least a row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The arrival time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `timeframe_type` | Enum | **Conditionally Required** | Defines the type of fare validation to be associated with `timeframes.start_time` and `timeframes.end_time`.

Valid options are:
`0` - In vehicle.
`1` - At fare gate or on platform.

Conditionally Required:
- **Required** if either `start_timeframe_group_id` or `end_timeframe_group_id` is defined.
- **Forbidden** otherwise.| | `fare_product_id` | Foreign ID referencing `fare_products.fare_product_id` | **Required** | The fare product required to travel the leg. | -| `override` | Non-negative integer | Optional | Allows certain rules to take precedence over others. When multiple entries in `fare_leg_rules.txt` match, the rule or set of rules with the highest value for `override` will be selected.

An empty value for `override` is treated as zero.| - -e third rule to take precedence -The same order value can be applied for multiple fare leg rules +| `override` | Non-negative integer | Optional | When multiple entries in `fare_leg_rules.txt` match, the one with the highest `override` value will be selected.

An empty value for `override` is treated as zero.| ### fare_transfer_rules.txt From 189822f63e267e9831589d7fbc858b9badbf5e64 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Fri, 7 Apr 2023 12:03:49 -0400 Subject: [PATCH 28/41] improve override description --- gtfs/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index d5c0b568c..900fe0767 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -436,7 +436,7 @@ To process the cost of a leg: | `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the arrival of the fare leg.

For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if there exists at least a row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The arrival time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `timeframe_type` | Enum | **Conditionally Required** | Defines the type of fare validation to be associated with `timeframes.start_time` and `timeframes.end_time`.

Valid options are:
`0` - In vehicle.
`1` - At fare gate or on platform.

Conditionally Required:
- **Required** if either `start_timeframe_group_id` or `end_timeframe_group_id` is defined.
- **Forbidden** otherwise.| | `fare_product_id` | Foreign ID referencing `fare_products.fare_product_id` | **Required** | The fare product required to travel the leg. | -| `override` | Non-negative integer | Optional | When multiple entries in `fare_leg_rules.txt` match, the one with the highest `override` value will be selected.

An empty value for `override` is treated as zero.| +| `override` | Non-negative integer | Optional | Allows certain rules to take precedence over others. When multiple entries in `fare_leg_rules.txt` match, the rule or set of rules with the highest value for `override` will be selected.

An empty value for `override` is treated as zero.| ### fare_transfer_rules.txt From f0e18a8b698e133107beeadf8667f795fb145ed4 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Fri, 7 Apr 2023 12:05:58 -0400 Subject: [PATCH 29/41] update timeframe fields description changes "a row" to "one row" --- gtfs/spec/en/reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 900fe0767..f7d10113f 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -432,8 +432,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` | -| `start_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the departure of the fare leg.

For a fare leg rule that specifies a `start_timeframe_group_id`, that rule will match a particular leg if there exists at least a row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `start_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The departure time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.start_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | -| `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the arrival of the fare leg.

For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if there exists at least a row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The arrival time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | +| `start_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the departure of the fare leg.

For a fare leg rule that specifies a `start_timeframe_group_id`, that rule will match a particular leg if there exists at least one row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `start_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The departure time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.start_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | +| `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the arrival of the fare leg.

For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if there exists at least one row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The arrival time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `timeframe_type` | Enum | **Conditionally Required** | Defines the type of fare validation to be associated with `timeframes.start_time` and `timeframes.end_time`.

Valid options are:
`0` - In vehicle.
`1` - At fare gate or on platform.

Conditionally Required:
- **Required** if either `start_timeframe_group_id` or `end_timeframe_group_id` is defined.
- **Forbidden** otherwise.| | `fare_product_id` | Foreign ID referencing `fare_products.fare_product_id` | **Required** | The fare product required to travel the leg. | | `override` | Non-negative integer | Optional | Allows certain rules to take precedence over others. When multiple entries in `fare_leg_rules.txt` match, the rule or set of rules with the highest value for `override` will be selected.

An empty value for `override` is treated as zero.| From 0aedadc530c93e6ca67a150eb10329556ca486da Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Tue, 11 Apr 2023 09:40:52 -0400 Subject: [PATCH 30/41] remove timeframe fields for no exact matched found --- gtfs/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index f7d10113f..15d20b673 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -416,7 +416,7 @@ To process the cost of a leg: 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.start_timeframe_group_id`, and `fare_leg_rules.end_timeframe_group_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`, 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` From 91bda277d61e9dfab64d9def48d73ac2e71e0a74 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Tue, 11 Apr 2023 09:48:47 -0400 Subject: [PATCH 31/41] Update descriptions for empty values: - removed the "If there are no matching `fare_leg_rules.start_timeframe_group_id` values to the `timeframe_group_id` being filtered..." - added "that rule will match a particular leg if either start_timeframe_group_id is empty, or if there exists at least a row in `timeframes.txt` where all..." --- gtfs/spec/en/reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 15d20b673..953683fcd 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -432,8 +432,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` | -| `start_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the departure of the fare leg.

For a fare leg rule that specifies a `start_timeframe_group_id`, that rule will match a particular leg if there exists at least one row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `start_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The departure time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.start_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | -| `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the arrival of the fare leg.

For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if there exists at least one row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The arrival time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

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

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | +| `start_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the departure of the fare leg.

For a fare leg rule that specifies a `start_timeframe_group_id`, that rule will match a particular leg if either `start_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `start_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The departure time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.start_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | +| `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the arrival of the fare leg.

For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if either `end_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The arrival time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `timeframe_type` | Enum | **Conditionally Required** | Defines the type of fare validation to be associated with `timeframes.start_time` and `timeframes.end_time`.

Valid options are:
`0` - In vehicle.
`1` - At fare gate or on platform.

Conditionally Required:
- **Required** if either `start_timeframe_group_id` or `end_timeframe_group_id` is defined.
- **Forbidden** otherwise.| | `fare_product_id` | Foreign ID referencing `fare_products.fare_product_id` | **Required** | The fare product required to travel the leg. | | `override` | Non-negative integer | Optional | Allows certain rules to take precedence over others. When multiple entries in `fare_leg_rules.txt` match, the rule or set of rules with the highest value for `override` will be selected.

An empty value for `override` is treated as zero.| From af4b67bf3531f6eff4ef26edc5a3a9da1b41f673 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Wed, 24 May 2023 13:16:04 -0400 Subject: [PATCH 32/41] Both values need to be empty or neither should be empty as discussed in the last working group meeting --- gtfs/spec/en/reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 953683fcd..3b2e9c648 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -358,8 +358,8 @@ Used to describe fares that can vary based on the time of day, the day of the we | Field Name | Type | Presence | Description | | ------ | ------ | ------ | ------ | | `timeframe_group_id` | ID | **Required** | Identifies a timeframe or set of timeframes. | -| `start_time` | Time | **Required** | Start time for the interval. The interval includes the start time. | -| `end_time` | Time | **Required** | End time for the interval. The interval does not include the end time. | +| `start_time` | Time | **Conditionally Required** | Defines the beginning of a timeframe. The interval includes the start time.
Values greater than `24:00:00` are forbidden. An empty value in `start_time` is considered `00:00:00`.

Conditionally Required:
- **Required** if `timeframes.end_time` is defined.
- Forbidden otherwise | +| `end_time` | Time | **Conditionally Required** | Defines the end of a timeframe. The interval does not include the end time.
Values greater than `24:00:00` are forbidden. An empty value in `end_time` is considered `24:00:00`.

Conditionally Required:
- **Required** if `timeframes.start_time` is defined.
- 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.
There must not be overlapping time intervals for the same `timeframe_group_id` and `service_id` values. | ### fare_media.txt From fe45e7ebab33507581fe6a96780add986767b2bc Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Wed, 24 May 2023 13:30:43 -0400 Subject: [PATCH 33/41] Change to local time semantics As discussed in the working group meeting --- gtfs/spec/en/reference.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 3b2e9c648..cc0e9bcee 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -362,6 +362,11 @@ Used to describe fares that can vary based on the time of day, the day of the we | `end_time` | Time | **Conditionally Required** | Defines the end of a timeframe. The interval does not include the end time.
Values greater than `24:00:00` are forbidden. An empty value in `end_time` is considered `24:00:00`.

Conditionally Required:
- **Required** if `timeframes.start_time` is defined.
- 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.
There must not be overlapping time intervals for the same `timeframe_group_id` and `service_id` values. | +#### 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** @@ -432,8 +437,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` | -| `start_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the departure of the fare leg.

For a fare leg rule that specifies a `start_timeframe_group_id`, that rule will match a particular leg if either `start_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `start_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The departure time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.start_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | -| `end_timeframe_group_id` | Foreign ID referencing `timeframes.timeframe_group_id` | Optional | Defines the timeframe for the arrival of the fare leg.

For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if either `end_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true:
- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.
- The set of service days identified by the row’s `service_id` contains the service day of the leg’s departure trip.
- The arrival time of the leg, relative to the service day per [GTFS Time field type](#field-types) conventions, is greater than or equal to the rows `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | +| `start_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.

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 initial departure event should be used for timezone resolution, where appropriate.

For a fare leg rule that specifies a `start_timeframe_group_id`, that rule will match a particular leg if either `start_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `start_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.start_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | +| `end_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.

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 initial arrival event should be used for timezone resolution, where appropriate.

For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if either `end_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `timeframe_type` | Enum | **Conditionally Required** | Defines the type of fare validation to be associated with `timeframes.start_time` and `timeframes.end_time`.

Valid options are:
`0` - In vehicle.
`1` - At fare gate or on platform.

Conditionally Required:
- **Required** if either `start_timeframe_group_id` or `end_timeframe_group_id` is defined.
- **Forbidden** otherwise.| | `fare_product_id` | Foreign ID referencing `fare_products.fare_product_id` | **Required** | The fare product required to travel the leg. | | `override` | Non-negative integer | Optional | Allows certain rules to take precedence over others. When multiple entries in `fare_leg_rules.txt` match, the rule or set of rules with the highest value for `override` will be selected.

An empty value for `override` is treated as zero.| From 045258fc02c99a2933ce01dff194a98a132d86f4 Mon Sep 17 00:00:00 2001 From: Tzu-Jen Chan <126435471+tzujenchanmbd@users.noreply.github.com> Date: Wed, 24 May 2023 15:39:18 -0400 Subject: [PATCH 34/41] Changed name start/end_timeframe_group_id As discussed in working group meeting --- gtfs/spec/en/reference.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index cc0e9bcee..140e5cbd8 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -402,7 +402,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, start_timeframe_group_id, end_timeframe_group_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. @@ -414,8 +414,8 @@ To process the cost of a leg: - `fare_leg_rules.network_id` - `fare_leg_rules.from_area_id` - `fare_leg_rules.to_area_id` - - `fare_leg_rules.start_timeframe_group_id` - - `fare_leg_rules.end_timeframe_group_id`
+ - `fare_leg_rules.from_timeframe_group_id` + - `fare_leg_rules.to_timeframe_group_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. @@ -437,8 +437,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` | -| `start_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.

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 initial departure event should be used for timezone resolution, where appropriate.

For a fare leg rule that specifies a `start_timeframe_group_id`, that rule will match a particular leg if either `start_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `start_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.start_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | -| `end_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.

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 initial arrival event should be used for timezone resolution, where appropriate.

For a fare leg rule that specifies a `end_timeframe_group_id`, that rule will match a particular leg if either `end_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `end_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.end_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | +| `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.

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 initial departure event should be used for timezone resolution, where appropriate.

For a fare leg rule that specifies a `from_timeframe_group_id`, that rule will match a particular leg if either `from_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `from_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.from_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | +| `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.

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 initial arrival event should be used for timezone resolution, where appropriate.

For a fare leg rule that specifies a `to_timeframe_group_id`, that rule will match a particular leg if either `to_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `to_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.to_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `timeframe_type` | Enum | **Conditionally Required** | Defines the type of fare validation to be associated with `timeframes.start_time` and `timeframes.end_time`.

Valid options are:
`0` - In vehicle.
`1` - At fare gate or on platform.

Conditionally Required:
- **Required** if either `start_timeframe_group_id` or `end_timeframe_group_id` is defined.
- **Forbidden** otherwise.| | `fare_product_id` | Foreign ID referencing `fare_products.fare_product_id` | **Required** | The fare product required to travel the leg. | | `override` | Non-negative integer | Optional | Allows certain rules to take precedence over others. When multiple entries in `fare_leg_rules.txt` match, the rule or set of rules with the highest value for `override` will be selected.

An empty value for `override` is treated as zero.| From ad54f36c962a1ed80643dec1a7033ca65e9855a6 Mon Sep 17 00:00:00 2001 From: Tzu-Jen Chan <126435471+tzujenchanmbd@users.noreply.github.com> Date: Wed, 24 May 2023 17:33:38 -0400 Subject: [PATCH 35/41] Remove timeframe_type & priority fields Changes as discussed in working group meeting --- gtfs/spec/en/reference.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 140e5cbd8..fe531c7fc 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -439,9 +439,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_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.

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 initial departure event should be used for timezone resolution, where appropriate.

For a fare leg rule that specifies a `from_timeframe_group_id`, that rule will match a particular leg if either `from_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `from_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.from_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | | `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.

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 initial arrival event should be used for timezone resolution, where appropriate.

For a fare leg rule that specifies a `to_timeframe_group_id`, that rule will match a particular leg if either `to_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `to_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.to_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | -| `timeframe_type` | Enum | **Conditionally Required** | Defines the type of fare validation to be associated with `timeframes.start_time` and `timeframes.end_time`.

Valid options are:
`0` - In vehicle.
`1` - At fare gate or on platform.

Conditionally Required:
- **Required** if either `start_timeframe_group_id` or `end_timeframe_group_id` is defined.
- **Forbidden** otherwise.| | `fare_product_id` | Foreign ID referencing `fare_products.fare_product_id` | **Required** | The fare product required to travel the leg. | -| `override` | Non-negative integer | Optional | Allows certain rules to take precedence over others. When multiple entries in `fare_leg_rules.txt` match, the rule or set of rules with the highest value for `override` will be selected.

An empty value for `override` is treated as zero.| ### fare_transfer_rules.txt From 518578b178b412e80178cf1c7262cfa8605c7ff2 Mon Sep 17 00:00:00 2001 From: Tzu-Jen Chan <126435471+tzujenchanmbd@users.noreply.github.com> Date: Thu, 25 May 2023 15:06:49 -0400 Subject: [PATCH 36/41] revise "start" to "end" --- gtfs/spec/en/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index fe531c7fc..0a4bc1f13 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -438,7 +438,7 @@ To process the cost of a leg: | `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_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.

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 initial departure event should be used for timezone resolution, where appropriate.

For a fare leg rule that specifies a `from_timeframe_group_id`, that rule will match a particular leg if either `from_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `from_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.from_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | -| `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.

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 initial arrival event should be used for timezone resolution, where appropriate.

For a fare leg rule that specifies a `to_timeframe_group_id`, that rule will match a particular leg if either `to_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `to_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.to_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | +| `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.

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 initial arrival event should be used for timezone resolution, where appropriate.

For a fare leg rule that specifies a `to_timeframe_group_id`, that rule will match a particular leg if either `to_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `to_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s end time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.to_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `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 f33a935fc7070049c63af83fa504d9beb991e79c Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Sun, 25 Jun 2023 18:00:53 -0400 Subject: [PATCH 37/41] Remove "initial" after Gavriel's comment Gavriel pointed out in the proposal document that "initial" is un-necessary https://docs.google.com/document/d/1N3WpgAh2OxPuE5Vvjbd6mjvKK42M7mSVdxscVvzP8SU/edit --- gtfs/spec/en/reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 0a4bc1f13..434de451f 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -437,8 +437,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_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.

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 initial departure event should be used for timezone resolution, where appropriate.

For a fare leg rule that specifies a `from_timeframe_group_id`, that rule will match a particular leg if either `from_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `from_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.from_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | -| `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.

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 initial arrival event should be used for timezone resolution, where appropriate.

For a fare leg rule that specifies a `to_timeframe_group_id`, that rule will match a particular leg if either `to_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `to_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s end time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.to_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | +| `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.

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.

For a fare leg rule that specifies a `from_timeframe_group_id`, that rule will match a particular leg if either `from_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `from_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.from_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | +| `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.

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.

For a fare leg rule that specifies a `to_timeframe_group_id`, that rule will match a particular leg if either `to_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `to_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s end time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.to_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `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 4bf749f39c93d16a00d072669864e08b1b8e1abe Mon Sep 17 00:00:00 2001 From: Tzu-Jen Chan <126435471+tzujenchanmbd@users.noreply.github.com> Date: Wed, 19 Jul 2023 11:16:25 -0400 Subject: [PATCH 38/41] Remove unnecessary empty description --- gtfs/spec/en/reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 434de451f..03e694ab8 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -437,8 +437,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_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.

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.

For a fare leg rule that specifies a `from_timeframe_group_id`, that rule will match a particular leg if either `from_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `from_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.from_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | -| `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.

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.

For a fare leg rule that specifies a `to_timeframe_group_id`, that rule will match a particular leg if either `to_timeframe_group_id` is empty, or if there exists at least one row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `to_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s end time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.to_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | +| `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.

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.

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 row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `from_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.from_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | +| `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.

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.

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 row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `to_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s end time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.to_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `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 0007c89a85f16469dc6e6154a68eea012edfd2b9 Mon Sep 17 00:00:00 2001 From: Tzu-Jen Chan <126435471+tzujenchanmbd@users.noreply.github.com> Date: Thu, 20 Jul 2023 12:07:06 -0400 Subject: [PATCH 39/41] Changes based on Jeremy's feedback Comment https://github.com/google/transit/pull/357#discussion_r1267080408 1. Specify "time of day" of fare leg's start/end time 2. Clarify the start_time/end_time are in timeframes.txt Additional: change "row" to " "record" to synchronize the rest of GTFS. --- gtfs/spec/en/reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 03e694ab8..87e291f31 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -437,8 +437,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_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.

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.

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 row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `from_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s start time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.from_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | -| `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.

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.

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 row in `timeframes.txt` where all of the following conditions are true
- The row’s `timeframe_group_id` is equal to the `to_timeframe_group_id` value.
- The set of days identified by the row’s `service_id` contains the “current day” of the fare leg’s end time.
- The fare leg’s “time-of-day” is greater than or equal to the row’s `start_time` value and less than the `end_time` value.

An empty `fare_leg_rules.to_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | +| `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.

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.

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
- The value of `timeframe_group_id` is equal to the `from_timeframe_group_id` value.
- The set of days identified by the record’s `service_id` contains the “current day” of the fare leg’s start time.
- 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.

An empty `fare_leg_rules.from_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | +| `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.

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.

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
- The value of `timeframe_group_id` is equal to the `to_timeframe_group_id` value.
- The set of days identified by the record’s `service_id` contains the “current day” of the fare leg’s end time.
- 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.

An empty `fare_leg_rules.to_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | | `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 1a65d75c0dc1954d7a8278bf99d00e965f742331 Mon Sep 17 00:00:00 2001 From: Tzu-Jen Chan <126435471+tzujenchanmbd@users.noreply.github.com> Date: Thu, 20 Jul 2023 14:14:27 -0400 Subject: [PATCH 40/41] Modify empty wording Based on Hal's suggestion - https://github.com/google/transit/pull/357#issuecomment-1644360575 --- gtfs/spec/en/reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 87e291f31..94467b763 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -437,8 +437,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_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.

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.

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
- The value of `timeframe_group_id` is equal to the `from_timeframe_group_id` value.
- The set of days identified by the record’s `service_id` contains the “current day” of the fare leg’s start time.
- 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.

An empty `fare_leg_rules.from_timeframe_group_id` indicates that the start time of the leg does not affect the fare. | -| `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.

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.

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
- The value of `timeframe_group_id` is equal to the `to_timeframe_group_id` value.
- The set of days identified by the record’s `service_id` contains the “current day” of the fare leg’s end time.
- 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.

An empty `fare_leg_rules.to_timeframe_group_id` indicates that the end time of the leg does not affect the fare. | +| `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.

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.

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
- The value of `timeframe_group_id` is equal to the `from_timeframe_group_id` value.
- The set of days identified by the record’s `service_id` contains the “current day” of the fare leg’s start time.
- 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.

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.

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.

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
- The value of `timeframe_group_id` is equal to the `to_timeframe_group_id` value.
- The set of days identified by the record’s `service_id` contains the “current day” of the fare leg’s end time.
- 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.

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 From 12c3bb7d270cedd80524f99cd8b7f52d454497d3 Mon Sep 17 00:00:00 2001 From: isabelle-dr Date: Thu, 27 Jul 2023 08:17:22 -0400 Subject: [PATCH 41/41] Move overlapping requirement out of service_id description --- gtfs/spec/en/reference.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gtfs/spec/en/reference.md b/gtfs/spec/en/reference.md index 94467b763..9690703d9 100644 --- a/gtfs/spec/en/reference.md +++ b/gtfs/spec/en/reference.md @@ -353,14 +353,15 @@ 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`. +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`.
+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.
Values greater than `24:00:00` are forbidden. An empty value in `start_time` is considered `00:00:00`.

Conditionally Required:
- **Required** if `timeframes.end_time` is defined.
- Forbidden otherwise | -| `end_time` | Time | **Conditionally Required** | Defines the end of a timeframe. The interval does not include the end time.
Values greater than `24:00:00` are forbidden. An empty value in `end_time` is considered `24:00:00`.

Conditionally Required:
- **Required** if `timeframes.start_time` is defined.
- 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.
There must not be overlapping time intervals for the same `timeframe_group_id` and `service_id` values. | +| `start_time` | Time | **Conditionally Required** | Defines the beginning of a timeframe. The interval includes the start time.
Values greater than `24:00:00` are forbidden. An empty value in `start_time` is considered `00:00:00`.

Conditionally Required:
- **Required** if `timeframes.end_time` is defined.
- **Forbidden** otherwise | +| `end_time` | Time | **Conditionally Required** | Defines the end of a timeframe. The interval does not include the end time.
Values greater than `24:00:00` are forbidden. An empty value in `end_time` is considered `24:00:00`.

Conditionally Required:
- **Required** if `timeframes.start_time` is defined.
- **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.