0

i have the following date coming from a server 2019-09-05T10:37:49.494Z as a string and i need to parse this and convert it to a format like this Fri September 13,2019 12:36 AM and back to a string again: i found multiple question links but none of them are working for me Question One Question Two

it tried doing this:

let dateFormatterGet = DateFormatter()
let dateFormatterPrint = DateFormatter()
var rawDate = "2019-09-05T10:37:49.494Z"

dateFormatterGet.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
dateFormatterPrint.dateFormat = "E, d MMM yyyy HH:mm"
var formattedDate = "Error Formatting date"
if let date = dateFormatterGet.date(from: rawDate) {
    formattedDate = dateFormatterPrint.string(from: date)
    print("Formatted Date : \(formattedDate)")
}else {
     print("There was an error decoding the string")
}

this fails printing the error message, what am i doing wrong and how can i fix it?

Surafel
  • 675
  • 4
  • 11
  • 24
  • Almost there. `yyyy-MM-dd'T'HH:mm:ssZ` vs `"2019-09-05T10:37:49.494Z"`. You see that there are numbers after the seconds? But you didn't tell the DateFormatter (through the `dateFormat`) how to parse them. So it fails. See there http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns (Fractional Seconds?) – Larme Sep 06 '19 at 08:24
  • i thought that was the zone? – Surafel Sep 06 '19 at 08:25
  • ".494", that's not a zone. Which zone should it be? – Larme Sep 06 '19 at 08:26
  • i dont know i am getting this date from backend thats why i got confused so how should i change the formatting? – Surafel Sep 06 '19 at 08:27
  • In `rawDate`, the "Z" could be standing for "Zulu Time Zone" – ielyamani Sep 06 '19 at 08:31

3 Answers3

2

You are almost there.

A small tip playing with (NS)DateFormatter put the dateFormat above/under the date string.

yyyy-MM-dd'T'HH:mm:ssZ
2019-09-05T10:37:49.494Z

Then, add "spaces" to align and separate them.

yyyy - MM - dd 'T' HH : mm : ss      Z
2019 - 09 - 05  T  10 : 37 : 49 . 494Z
                                ^ ^^^

I highlighted the missing ones. You need to tell the (NS)DateFormatter through the dateFormat how to interpret theses additional characters.

Let's check the documentation.

It's

Fractional Second - truncates (like other time fields) to the count of letters. (example shows display using pattern SSSS for seconds value 12.34567)

So using yyyy-MM-dd'T'HH:mm:ss.SSSZ should interpret them and fix your issue.

That's how you fix your issue. And it explained your error. But since as pointed by @Zombie it's using a ISO format, use if available the ISO8601DateFormatter if possible (iOS10+) If in future cases you don't have an ISO something format, you can use theses tips ;)

Larme
  • 24,190
  • 6
  • 51
  • 81
1

The format you provided seems like an iso 8601 date for this reason I would suggest using the ISO8601DateFormatter

You can specify the options to match your string here is an example

let dateString = "2019-09-05T10:37:49.494Z"

let formatter = ISO8601DateFormatter()

formatter.formatOptions = [
    .withDashSeparatorInDate,
    .withFullDate,
    .withFullTime,
    .withFractionalSeconds,
    .withColonSeparatorInTime
]

// "Sep 5, 2019 at 12:37 PM"
let date = formatter.date(from: dateString) ?? Date()

//"Thursday, September 5, 2019 at 12:37:49 PM"
let formattedDate = DateFormatter.localizedString(
    from: date,
    dateStyle: .full,
    timeStyle: .medium
)
zombie
  • 5,069
  • 3
  • 25
  • 54
  • 1
    The format options can be simplified: `formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]` – vadian Sep 06 '19 at 08:46
0

The problem is you don't tell dateFormatterGet how to parse milliseconds. Modify the dateFormat to:

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

Martin Pilch
  • 3,245
  • 3
  • 38
  • 61