问题
I am getting time from the response in hours, minutes and seconds like "01:32:34" of multiple objects. I have saved it in a custom date object, where i am saving the date value and the string value, there are a large number of records so i am saving it in my local db and upon retrieving i get the date value in the format 1999-12-31 19:01:04 +0000
whereas my string value which i am getting from response as well is 19:01:04
. now i would like to add all of these values to return a string e.g 1:15:16
, 00:15:02
, 00:45:27
should return 2 hours 15 minutes 45 seconds. I have explored Calendar.Components.byAdding
but the methods there only let me add one single component, it doesn't receive an array and return Date
. Is there any swifty way to achieve this, I want to achieve this via an elegant and proper method, i could think of a few fixes but they don't seem appropriate.
回答1:
I’m going to assume that “01:32:34” represents an elapsed time of 5,554 seconds, not 1:32am. So, I’d convert it to a TimeInterval
, not a Date
:
func timeInterval(from string: String) -> TimeInterval? {
let components = string.components(separatedBy: ":").map { Double($0) }
guard
components.count == 3,
let hours = components[0],
let minutes = components[1],
let seconds = components[2]
else { return nil }
return ((hours * 60) + minutes) * 60 + seconds
}
You can chose to store either the original “01:32:34” string or this value, 5,554.0.
Anyway, then adding these numeric time intervals is trivial addition. And to display a resulting TimeInterval
, you’d use a DateComponentsFormatter
, e.g.
let timeIntervalFormatter: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .positional
formatter.allowedUnits = [.hour, .minute, .second]
return formatter
}()
func totalElapsed(_ strings: [String]) -> String? {
let total = strings.reduce(TimeInterval.zero) { sum, string in
sum + (timeInterval(from: string) ?? 0)
}
return timeIntervalFormatter.string(from: total)
}
let strings = ["1:15:16", "00:15:02", "00:45:27"]
let result = totalElapsed(strings)
02:15:45
Or if you want more of a (localized) natural language representation, use unitsStyle
of .full
:
2 hours, 15 minutes, 45 seconds
This approach (using TimeInterval
, not Date
) has the virtue that it also can represent intervals that exceed 24 hours.
来源:https://stackoverflow.com/questions/59479413/adding-time-interval-e-g-hours-minutes-and-seconds