iOS Swift 3:Convert "Yyyy-Mm-Dd'T'Hh:Mm:Ssz" Format String to Date Object

iOS Swift 3 : Convert yyyy-MM-dd'T'HH:mm:ssZ format string to date object

You need an input format to convert the ISO8601 string to date and an output format to convert the date back to string:

let string = "2017-01-27T18:36:36Z"

let dateFormatter = DateFormatter()
let tempLocale = dateFormatter.locale // save locale temporarily
dateFormatter.locale = Locale(identifier: "en_US_POSIX") // set locale to reliable US_POSIX
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
let date = dateFormatter.date(from: string)!
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
dateFormatter.locale = tempLocale // reset the locale
let dateString = dateFormatter.string(from: date)
print("EXACT_DATE : \(dateString)")

Swift `yyyy-MM-dd'T'HH:mm:ss.sssZ` string to date

Your format is wrong. It should be:

"yyyy-MM-dd'T'HH:mm:ss.SSSZ"

Have a look at date time format here:
https://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns

How to convert date yyyy-mm-dd'T'HH:mm:ss.SSSZ in swift

let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

let dateFromInputString = dateFormatter.date(from: "2018-09-11T09:53:25.000+0000")

dateFormatter.dateFormat = "dd-MM-yyyy"

if(dateFromInputString != nil){
return dateFormatter.string(from: dateFromInputString!)
}
else{
debugPrint("could not convert date")
return "N/A"
}

Convert Date to String with format yyyy-MM-dd'T'HH:mm:ssZ

If you want that specific format, you have to set the timezone to UTC

dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)

and use the date format "yyyy-MM-dd'T'HH:mm:ssX" (X instead of Z)


An easier way is ISO8601DateFormatter

let dateFormatter = ISO8601DateFormatter()
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
let date = Date()
print(dateFormatter.string(from: date))

Convert string to date in Swift

  • Convert the ISO8601 string to date

      let isoDate = "2016-04-14T10:44:00+0000"

    let dateFormatter = DateFormatter()
    dateFormatter.locale = Locale(identifier: "en_US_POSIX") // set locale to reliable US_POSIX
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
    let date = dateFormatter.date(from:isoDate)!
  • Get the date components for year, month, day and hour from the date

      let calendar = Calendar.current
    let components = calendar.dateComponents([.year, .month, .day, .hour], from: date)
  • Finally create a new Date object and strip minutes and seconds

      let finalDate = calendar.date(from:components)

Consider also the convenience formatter ISO8601DateFormatter introduced in iOS 10 / macOS 10.12:

let isoDate = "2016-04-14T10:44:00+0000"

let dateFormatter = ISO8601DateFormatter()
let date = dateFormatter.date(from:isoDate)!

How to get time from YYYY-MM-dd'T'HH:mm:ss.sssZ

use the dateformat

formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"

instead of

formatter.dateFormat = "YYYY-MM-dd'T'HH:mm:ss.sssZ" 

for full code

 let formatter = Foundation.DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" //2017-04-01T18:05:00.000
let date1 = formatter.date(from: "2017-04-01T18:05:00.000Z")
print("date:\(String(describing: date1))")
formatter.dateFormat = "HH:mm"
let resultTime = formatter.string(from: date1!)
print("time:\(String(describing: resultTime))")

option-2

    let formatter = Foundation.DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.sssZ" //2017-04-01T18:05:00.000
let date1 = formatter.date(from: "2017-04-01T18:05:00.000Z")
print("date:\(String(describing: date1))")
formatter.timeZone = TimeZone(abbreviation: "UTC")
formatter.dateFormat = "HH:mm"
let resultTime = formatter.string(from: date1!)
print("time:\(String(describing: resultTime))")

output

Sample Image

Issue when converting a date string of format yyyy-MM-dd HH:mm:ss.m to yyyy-MM-dd HH:mm:ss

m is minutes and S is milliseconds so the format must be "yyyy-MM-dd HH:mm:ss.S".

Further for fixed date formats it's highly recommended to set the locale to en_US_POSIX

let dateTime = "1900-01-01 08:30:00.000000"
let outFormatter = DateFormatter()
outFormatter.locale = Locale(identifier: "en_US_POSIX")
outFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.S"

if let date = outFormatter.date(from: dateTime) {
//here value od date is 1900-01-01 04:18:48 +0000
outFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

let exactDate = outFormatter.string(from: date)
//here the value of exactDate is 1900-01-01 08:00:00
}

But if you only want to strip the milliseconds from the date string there is a simpler solution

let dateTime = "1900-01-01 08:30:00.000000"
let exactDate = dateTime.replacingOccurrences(of: "\\.\\d+", with: "", options: .regularExpression)

It removes the dot and any digit behind

Date formatter from string swift

The issue is that this code is using a dateFormat string of yyyy-MM-dd HH:mm, but that’s not what the actual input string is. It is yyyy-MM-dd'T'HH:mm:ss. Thus the conversion to the Date object is failing, and the forced unwrapping will cause it to crash.

Instead, I would recommend one formatter to convert the ISO8601 format of 2020-03-18T00:00:00 into a Date object. And if you then want a string in the format of 2020.03.18 00:00, you would have a separate formatter for that.

In the absence of an explicit timezone in ISO8601 date strings, it’s assumed to be the local time zone. So do not specify the timeZone property at all. (The only time you’d generally specify it is if it was Zulu/GMT/UTC, i.e. TimeZone(secondsFromGMT: 0).)

E.g.

let iso8601Formatter = DateFormatter()
iso8601Formatter.locale = Locale(identifier: "en_US_POSIX")
iso8601Formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"

let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy.MM.dd HH:mm"

func convert(input: String) -> String? {
guard let date = iso8601Formatter.date(from: input) else { return nil }
return formatter.string(from: date)
}

let result = convert(input: "2020-03-18T00:00:00") // "2020.03.18 00:00"

Note, instantiation of formatters (and changing of dateFormat strings) is a notoriously computationally intensive process, which is why I made these formatters properties rather than local variables. Obviously name them whatever you want and put them wherever you want, but make sure you avoid repeatedly instantiating these formatters or changing of dateFormat strings.



Related Topics



Leave a reply



Submit