diff --git a/Sources/CodexBarCore/Providers/LLMProxy/LLMProxyUsageFetcher.swift b/Sources/CodexBarCore/Providers/LLMProxy/LLMProxyUsageFetcher.swift index 8b52fb50ef..094ec30154 100644 --- a/Sources/CodexBarCore/Providers/LLMProxy/LLMProxyUsageFetcher.swift +++ b/Sources/CodexBarCore/Providers/LLMProxy/LLMProxyUsageFetcher.swift @@ -291,7 +291,18 @@ public struct LLMProxyUsageFetcher: Sendable { private static func parseDate(_ raw: String?) -> Date? { guard let raw else { return nil } - return ISO8601DateFormatter().date(from: raw) + if let date = self.iso8601DateFormatter(fractionalSeconds: true).date(from: raw) { + return date + } + return self.iso8601DateFormatter(fractionalSeconds: false).date(from: raw) + } + + private static func iso8601DateFormatter(fractionalSeconds: Bool) -> ISO8601DateFormatter { + let formatter = ISO8601DateFormatter() + if fractionalSeconds { + formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] + } + return formatter } private static func responseSummary(_ data: Data) -> String { diff --git a/Tests/CodexBarTests/LLMProxyUsageFetcherTests.swift b/Tests/CodexBarTests/LLMProxyUsageFetcherTests.swift index 4696695807..3c61b3016a 100644 --- a/Tests/CodexBarTests/LLMProxyUsageFetcherTests.swift +++ b/Tests/CodexBarTests/LLMProxyUsageFetcherTests.swift @@ -82,4 +82,39 @@ struct LLMProxyUsageFetcherTests { ._quotaStatsURLForTesting(baseURL: #require(URL(string: "https://proxy.example.com/v1"))) .absoluteString == "https://proxy.example.com/v1/quota-stats") } + + @Test + func `parses fractional second quota reset times`() throws { + let json = """ + { + "providers": { + "openai": { + "quota_groups": [ + { + "remaining_percent": 42, + "reset_time": "2026-05-18T12:00:00.123Z" + } + ] + } + } + } + """ + + let parsed = try LLMProxyUsageFetcher._parseSnapshotForTesting( + Data(json.utf8), + updatedAt: Date(timeIntervalSince1970: 1)) + let components = DateComponents( + calendar: Calendar(identifier: .gregorian), + timeZone: TimeZone(secondsFromGMT: 0), + year: 2026, + month: 5, + day: 18, + hour: 12, + minute: 0, + second: 0, + nanosecond: 123_000_000) + let expected = try #require(components.date) + + #expect(try abs(#require(parsed.nextResetAt).timeIntervalSince(expected)) < 0.001) + } }