From 133db456a4bd069daecb60b3ec6fa147868493a3 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 18 Nov 2025 00:27:51 +0100 Subject: Handle GTFS times exceeding 24 hours for night services (#98) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: arielcostas <94913521+arielcostas@users.noreply.github.com> Co-authored-by: Ariel Costas Guerrero --- .../Types/VigoSchedules.cs | 56 +++++++++++++++++----- 1 file changed, 44 insertions(+), 12 deletions(-) (limited to 'src/Costasdev.Busurbano.Backend/Types') diff --git a/src/Costasdev.Busurbano.Backend/Types/VigoSchedules.cs b/src/Costasdev.Busurbano.Backend/Types/VigoSchedules.cs index 76c8fa1..f3a6727 100644 --- a/src/Costasdev.Busurbano.Backend/Types/VigoSchedules.cs +++ b/src/Costasdev.Busurbano.Backend/Types/VigoSchedules.cs @@ -20,27 +20,59 @@ public class ScheduledStop [JsonPropertyName("starting_time")] public required string StartingTime { get; set; } public DateTime? StartingDateTime() { - if (!TimeOnly.TryParse(StartingTime, out var time)) - { - return null; - } - var dt = DateTime.Today + time.ToTimeSpan(); - return dt.AddSeconds(60 - dt.Second); + return ParseGtfsTime(StartingTime); } [JsonPropertyName("calling_ssm")] public required int CallingSsm { get; set; } [JsonPropertyName("calling_time")] public required string CallingTime { get; set; } public DateTime? CallingDateTime() { - if (!TimeOnly.TryParse(CallingTime, out var time)) - { - return null; - } - var dt = DateTime.Today + time.ToTimeSpan(); - return dt.AddSeconds(60 - dt.Second); + return ParseGtfsTime(CallingTime); } [JsonPropertyName("terminus_code")] public required string TerminusCode { get; set; } [JsonPropertyName("terminus_name")] public required string TerminusName { get; set; } [JsonPropertyName("terminus_time")] public required string TerminusTime { get; set; } + + /// + /// Parse GTFS time format (HH:MM:SS) which can have hours >= 24 for services past midnight + /// + private static DateTime? ParseGtfsTime(string timeStr) + { + if (string.IsNullOrWhiteSpace(timeStr)) + { + return null; + } + + var parts = timeStr.Split(':'); + if (parts.Length != 3) + { + return null; + } + + if (!int.TryParse(parts[0], out var hours) || + !int.TryParse(parts[1], out var minutes) || + !int.TryParse(parts[2], out var seconds)) + { + return null; + } + + // Handle GTFS times that exceed 24 hours (e.g., 25:30:00 for 1:30 AM next day) + var days = hours / 24; + var normalizedHours = hours % 24; + + try + { + var dt = DateTime.Today + .AddDays(days) + .AddHours(normalizedHours) + .AddMinutes(minutes) + .AddSeconds(seconds); + return dt.AddSeconds(60 - dt.Second); + } + catch + { + return null; + } + } } -- cgit v1.3