diff --git a/Scripts/sportstime_parser/normalizers/stadium_resolver.py b/Scripts/sportstime_parser/normalizers/stadium_resolver.py index 9a30a1b..a6992b0 100644 --- a/Scripts/sportstime_parser/normalizers/stadium_resolver.py +++ b/Scripts/sportstime_parser/normalizers/stadium_resolver.py @@ -42,6 +42,7 @@ class StadiumInfo: sport: str latitude: float longitude: float + timezone: str = "America/New_York" # IANA timezone identifier # Hardcoded stadium mappings @@ -55,10 +56,10 @@ STADIUM_MAPPINGS: dict[str, dict[str, StadiumInfo]] = { "stadium_nba_united_center": StadiumInfo("stadium_nba_united_center", "United Center", "Chicago", "IL", "USA", "nba", 41.8807, -87.6742), "stadium_nba_rocket_mortgage_fieldhouse": StadiumInfo("stadium_nba_rocket_mortgage_fieldhouse", "Rocket Mortgage FieldHouse", "Cleveland", "OH", "USA", "nba", 41.4965, -81.6882), "stadium_nba_american_airlines_center": StadiumInfo("stadium_nba_american_airlines_center", "American Airlines Center", "Dallas", "TX", "USA", "nba", 32.7905, -96.8103), - "stadium_nba_ball_arena": StadiumInfo("stadium_nba_ball_arena", "Ball Arena", "Denver", "CO", "USA", "nba", 39.7487, -105.0077), + "stadium_nba_ball_arena": StadiumInfo("stadium_nba_ball_arena", "Ball Arena", "Denver", "CO", "USA", "nba", 39.7487, -105.0077, "America/Denver"), "stadium_nba_little_caesars_arena": StadiumInfo("stadium_nba_little_caesars_arena", "Little Caesars Arena", "Detroit", "MI", "USA", "nba", 42.3411, -83.0553), - "stadium_nba_chase_center": StadiumInfo("stadium_nba_chase_center", "Chase Center", "San Francisco", "CA", "USA", "nba", 37.7680, -122.3877), - "stadium_nba_toyota_center": StadiumInfo("stadium_nba_toyota_center", "Toyota Center", "Houston", "TX", "USA", "nba", 29.7508, -95.3621), + "stadium_nba_chase_center": StadiumInfo("stadium_nba_chase_center", "Chase Center", "San Francisco", "CA", "USA", "nba", 37.7680, -122.3877, "America/Los_Angeles"), + "stadium_nba_toyota_center": StadiumInfo("stadium_nba_toyota_center", "Toyota Center", "Houston", "TX", "USA", "nba", 29.7508, -95.3621, "America/Chicago"), "stadium_nba_gainbridge_fieldhouse": StadiumInfo("stadium_nba_gainbridge_fieldhouse", "Gainbridge Fieldhouse", "Indianapolis", "IN", "USA", "nba", 39.7640, -86.1555), "stadium_nba_intuit_dome": StadiumInfo("stadium_nba_intuit_dome", "Intuit Dome", "Inglewood", "CA", "USA", "nba", 33.9425, -118.3417), "stadium_nba_cryptocom_arena": StadiumInfo("stadium_nba_cryptocom_arena", "Crypto.com Arena", "Los Angeles", "CA", "USA", "nba", 34.0430, -118.2673), @@ -75,8 +76,8 @@ STADIUM_MAPPINGS: dict[str, dict[str, StadiumInfo]] = { "stadium_nba_moda_center": StadiumInfo("stadium_nba_moda_center", "Moda Center", "Portland", "OR", "USA", "nba", 45.5316, -122.6668), "stadium_nba_golden_1_center": StadiumInfo("stadium_nba_golden_1_center", "Golden 1 Center", "Sacramento", "CA", "USA", "nba", 38.5802, -121.4997), "stadium_nba_frost_bank_center": StadiumInfo("stadium_nba_frost_bank_center", "Frost Bank Center", "San Antonio", "TX", "USA", "nba", 29.4270, -98.4375), - "stadium_nba_scotiabank_arena": StadiumInfo("stadium_nba_scotiabank_arena", "Scotiabank Arena", "Toronto", "ON", "Canada", "nba", 43.6435, -79.3791), - "stadium_nba_delta_center": StadiumInfo("stadium_nba_delta_center", "Delta Center", "Salt Lake City", "UT", "USA", "nba", 40.7683, -111.9011), + "stadium_nba_scotiabank_arena": StadiumInfo("stadium_nba_scotiabank_arena", "Scotiabank Arena", "Toronto", "ON", "Canada", "nba", 43.6435, -79.3791, "America/Toronto"), + "stadium_nba_delta_center": StadiumInfo("stadium_nba_delta_center", "Delta Center", "Salt Lake City", "UT", "USA", "nba", 40.7683, -111.9011, "America/Denver"), "stadium_nba_capital_one_arena": StadiumInfo("stadium_nba_capital_one_arena", "Capital One Arena", "Washington", "DC", "USA", "nba", 38.8981, -77.0209), }, "mlb": { diff --git a/SportsTime/Core/Models/Domain/Game.swift b/SportsTime/Core/Models/Domain/Game.swift index 103c772..8fce1ca 100644 --- a/SportsTime/Core/Models/Domain/Game.swift +++ b/SportsTime/Core/Models/Domain/Game.swift @@ -91,4 +91,20 @@ struct RichGame: Identifiable, Hashable, Codable { var venueDescription: String { "\(stadium.name), \(stadium.city)" } + + /// Game time formatted in the stadium's local timezone with timezone indicator + var localGameTime: String { + let formatter = DateFormatter() + formatter.dateFormat = "h:mm a z" + formatter.timeZone = stadium.timeZone ?? .current + return formatter.string(from: game.dateTime) + } + + /// Game time formatted in the stadium's local timezone without timezone indicator + var localGameTimeShort: String { + let formatter = DateFormatter() + formatter.dateFormat = "h:mm a" + formatter.timeZone = stadium.timeZone ?? .current + return formatter.string(from: game.dateTime) + } } diff --git a/SportsTime/Core/Models/Domain/Stadium.swift b/SportsTime/Core/Models/Domain/Stadium.swift index 4a4a854..a8a7412 100644 --- a/SportsTime/Core/Models/Domain/Stadium.swift +++ b/SportsTime/Core/Models/Domain/Stadium.swift @@ -17,6 +17,7 @@ struct Stadium: Identifiable, Codable, Hashable { let sport: Sport let yearOpened: Int? let imageURL: URL? + let timeZoneIdentifier: String? init( id: String, @@ -28,7 +29,8 @@ struct Stadium: Identifiable, Codable, Hashable { capacity: Int, sport: Sport, yearOpened: Int? = nil, - imageURL: URL? = nil + imageURL: URL? = nil, + timeZoneIdentifier: String? = nil ) { self.id = id self.name = name @@ -40,6 +42,11 @@ struct Stadium: Identifiable, Codable, Hashable { self.sport = sport self.yearOpened = yearOpened self.imageURL = imageURL + self.timeZoneIdentifier = timeZoneIdentifier + } + + var timeZone: TimeZone? { + timeZoneIdentifier.flatMap { TimeZone(identifier: $0) } } var location: CLLocation {