How about this?
That won’t work in all circumstances. Three things:
If you work with fixed-format date strings, you need to work in the
en_US_POSIX
locale. See QA1480 NSDateFormatter and Internet Dates.In situations like this, where you don’t need the actual date but rather just want a clean round trip conversion, it’s best to work in the GMT time zone. If you work in the user’s time zone you’ll run into problems if the time in question doesn’t exist in that time zone (for example, you do this calculation on a daylight savings time transition day).
When working with date format strings, it’s a good idea to quote any literal components (like the colons).
Date formatters are relatively expensive, so you should statically allocates ones that can’t change.
With these changes in place the code looks more complex:
enum TimeError : Error {
case invalidTimeString
}
private var fromFormatter: DateFormatter = {
let df = DateFormatter()
df.locale = Locale(identifier: "en_US_POSIX")
df.timeZone = TimeZone(secondsFromGMT: 0)
df.dateFormat = "hh':'mm':'ssaa"
return df
}()
private var toFormatter: DateFormatter = {
let df = DateFormatter()
df.locale = Locale(identifier: "en_US_POSIX")
df.timeZone = TimeZone(secondsFromGMT: 0)
df.dateFormat = "HH':'mm':'ss"
return df
}()
func convertToMilitatyTime(fromTime time: String) throws -> String {
let date = fromFormatter.date(from: time)
guard date != nil else { throw TimeError.invalidTimeString }
return toFormatter.string(from: date!)
}
Honestly, I’m not sure if
DateFormatter
is the right way to go here. It’s a complex piece of code and it’s not clear whether the problem requirements justifies that complexity. Specifically, if the input string is
very tightly constrained, you could do something hackish like this.
func convertToMilitatyTime(fromTime time: String) -> String {
let timeChars = Array(time.characters)
let hours = String(timeChars[0..<2])
let prefix: String
switch (timeChars[8], hours) {
case ("A", "12"):
prefix = "00"
case ("P", "12"):
prefix = "12"
case ("A", _):
prefix = hours
case ("P", _):
prefix = String(Int(hours)! + 12)
default:
fatalError()
}
return "\(prefix)\(String(timeChars[2..<8]))"
}
Of course, this will trap if the input doesn’t exactly match the standard format.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"