From 552b6a3f7677bef890ae46c5b966e11395091d07 Mon Sep 17 00:00:00 2001 From: Justin Mazur Date: Sun, 13 Sep 2026 02:41:55 -0400 Subject: [PATCH] Add consistent _utc and _local date helpers A project I am working on assumed every time-shaped field returned a Time-like object, because most of the gem's resource classes expose a conversion helper (`_utc`) for their time fields, letting a consumer avoid ever touching the raw value directly. A few classes had no helper at all, leaving their raw, unconverted strings as the only way to read the field, an easy trap for exactly the assumption that caused the bug. Separately, no class anywhere in the gem exposed a proper local-zoned Time either, despite every one of these fields already being local Toronto time as returned by the API, so a consumer wanting that representation had to parse the raw string themselves, the same class of manual work that went wrong in the first place. This change addresses the need by: * Adding a shared `to_local` helper to ApiResource, alongside the existing `to_utc`, both built on the same `in_time_zone` call * Adding `_utc` to the six classes that had no time-conversion helper at all (including Schedule::Line::Trip::Stop, the exact class that caused the my_go_api incident) * Adding `_local` to every time field across the gem, all fifteen classes, so every one now has both a UTC and a Toronto-zoned accessor, not just some of them * Updating the README's own claim (previously inaccurate) that every date and time field has a UTC conversion method * Leaving Schedule::Journey::SchJourney's date/time pair untouched, documented inline: it splits a moment across two fields rather than one combined string, and no real API response was available to confirm either field's exact format before assuming one --- .rubocop.yml | 2 + Gemfile.lock | 2 +- lib/go_transit/api_resource.rb | 6 ++- lib/go_transit/resources/metadata.rb | 4 ++ .../resources/schedule/journey/sch_journey.rb | 2 +- .../schedule/journey/sch_journey/service.rb | 8 ++++ .../journey/sch_journey/service/transfer.rb | 2 +- .../resources/schedule/line/trip/stop.rb | 8 ++++ lib/go_transit/resources/schedule/trip.rb | 4 ++ .../schedule/trip/stop/arrival_time.rb | 8 ---- .../schedule/trip/stop/departure_time.rb | 8 ---- .../resources/service_at_a_glance/trip.rb | 4 ++ .../resources/service_update/message.rb | 4 ++ .../service_update/union_departures/trip.rb | 4 ++ .../resources/stop/next_service/line.rb | 12 +++++ lib/go_transit/version.rb | 2 +- readme.md | 21 ++++++--- spec/resources/metadata_spec.rb | 13 ++++++ .../sch_journey/service/trip/stop_spec.rb | 23 ++++++++++ .../journey/sch_journey/service_spec.rb | 30 +++++++++++++ .../resources/schedule/line/trip/stop_spec.rb | 45 +++++++++++++++++++ .../schedule/trip/stop/arrival_time_spec.rb | 31 ------------- .../schedule/trip/stop/departure_time_spec.rb | 31 ------------- spec/resources/schedule/trip_spec.rb | 27 +++++++++++ .../service_at_a_glance/trip_spec.rb | 15 +++++++ spec/resources/service_update/message_spec.rb | 15 +++++++ .../union_departures/trip_spec.rb | 15 +++++++ spec/resources/stop/next_service/line_spec.rb | 45 +++++++++++++++++++ 28 files changed, 303 insertions(+), 88 deletions(-) create mode 100644 .rubocop.yml create mode 100644 spec/resources/schedule/journey/sch_journey/service/trip/stop_spec.rb create mode 100644 spec/resources/schedule/line/trip/stop_spec.rb delete mode 100644 spec/resources/schedule/trip/stop/arrival_time_spec.rb delete mode 100644 spec/resources/schedule/trip/stop/departure_time_spec.rb create mode 100644 spec/resources/schedule/trip_spec.rb diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..17102f4 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,2 @@ +Style/StringLiterals: + Enabled: false diff --git a/Gemfile.lock b/Gemfile.lock index 2dd918d..4b234ec 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - go_transit (1.1.0) + go_transit (1.2.0) activesupport GEM diff --git a/lib/go_transit/api_resource.rb b/lib/go_transit/api_resource.rb index b0c4dcd..11a65a7 100644 --- a/lib/go_transit/api_resource.rb +++ b/lib/go_transit/api_resource.rb @@ -42,7 +42,11 @@ def collection?(value) end def to_utc(date) - date.in_time_zone("America/Toronto").utc + to_local(date).utc + end + + def to_local(date, timezone: "America/Toronto") + date.in_time_zone(timezone) end end end diff --git a/lib/go_transit/resources/metadata.rb b/lib/go_transit/resources/metadata.rb index 31443fc..005abb9 100644 --- a/lib/go_transit/resources/metadata.rb +++ b/lib/go_transit/resources/metadata.rb @@ -13,5 +13,9 @@ def code def time_stamp_utc to_utc(time_stamp) end + + def time_stamp_local + to_local(time_stamp) + end end end diff --git a/lib/go_transit/resources/schedule/journey/sch_journey.rb b/lib/go_transit/resources/schedule/journey/sch_journey.rb index 0168c73..02164cb 100644 --- a/lib/go_transit/resources/schedule/journey/sch_journey.rb +++ b/lib/go_transit/resources/schedule/journey/sch_journey.rb @@ -2,4 +2,4 @@ module GoTransit class Schedule::Journey::SchJourney < ApiResource attr_accessor :date, :time, :to, :from, :services end -end \ No newline at end of file +end diff --git a/lib/go_transit/resources/schedule/journey/sch_journey/service.rb b/lib/go_transit/resources/schedule/journey/sch_journey/service.rb index 1bb0e92..2ebfc2b 100644 --- a/lib/go_transit/resources/schedule/journey/sch_journey/service.rb +++ b/lib/go_transit/resources/schedule/journey/sch_journey/service.rb @@ -13,5 +13,13 @@ def start_time_utc def end_time_utc to_utc(end_time) end + + def start_time_local + to_local(start_time) + end + + def end_time_local + to_local(end_time) + end end end diff --git a/lib/go_transit/resources/schedule/journey/sch_journey/service/transfer.rb b/lib/go_transit/resources/schedule/journey/sch_journey/service/transfer.rb index 6b1f297..0ab45ca 100644 --- a/lib/go_transit/resources/schedule/journey/sch_journey/service/transfer.rb +++ b/lib/go_transit/resources/schedule/journey/sch_journey/service/transfer.rb @@ -2,4 +2,4 @@ module GoTransit class Schedule::Journey::SchJourney::Service::Transfer < ApiResource attr_accessor :code, :order, :time end -end \ No newline at end of file +end diff --git a/lib/go_transit/resources/schedule/line/trip/stop.rb b/lib/go_transit/resources/schedule/line/trip/stop.rb index 23e770e..f4959ae 100644 --- a/lib/go_transit/resources/schedule/line/trip/stop.rb +++ b/lib/go_transit/resources/schedule/line/trip/stop.rb @@ -5,5 +5,13 @@ class Schedule::Line::Trip::Stop < ApiResource def major? is_major.to_i.positive? end + + def time_utc + to_utc(time) + end + + def time_local + to_local(time) + end end end \ No newline at end of file diff --git a/lib/go_transit/resources/schedule/trip.rb b/lib/go_transit/resources/schedule/trip.rb index e36797c..b1d08de 100644 --- a/lib/go_transit/resources/schedule/trip.rb +++ b/lib/go_transit/resources/schedule/trip.rb @@ -6,5 +6,9 @@ class Schedule::Trip < ApiResource def time_stamp_utc to_utc(time_stamp) end + + def time_stamp_local + to_local(time_stamp) + end end end diff --git a/lib/go_transit/resources/schedule/trip/stop/arrival_time.rb b/lib/go_transit/resources/schedule/trip/stop/arrival_time.rb index 613d458..ec12d9b 100644 --- a/lib/go_transit/resources/schedule/trip/stop/arrival_time.rb +++ b/lib/go_transit/resources/schedule/trip/stop/arrival_time.rb @@ -1,13 +1,5 @@ module GoTransit class Schedule::Trip::Stop::ArrivalTime < ApiResource attr_accessor :scheduled, :computed, :status - - def scheduled_utc - to_utc(scheduled) - end - - def computed_utc - to_utc(computed) - end end end diff --git a/lib/go_transit/resources/schedule/trip/stop/departure_time.rb b/lib/go_transit/resources/schedule/trip/stop/departure_time.rb index 632734e..0cb4647 100644 --- a/lib/go_transit/resources/schedule/trip/stop/departure_time.rb +++ b/lib/go_transit/resources/schedule/trip/stop/departure_time.rb @@ -1,13 +1,5 @@ module GoTransit class Schedule::Trip::Stop::DepartureTime < ApiResource attr_accessor :scheduled, :computed, :status - - def scheduled_utc - to_utc(scheduled) - end - - def computed_utc - to_utc(computed) - end end end diff --git a/lib/go_transit/resources/service_at_a_glance/trip.rb b/lib/go_transit/resources/service_at_a_glance/trip.rb index 337521b..97d1e7f 100644 --- a/lib/go_transit/resources/service_at_a_glance/trip.rb +++ b/lib/go_transit/resources/service_at_a_glance/trip.rb @@ -14,5 +14,9 @@ def in_motion? def modified_date_utc to_utc(modified_date) end + + def modified_date_local + to_local(modified_date) + end end end diff --git a/lib/go_transit/resources/service_update/message.rb b/lib/go_transit/resources/service_update/message.rb index 4658f1b..c3aa058 100644 --- a/lib/go_transit/resources/service_update/message.rb +++ b/lib/go_transit/resources/service_update/message.rb @@ -7,5 +7,9 @@ class ServiceUpdate::Message < ApiResource def posted_date_time_utc to_utc(posted_date_time) end + + def posted_date_time_local + to_local(posted_date_time) + end end end diff --git a/lib/go_transit/resources/service_update/union_departures/trip.rb b/lib/go_transit/resources/service_update/union_departures/trip.rb index 1b6df4c..fe6c6e1 100644 --- a/lib/go_transit/resources/service_update/union_departures/trip.rb +++ b/lib/go_transit/resources/service_update/union_departures/trip.rb @@ -11,5 +11,9 @@ def platforms def time_utc to_utc(time) end + + def time_local + to_local(time) + end end end diff --git a/lib/go_transit/resources/stop/next_service/line.rb b/lib/go_transit/resources/stop/next_service/line.rb index a147e36..db98388 100644 --- a/lib/go_transit/resources/stop/next_service/line.rb +++ b/lib/go_transit/resources/stop/next_service/line.rb @@ -18,5 +18,17 @@ def computed_departure_time_utc def update_time_utc to_utc(update_time) end + + def scheduled_departure_time_local + to_local(scheduled_departure_time) + end + + def computed_departure_time_local + to_local(computed_departure_time) + end + + def update_time_local + to_local(update_time) + end end end diff --git a/lib/go_transit/version.rb b/lib/go_transit/version.rb index d3119e8..5814574 100644 --- a/lib/go_transit/version.rb +++ b/lib/go_transit/version.rb @@ -1,3 +1,3 @@ module GoTransit - VERSION = "1.1.0".freeze + VERSION = "1.2.0".freeze end diff --git a/readme.md b/readme.md index 17d35c8..ba28479 100644 --- a/readme.md +++ b/readme.md @@ -75,12 +75,22 @@ This gem exposes the Go Transit API endpoints and hydrates objects related to th ## Dates & Times All dates & times returned from the GO Transit API are in the `America/Toronto` -timezone. All date and time fields have an additional method to convert into -UTC. For example `departure_time_utc` on a stop will return the regular -`departure_time` converted unto UTC. +timezone, returned as plain, unconverted strings, exactly as the API sent +them. Every date and time field has two additional methods: `_utc` +converts it into a UTC `Time`, and `_local` returns it as a proper +`ActiveSupport::TimeWithZone` in `America/Toronto`, without shifting the +value itself. For example, `departure_time_utc` on a stop returns the +regular `departure_time` converted to UTC, and `departure_time_local` +returns the same time zoned to Toronto instead. ## Missing Test Data -At the time of development I was unable to get test data for the following endpoints. Some of these seem like they are restricted access endpoints and my key is unable to fetch any data. I'm not sure if the others are caused by API issues. These endpoints *should* work assuming the documenation is correct, but the lack of data means testing was not possible. If you are able to get data for these endpoints please open a PR and submit it, it would greatly help development. +At the time of development I was unable to get test data for the following +endpoints. Some of these seem like they are restricted access endpoints and my +key is unable to fetch any data. I'm not sure if the others are caused by API +issues. These endpoints *should* work assuming the documenation is correct, but +the lack of data means testing was not possible. If you are able to get data for +these endpoints please open a PR and submit it, it would greatly help +development. * `GET api/V1/ServiceataGlance/UPX/All` - 204 No Content * `GET api/V1/ServiceUpdate/ServiceGuarantee/{TripNumber}/{OperationalDay}` - 204 No Content @@ -89,7 +99,8 @@ At the time of development I was unable to get test data for the following endpo * `GET api/V1/Fleet/Consist/Engine/{EngineNumber}` - 403 Forbidden ## Changing the API base url -In some cases you may want to change the base go transit API url. You can use the `custom_base_url` config to set one: +In some cases you may want to change the base go transit API url. You can use +the `custom_base_url` config to set one: ```ruby GoTransit.configure do |config| diff --git a/spec/resources/metadata_spec.rb b/spec/resources/metadata_spec.rb index b65a169..c5dd2fe 100644 --- a/spec/resources/metadata_spec.rb +++ b/spec/resources/metadata_spec.rb @@ -37,4 +37,17 @@ end end end + + describe "#time_stamp_local" do + it "returns the timestamp zoned to toronto time, unshifted" do + Timecop.travel("2023-09-14") do + toronto_time = "2023-09-14 12:00:00" + metadata = GoTransit::Metadata.new(time_stamp: toronto_time) + + result = metadata.time_stamp_local + + expect(result).to eq(toronto_time.in_time_zone("America/Toronto")) + end + end + end end diff --git a/spec/resources/schedule/journey/sch_journey/service/trip/stop_spec.rb b/spec/resources/schedule/journey/sch_journey/service/trip/stop_spec.rb new file mode 100644 index 0000000..f94dded --- /dev/null +++ b/spec/resources/schedule/journey/sch_journey/service/trip/stop_spec.rb @@ -0,0 +1,23 @@ +RSpec.describe GoTransit::Schedule::Journey::SchJourney::Service::Trip::Stop do + describe "#major?" do + context "when is_major is 1" do + it "is major" do + stop = GoTransit::Schedule::Journey::SchJourney::Service::Trip::Stop.new( + is_major: "1" + ) + + expect(stop).to be_major + end + end + + context "when is_major is not 1" do + it "is not major" do + stop = GoTransit::Schedule::Journey::SchJourney::Service::Trip::Stop.new( + is_major: "0" + ) + + expect(stop).not_to be_major + end + end + end +end diff --git a/spec/resources/schedule/journey/sch_journey/service_spec.rb b/spec/resources/schedule/journey/sch_journey/service_spec.rb index 4879a1c..b6d618c 100644 --- a/spec/resources/schedule/journey/sch_journey/service_spec.rb +++ b/spec/resources/schedule/journey/sch_journey/service_spec.rb @@ -28,4 +28,34 @@ end end end + + describe "#start_time_local" do + it "returns the timestamp zoned to toronto time, unshifted" do + Timecop.travel("2023-09-14") do + toronto_time = "2023-09-17 12:00:00" + service = GoTransit::Schedule::Journey::SchJourney::Service.new( + start_time: toronto_time + ) + + result = service.start_time_local + + expect(result).to eq(toronto_time.in_time_zone("America/Toronto")) + end + end + end + + describe "#end_time_local" do + it "returns the timestamp zoned to toronto time, unshifted" do + Timecop.travel("2023-09-14") do + toronto_time = "2023-09-17 12:00:00" + service = GoTransit::Schedule::Journey::SchJourney::Service.new( + end_time: toronto_time + ) + + result = service.end_time_local + + expect(result).to eq(toronto_time.in_time_zone("America/Toronto")) + end + end + end end diff --git a/spec/resources/schedule/line/trip/stop_spec.rb b/spec/resources/schedule/line/trip/stop_spec.rb new file mode 100644 index 0000000..f71d8a6 --- /dev/null +++ b/spec/resources/schedule/line/trip/stop_spec.rb @@ -0,0 +1,45 @@ +RSpec.describe GoTransit::Schedule::Line::Trip::Stop do + describe "#major?" do + context "when is_major is 1" do + it "is major" do + stop = GoTransit::Schedule::Line::Trip::Stop.new(is_major: "1") + + expect(stop).to be_major + end + end + + context "when is_major is not 1" do + it "is not major" do + stop = GoTransit::Schedule::Line::Trip::Stop.new(is_major: "0") + + expect(stop).not_to be_major + end + end + end + + describe "#time_utc" do + it "converts the timestamp from toronto time to UTC time" do + Timecop.travel("2023-09-14") do + toronto_time = "2023-09-17 12:00:00" + stop = GoTransit::Schedule::Line::Trip::Stop.new(time: toronto_time) + + result = stop.time_utc + + expect(result).to eq("2023-09-17 16:00:00".to_datetime) + end + end + end + + describe "#time_local" do + it "returns the timestamp zoned to toronto time, unshifted" do + Timecop.travel("2023-09-14") do + toronto_time = "2023-09-17 12:00:00" + stop = GoTransit::Schedule::Line::Trip::Stop.new(time: toronto_time) + + result = stop.time_local + + expect(result).to eq(toronto_time.in_time_zone("America/Toronto")) + end + end + end +end diff --git a/spec/resources/schedule/trip/stop/arrival_time_spec.rb b/spec/resources/schedule/trip/stop/arrival_time_spec.rb deleted file mode 100644 index db5c5b0..0000000 --- a/spec/resources/schedule/trip/stop/arrival_time_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -RSpec.describe GoTransit::Schedule::Trip::Stop::ArrivalTime do - describe "#scheduled_utc" do - it "converts the timestamp from toronto time to UTC time" do - Timecop.travel("2023-09-14") do - toronto_time = "2023-09-17 12:00:00" - service = GoTransit::Schedule::Trip::Stop::ArrivalTime.new( - scheduled: toronto_time - ) - - result = service.scheduled_utc - - expect(result).to eq("2023-09-17 16:00:00".to_datetime) - end - end - end - - describe "#computed_utc" do - it "converts the timestamp from toronto time to UTC time" do - Timecop.travel("2023-09-14") do - toronto_time = "2023-09-17 12:00:00" - service = GoTransit::Schedule::Trip::Stop::ArrivalTime.new( - computed: toronto_time - ) - - result = service.computed_utc - - expect(result).to eq("2023-09-17 16:00:00".to_datetime) - end - end - end -end diff --git a/spec/resources/schedule/trip/stop/departure_time_spec.rb b/spec/resources/schedule/trip/stop/departure_time_spec.rb deleted file mode 100644 index 4c4bb65..0000000 --- a/spec/resources/schedule/trip/stop/departure_time_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -RSpec.describe GoTransit::Schedule::Trip::Stop::DepartureTime do - describe "#scheduled_utc" do - it "converts the timestamp from toronto time to UTC time" do - Timecop.travel("2023-09-14") do - toronto_time = "2023-09-17 12:00:00" - service = GoTransit::Schedule::Trip::Stop::DepartureTime.new( - scheduled: toronto_time - ) - - result = service.scheduled_utc - - expect(result).to eq("2023-09-17 16:00:00".to_datetime) - end - end - end - - describe "#computed_utc" do - it "converts the timestamp from toronto time to UTC time" do - Timecop.travel("2023-09-14") do - toronto_time = "2023-09-17 12:00:00" - service = GoTransit::Schedule::Trip::Stop::DepartureTime.new( - computed: toronto_time - ) - - result = service.computed_utc - - expect(result).to eq("2023-09-17 16:00:00".to_datetime) - end - end - end -end diff --git a/spec/resources/schedule/trip_spec.rb b/spec/resources/schedule/trip_spec.rb new file mode 100644 index 0000000..bc50184 --- /dev/null +++ b/spec/resources/schedule/trip_spec.rb @@ -0,0 +1,27 @@ +RSpec.describe GoTransit::Schedule::Trip do + describe "#time_stamp_utc" do + it "converts the timestamp from toronto time to UTC time" do + Timecop.travel("2023-09-14") do + toronto_time = "2023-09-17 12:00:00" + trip = GoTransit::Schedule::Trip.new(time_stamp: toronto_time) + + result = trip.time_stamp_utc + + expect(result).to eq("2023-09-17 16:00:00".to_datetime) + end + end + end + + describe "#time_stamp_local" do + it "returns the timestamp zoned to toronto time, unshifted" do + Timecop.travel("2023-09-14") do + toronto_time = "2023-09-17 12:00:00" + trip = GoTransit::Schedule::Trip.new(time_stamp: toronto_time) + + result = trip.time_stamp_local + + expect(result).to eq(toronto_time.in_time_zone("America/Toronto")) + end + end + end +end diff --git a/spec/resources/service_at_a_glance/trip_spec.rb b/spec/resources/service_at_a_glance/trip_spec.rb index 0bbfa44..0fa7a08 100644 --- a/spec/resources/service_at_a_glance/trip_spec.rb +++ b/spec/resources/service_at_a_glance/trip_spec.rb @@ -31,4 +31,19 @@ end end end + + describe "#modified_date_local" do + it "returns the timestamp zoned to toronto time, unshifted" do + Timecop.travel("2023-09-14") do + toronto_time = "2023-09-17 12:00:00" + service = GoTransit::ServiceAtAGlance::Trip.new( + modified_date: toronto_time + ) + + result = service.modified_date_local + + expect(result).to eq(toronto_time.in_time_zone("America/Toronto")) + end + end + end end diff --git a/spec/resources/service_update/message_spec.rb b/spec/resources/service_update/message_spec.rb index 3fb3cf0..c3cf9d7 100644 --- a/spec/resources/service_update/message_spec.rb +++ b/spec/resources/service_update/message_spec.rb @@ -13,4 +13,19 @@ end end end + + describe "#posted_date_time_local" do + it "returns the timestamp zoned to toronto time, unshifted" do + Timecop.travel("2023-09-14") do + toronto_time = "2023-09-17 12:00:00" + service = GoTransit::ServiceUpdate::Message.new( + posted_date_time: toronto_time + ) + + result = service.posted_date_time_local + + expect(result).to eq(toronto_time.in_time_zone("America/Toronto")) + end + end + end end diff --git a/spec/resources/service_update/union_departures/trip_spec.rb b/spec/resources/service_update/union_departures/trip_spec.rb index be6142e..310a1a1 100644 --- a/spec/resources/service_update/union_departures/trip_spec.rb +++ b/spec/resources/service_update/union_departures/trip_spec.rb @@ -33,4 +33,19 @@ end end end + + describe "#time_local" do + it "returns the timestamp zoned to toronto time, unshifted" do + Timecop.travel("2023-09-14") do + toronto_time = "2023-09-17 12:00:00" + service = GoTransit::ServiceUpdate::UnionDepartures::Trip.new( + time: toronto_time + ) + + result = service.time_local + + expect(result).to eq(toronto_time.in_time_zone("America/Toronto")) + end + end + end end diff --git a/spec/resources/stop/next_service/line_spec.rb b/spec/resources/stop/next_service/line_spec.rb index 4b9f250..d4dcd4c 100644 --- a/spec/resources/stop/next_service/line_spec.rb +++ b/spec/resources/stop/next_service/line_spec.rb @@ -43,4 +43,49 @@ end end end + + describe "#scheduled_departure_time_local" do + it "returns the timestamp zoned to toronto time, unshifted" do + Timecop.travel("2023-09-14") do + toronto_time = "2023-09-17 12:00:00" + service = GoTransit::Stop::NextService::Line.new( + scheduled_departure_time: toronto_time + ) + + result = service.scheduled_departure_time_local + + expect(result).to eq(toronto_time.in_time_zone("America/Toronto")) + end + end + end + + describe "#computed_departure_time_local" do + it "returns the timestamp zoned to toronto time, unshifted" do + Timecop.travel("2023-09-14") do + toronto_time = "2023-09-17 12:00:00" + service = GoTransit::Stop::NextService::Line.new( + computed_departure_time: toronto_time + ) + + result = service.computed_departure_time_local + + expect(result).to eq(toronto_time.in_time_zone("America/Toronto")) + end + end + end + + describe "#update_time_local" do + it "returns the timestamp zoned to toronto time, unshifted" do + Timecop.travel("2023-09-14") do + toronto_time = "2023-09-17 12:00:00" + service = GoTransit::Stop::NextService::Line.new( + update_time: toronto_time + ) + + result = service.update_time_local + + expect(result).to eq(toronto_time.in_time_zone("America/Toronto")) + end + end + end end