GoForIt
GoForIt

Reputation: 49

Formating date to sql date formate in Swift

I have a method that converts my SQL date to "MM-dd-yyyy, HH:mm" in swift. I need to be able to convert this back to "yyyy-MM-dd'T'HH:mm:ss". This will be in server time and also eastern time zone.

Converting to "MM-dd-yyyy, HH:mm":

  static func dateView(_ DateString: String) -> String {
        var returnDate = ""
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "en_US_POSIX")
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
        let string = String(DateString)
        if let date = dateFormatter.date(from: string) {
            dateFormatter.dateStyle = .short
            dateFormatter.timeStyle = .short
            returnDate = dateFormatter.string(from: date)
        }

    return returnDate
}

Trying to convert to "yyyy-MM-dd'T'HH:mm:ss":

static func dateToSQLDate(_ DateString: String) -> String {
    var returnDate = ""
    let dateFormatter = DateFormatter()
    dateFormatter.locale = Locale(identifier: "en_US_POSIX")
    dateFormatter.dateFormat = "MM/dd/yy HH:mm"
    let string = String(DateString)
    if let date = dateFormatter.date(from: string) {
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
        //dateFormatter.timeStyle = .short
        returnDate = dateFormatter.string(from: date)
    }

    return returnDate
}

Example would be:

var date = "3/10/16, 10:00AM"
dateToSQLDate(date)
Expected Out: 2016-03-10T10:00:00

Any ideas to what I am doing wrong?

Upvotes: 1

Views: 1045

Answers (3)

Rob
Rob

Reputation: 437917

Others have answered your question, but a few observations:

  1. It is probably prudent to always save your IS8601 timestamp strings in GMT/UTC/Zulu timezone (by setting the timeZone of your ISO8601 date string formatters to TimeZone(secondsFromGMT: 0), perhaps adding the X qualifier in the string to make it completely unambiguous. It shouldn’t be “server time zone” and probably shouldn’t be the device’s local time zone either.

  2. Even better, I might suggest using the ISO8601DateFormatter instead, which sets timezones, locales, etc., automatically, making configuration less fragile.

  3. I’d suggest instantiating two separate date formatters, one for the ISO 8601 date format (the one with the T in it), and another for presenting dates in your UI. While the ISO 8601 date formatter should use the en_US_POSIX locale (and if you use ISO8601DateFormatter, that’s taken care of for you), the UI date formatter should not (because you presumably want to show the date in the user’s device’s current locale).

  4. I personally would suggest that your model objects don’t use a string for the date, but rather use a Date object, instead. So, use ISO8601DateFormatter when converting between Date and API strings, store the Date in your model object, and only use the DateFormatter with dateStyle and timeStyle when presenting the Date in the user interface.

    So this means that rather than two string-to-string routines, you have string-to-date (and vice versa) for each of the two formatters.

  5. Date formatters are notoriously computationally expensive to create. So you might consider creating these two formatters once, save them in ivars, and then you don’t have to repeatedly reinstantiate them.

Upvotes: 0

vadian
vadian

Reputation: 285180

Your date format is wrong.

Compare the string "3/10/16, 10:00AM" with the date format "MM/dd/yy HH:mm". There are three issues:

  • The comma is missing
  • The AM/PM specifier a is missing
  • 12 hour mode is hh

static func dateToSQLDate(_ string: String) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.locale = Locale(identifier: "en_US_POSIX")
    dateFormatter.dateFormat = "MM/dd/yy, hh:mma"
    guard let date = dateFormatter.date(from: string) else { return "" }
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
    return dateFormatter.string(from: date)
}

Upvotes: 2

steveSarsawa
steveSarsawa

Reputation: 1679

Try this

static func dateToSQLDate(_ DateString: String) -> String {
    var returnDate = ""
    let dateFormatter = DateFormatter()
    dateFormatter.locale = Locale(identifier: "en_US_POSIX")
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
    let string = String(DateString)
    if let date = dateFormatter.date(from: string) {
    dateFormatter.dateFormat = "MM/dd/yy HH:mm"
        returnDate = dateFormatter.string(from: date)
    }    
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"

    return returnDate
}

Upvotes: 0

Related Questions