From e0077ec13bb4c82a7de6a2a8089f638d378e34b6 Mon Sep 17 00:00:00 2001 From: Tony Bark <35226681+tonytins@users.noreply.github.com> Date: Mon, 24 Aug 2026 21:05:11 -0400 Subject: [PATCH] Centralize lateness logic - I finally put the app in the Travel category. xD - I also moved the train lateness and arrival calculations into AmtrakDateFormatting from ContentView. I also renamed the timezone formatting parameters for clarity. --- Bundler.toml | 2 ++ .../AmtrakStatus/AmtrakDateFormatting.swift | 35 +++++++++++++++---- Sources/AmtrakStatus/ContentView.swift | 35 ++++--------------- 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/Bundler.toml b/Bundler.toml index 142cdbf..f8a1d93 100644 --- a/Bundler.toml +++ b/Bundler.toml @@ -1,3 +1,4 @@ +# https://swiftbundler.dev/documentation/swift-bundler/configuration format_version = 2 [apps.AmtrakStatus] @@ -5,6 +6,7 @@ identifier = 'com.tonybark.AmtrakStatus' product = 'AmtrakStatus' version = '0.2.103' icon = "./assets/icon.png" +category = "public.app-category.travel" [[apps.AmtrakStatus.overlays]] diff --git a/Sources/AmtrakStatus/AmtrakDateFormatting.swift b/Sources/AmtrakStatus/AmtrakDateFormatting.swift index 98042ec..34452cb 100644 --- a/Sources/AmtrakStatus/AmtrakDateFormatting.swift +++ b/Sources/AmtrakStatus/AmtrakDateFormatting.swift @@ -26,21 +26,21 @@ struct AmtrakDateFormatting { return isoFormatter.date(from: isoString) } - func time(from isoString: String?, timeZone: TimeZone?, relativeTo otherZone: TimeZone? = nil) -> String? { + func time(from isoString: String?, in zone: TimeZone?, comparedTo originZone: TimeZone? = nil) -> String? { guard let isoString, !isoString.isEmpty, let date = isoFormatter.date( from: isoString) else { return nil } - timeFormatter.timeZone = timeZone + timeFormatter.timeZone = zone let formatted = timeFormatter.string(from: date) guard - let timeZone, - let otherZone, - timeZone.identifier != otherZone.identifier, - let abbreviation = timeZone.abbreviation(for: date) + let zone, + let originZone, + zone.identifier != originZone.identifier, + let abbreviation = zone.abbreviation(for: date) else { return formatted } @@ -48,6 +48,29 @@ struct AmtrakDateFormatting { return "\(formatted) \(abbreviation)" } + + func isOnTime(actual: String?, scheduled: String?) -> TrainLateness { + + guard + let actualDate = parsedDate(from: actual), + let scheduledDate = parsedDate(from: scheduled) + else { + return .unknown + } + + let differenceInMinutes = Int(actualDate.timeIntervalSince(scheduledDate) / 60) + + switch differenceInMinutes { + case -1...1: + return .onTime + case ..<0: + return .early(minutes: -differenceInMinutes) + default: + return .late(minutes: differenceInMinutes) + } + } + + func localTime(timeZone: TimeZone?) -> String { let now = Date() timeFormatter.timeZone = timeZone diff --git a/Sources/AmtrakStatus/ContentView.swift b/Sources/AmtrakStatus/ContentView.swift index 08c3708..507cbe7 100644 --- a/Sources/AmtrakStatus/ContentView.swift +++ b/Sources/AmtrakStatus/ContentView.swift @@ -169,27 +169,6 @@ struct ContentView: View { } } - func isOnTime(arr: String?, schArr: String?) -> TrainLateness { - - guard - let actualDate = amtrakDate.parsedDate(from: arr), - let scheduledDate = amtrakDate.parsedDate(from: schArr) - else { - return .unknown - } - - let differenceInMinutes = Int(actualDate.timeIntervalSince(scheduledDate) / 60) - - switch differenceInMinutes { - case -1...1: - return .onTime - case ..<0: - return .early(minutes: -differenceInMinutes) - default: - return .late(minutes: differenceInMinutes) - } - } - func trainStatus( for train: Train, atStationCode code: String, @@ -210,12 +189,12 @@ struct ContentView: View { let time = amtrakDate.time( from: leg?.arr, - timeZone: timeZone, - relativeTo: originZone + in: timeZone, + comparedTo: originZone ) ?? amtrakDate.time( from: leg?.schArr, - timeZone: timeZone, - relativeTo: originZone + in: timeZone, + comparedTo: originZone ) currentStation = stationName @@ -229,9 +208,9 @@ struct ContentView: View { train: train.routeName, to: train.destName, from: train.origName, - status: isOnTime( - arr: leg?.arr, - schArr: leg?.schArr + status: amtrakDate.isOnTime( + actual: leg?.arr, + scheduled: leg?.schArr ), track: track.isEmpty ? "" : track )