@@ -133,35 +133,77 @@ extension UsageMenuCardView.Model {
133133 private static func bedrockLatestBillingDay( from entries: [ CostUsageDailyReport . Entry ] )
134134 -> CostUsageDailyReport . Entry ?
135135 {
136- entries. max { lhs, rhs in
137- let lDate = Self . bedrockBillingDate ( from: lhs. date) ?? . distantPast
138- let rDate = Self . bedrockBillingDate ( from: rhs. date) ?? . distantPast
139- if lDate != rDate { return lDate < rDate }
140- let lCost = lhs. costUSD ?? - 1
141- let rCost = rhs. costUSD ?? - 1
136+ entries. compactMap { entry -> ( entry: CostUsageDailyReport . Entry , dayKey: String ) ? in
137+ guard let dayKey = bedrockBillingDayKey ( from: entry. date) else { return nil }
138+ return ( entry, dayKey)
139+ }
140+ . max { lhs, rhs in
141+ if lhs. dayKey != rhs. dayKey { return lhs. dayKey < rhs. dayKey }
142+ let lCost = lhs. entry. costUSD ?? - 1
143+ let rCost = rhs. entry. costUSD ?? - 1
142144 if lCost != rCost { return lCost < rCost }
143- let lTokens = lhs. totalTokens ?? - 1
144- let rTokens = rhs. totalTokens ?? - 1
145+ let lTokens = lhs. entry . totalTokens ?? - 1
146+ let rTokens = rhs. entry . totalTokens ?? - 1
145147 if lTokens != rTokens { return lTokens < rTokens }
146- return lhs. date < rhs. date
147- }
148+ return lhs. entry . date < rhs. entry . date
149+ } ? . entry
148150 }
149151
150152 private static func bedrockDisplayDate( from text: String ) -> String ? {
151- guard let date = bedrockBillingDate ( from: text) else { return nil }
152- let formatter = DateFormatter ( )
153- formatter. locale = Locale ( identifier: " en_US_POSIX " )
154- formatter. timeZone = TimeZone ( secondsFromGMT: 0 )
155- formatter. dateFormat = " MMM d "
156- return formatter. string ( from: date)
153+ guard let dayKey = bedrockBillingDayKey ( from: text) else { return nil }
154+ let monthStart = dayKey. index ( dayKey. startIndex, offsetBy: 5 )
155+ let monthEnd = dayKey. index ( monthStart, offsetBy: 2 )
156+ let dayStart = dayKey. index ( dayKey. startIndex, offsetBy: 8 )
157+ guard
158+ let month = Int ( dayKey [ monthStart..< monthEnd] ) ,
159+ let day = Int ( dayKey [ dayStart... ] ) ,
160+ ( 1 ... Self . bedrockMonthAbbreviations. count) . contains ( month) ,
161+ ( 1 ... 31 ) . contains ( day)
162+ else { return nil }
163+ return " \( Self . bedrockMonthAbbreviations [ month - 1 ] ) \( day) "
157164 }
158165
159- private static func bedrockBillingDate( from text: String ) -> Date ? {
160- let formatter = DateFormatter ( )
161- formatter. locale = Locale ( identifier: " en_US_POSIX " )
162- formatter. timeZone = TimeZone ( secondsFromGMT: 0 )
163- formatter. dateFormat = " yyyy-MM-dd "
164- return formatter. date ( from: text. trimmingCharacters ( in: . whitespacesAndNewlines) )
166+ private static let bedrockMonthAbbreviations = [
167+ " Jan " , " Feb " , " Mar " , " Apr " , " May " , " Jun " ,
168+ " Jul " , " Aug " , " Sep " , " Oct " , " Nov " , " Dec " ,
169+ ]
170+
171+ private static func bedrockBillingDayKey( from text: String ) -> String ? {
172+ let trimmed = text. trimmingCharacters ( in: . whitespacesAndNewlines)
173+ guard trimmed. count == 10 else { return nil }
174+ for (offset, character) in trimmed. enumerated ( ) {
175+ switch offset {
176+ case 4 , 7 :
177+ guard character == " - " else { return nil }
178+ default :
179+ guard character. isNumber else { return nil }
180+ }
181+ }
182+ let monthStart = trimmed. index ( trimmed. startIndex, offsetBy: 5 )
183+ let monthEnd = trimmed. index ( monthStart, offsetBy: 2 )
184+ let dayStart = trimmed. index ( trimmed. startIndex, offsetBy: 8 )
185+ let yearEnd = trimmed. index ( trimmed. startIndex, offsetBy: 4 )
186+ guard
187+ let year = Int ( trimmed [ ..< yearEnd] ) ,
188+ let month = Int ( trimmed [ monthStart..< monthEnd] ) ,
189+ let day = Int ( trimmed [ dayStart... ] ) ,
190+ ( 1 ... Self . bedrockMonthAbbreviations. count) . contains ( month) ,
191+ ( 1 ... Self . daysInBedrockBillingMonth ( month, year: year) ) . contains ( day)
192+ else { return nil }
193+ return trimmed
194+ }
195+
196+ private static func daysInBedrockBillingMonth( _ month: Int , year: Int ) -> Int {
197+ switch month {
198+ case 2 :
199+ if year. isMultiple ( of: 400 ) { return 29 }
200+ if year. isMultiple ( of: 100 ) { return 28 }
201+ return year. isMultiple ( of: 4 ) ? 29 : 28
202+ case 4 , 6 , 9 , 11 :
203+ return 30
204+ default :
205+ return 31
206+ }
165207 }
166208
167209 static func providerCostSection(
0 commit comments