jonv562
jonv562

Reputation: 303

How to convert a string UTC date to NSDate in Swift

I'm getting UTC string dates that look like this "2015-10-17T00:00:00.000Z" and want to convert them to an NSDate in this format "October 12th 2015 11:19:12 am"

This is the route that I'm trying but I can't seem to get the right dateFormat.

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = //can't seem to get this right
dateFormatter.timeZone = NSTimeZone(name: "UTC")
let date = dateFormatter.dateFromString("2015-10-17T00:00:00.000Z")

Upvotes: 10

Views: 16651

Answers (4)

vadian
vadian

Reputation: 285270

This question is a few years old but let's answer it literally.

First of all DateFormatter doesn't provide a format specifier for an ordinal suffix so we have to write a function

func ordinalSuffix(for day : String) -> String {
    switch day {
        case "1", "11", "21", "31": return "st"
        case "2", "12", "22": return "nd"
        case "3", "13", "23": return "rd"
        default: return "th"
    }
}

To convert the iso8601 string to date create a DateFormatter, set its calendar to an iso8601 calendar and convert the string to Date. As the time zone is specified in the string you don't need to set it explicitly

let dateString = "2015-10-17T00:00:00.000Z"
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
guard let date = formatter.date(from: dateString) else {
    // replace that with a proper error handling
    fatalError("Could not convert date string")
}

To convert the date back to string you have to set the Locale to a fixed value, set the am/pm symbols to the lowercase versions, extract the day component first for the ordinal suffix calculation and then take advantage of String(format to insert the ordinal suffix.

formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.amSymbol = "am"
formatter.pmSymbol = "pm"
formatter.dateFormat = "dd"
let day = formatter.string(from: date)
formatter.dateFormat = "MMMM dd'%@' yyyy h:mm:ss a"
let output = String(format: formatter.string(from: date), ordinalSuffix(for: day))
print(output)

Upvotes: 0

ozzyzig
ozzyzig

Reputation: 719

I think this should work

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let localDate = formatter.date(from: date)

Upvotes: 22

Artemis Shlesberg
Artemis Shlesberg

Reputation: 308

Swift 4 code

let dateString = "2015-10-17T00:00:00.000Z"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date = formatter.date(from: dateString)

You can find useful info about date formats here

Upvotes: 1

BHUVANESH MOHANKUMAR
BHUVANESH MOHANKUMAR

Reputation: 2787

This works for Swift 3.0 and latest Xcode [April 2017]

let dateString = "2017-Jan-01 12:00:00.250"
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-M-dd HH:mm:ss.SSS"
        dateFormatter.locale = Locale.init(identifier: "en_GB")
        let dateObj = dateFormatter.date(from: dateString)

        let date = dateObj
        let formatter = DateFormatter()
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSXXXXX"
        let currentDateTime = formatter.string(from: date!)

Upvotes: 3

Related Questions