jjatie
jjatie

Reputation: 5332

Time Interval Formatting

I am looking to display a time interval from an audio clip i.e.: "Snippet A is from 0:20 - 0:24"

I have tried to use DateIntervalFormatter like so:

let formatter = DateIntervalFormatter()
formatter.timeStyle = .short
formatter.dateStyle = .none

let interval = DateInterval(start: .init(), duration: 20)
let (_start, _end) = (interval.start, interval.end)
let getTimeComponents = {
    Calendar.current.dateComponents([.minute, .second], from: $0)
}
let startComponents = getTimeComponents(_start)
let endComponents = getTimeComponents(_end)

let dateFrom = { Calendar.current.date(from: $0) }
let start = dateFrom(startComponents)!
let end = dateFrom(endComponents)!
let string = formatter.string(from: start, to: end)
print(string) // OUTPUT: "12:34 – 12:35 AM"

But does not format in the desired way. I've looked at DateComponentsFormatter and RelativeDateTimeFormatter, but they don't appear to provide the desired behaviour either.

Is there a Formatter in Foundation that provides this behaviour? Implementing this manually seems prone to error when considering localization.

Upvotes: 0

Views: 486

Answers (1)

Sweeper
Sweeper

Reputation: 271565

Since the thing you are formatting represents a number of minutes and seconds, as opposed to a time of the day or a date, you should use DateComponentsFormatter.

You can first format the timestamps, then use string interpolation to include the rest of the sentence:

let start: TimeInterval = 20
let end: TimeInterval = 24

let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.minute, .second]
formatter.unitsStyle = .positional
formatter.zeroFormattingBehavior = .pad
let startString = formatter.string(from: start)
let endString = formatter.string(from: end)
let result = "Snippet A is from \(startString) - \(endString)"

You could also "cheat" and use DateIntervalFormatter... You just need to set dateTemplate to the desired format.

let formatter = DateIntervalFormatter()
formatter.dateTemplate = "m:ss"
let intervalString = formatter.string(from: Date(timeIntervalSince1970: start), to: Date(timeIntervalSince1970: end))
let result = "Snippet A is from \(intervalString)"

I feel like this is a cheat because you are not actually formatting dates. If you have a 24-hour-long audio clip, and the timestamp 24:00:00, DateIntervalFormatter won't be able to format it, but DateComponentsFormatter will. That said, there is not actually a TimestampIntervalFormatter...

Upvotes: 1

Related Questions