5 Replies  Level 1 (0 points)

I found this algorithmic question in HackerRank and I wondered how could it be improved. The algorithmic question asks you "Given a time in -hour AM/PM format, convert it to military (-hour) time."

It accepts a string in the format e.g "`07:05:45PM" and you are supposed to return "19:05:45"`

And here is my solution

```var str = "07:05:45PM"
func convertToMilitary(fromTime time : String) -> String {

var array = Array(time.characters.dropLast())
var strr = "\(array)\(array)"
if array[array.endIndex - 1] == "P"{
if strr != "12" {
strr = "\(Int(strr)!+12)"
}
} else if array[array.endIndex - 1] == "A" {
if strr == "12" {
strr = "00"
}
}
array.remove(at: 0)
array.remove(at: 0)
array.removeLast()
return "\(strr)\(String(array))"
}
convertToMilitary(fromTime: str)

```

How could I improve this solution?

• ###### Re: How could you improve this Swift algorithm?  Level 8 (9,185 points)

What's the purpose to improve ? Just fun of it ? Or is it cauising problem to your software ?

• ###### Re: How could you improve this Swift algorithm?  Level 1 (0 points)

```enum TimeError : Error {
case invalidTimeString
}

func convertToMilitatyTime(fromTime time: String) throws -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm:ssaa"
let date = dateFormatter.date(from: time)
guard date != nil else { throw TimeError.invalidTimeString }
dateFormatter.dateFormat = "HH:mm:ss"
return dateFormatter.string(from: date!)
}
```
• ###### Re: How could you improve this Swift algorithm?  Apple Staff (13,915 points)

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 }
}
```

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, 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"`

• ###### Re: How could you improve this Swift algorithm?  Level 2 (25 points)

**** that's a lot of code for a simple function, throw this into a function, return newTime and done.  regex and perl are your friends

```import Foundation
let AA = "07:05:45PM"
let a:[String] = AA.components(separatedBy: "AM")
var newTime:String = ""
if a != AA
{ newTime = a }
else
{
let b:[String] = AA.components(separatedBy: "PM")
let c:[String] = b.components(separatedBy: ":")
newTime = String("\(Int(c)! + 12 ):\(c):\(c)")
}

```