-1

When parsing an input datetime string with the matching format, I am still getting nil back from DateFormatter in swift.

Input string (copied at runtime from variable) and confirmed that is the string running the call with Postman.

"2020-06-30T14:41:33.9"

Parsing method

static func FormatDateTimeString(dateTimeString: String) -> String {
    let inputDateFormatter = DateFormatter()
    inputDateFormatter.dateFormat = "YYYY-MM-DDThh:mm:ss.s"
    let date = inputDateFormatter.date(from:dateTimeString) //date is always nil
    
    let outputDateFormatter = DateFormatter()
    outputDateFormatter.dateFormat = "MMM d, yyyy HH:mm"
    
    return outputDateFormatter.string(from: date!)
}

I have also tried "YYYY-MM-DD'T'hh:mm:ss.s" and "YYYY-MM-DDThh:mm:ss" but none seem to work.

EDIT: Trying the format suggested below I am still getting nil.

enter image description here

EDIT: As Suggested from the comments I am still getting nil. Format below is: inputDateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.S"

enter image description here

EDIT: Still getting null using the following config

enter image description here

Mark McGookin
  • 932
  • 1
  • 16
  • 39
  • 2
    The format does not match. Year is `yyyy`, day is `dd`, the `T` must be wrapped in single quotes, hour is `HH` and fractional seconds is `SS` – vadian Sep 20 '20 at 14:08
  • 2
    ... and you should set a POSIX locale when parsing a fixed-format date string, compare https://stackoverflow.com/q/40692378/1187415. – Martin R Sep 20 '20 at 14:09
  • 1
    `"en_US_POSIX"` not `"en_GB_POSIX"` – Leo Dabus Sep 20 '20 at 14:24
  • I've tried these suggestions and am still getting nil... Am I being stupid and missing something here? I had copied and pasted some of the formats, obviously they are off. It's a DateTime.UtcNow from dotnet over a web call that I am trying to parse. – Mark McGookin Sep 20 '20 at 14:27
  • Your dateFormat is wrong the correct format is `"yyyy-MM-dd'T'HH:mm:ss.S"` – Leo Dabus Sep 20 '20 at 14:27
  • And make sure your dateString is current timezone when parsing otherwise set the timezone to UTC – Leo Dabus Sep 20 '20 at 14:28
  • You should set the `locale` before setting the `dateFormat`. Again it should be `"en_US_POSIX"` not `"en_GB_POSIX"` – Leo Dabus Sep 20 '20 at 14:30
  • @LeoDabus I am in the UK so I thought en_GB would have been the right way to go. I tried with en_US and it is still nil. I have also moved that to the line above setting the format and I am still getting nil. – Mark McGookin Sep 20 '20 at 14:32
  • It doesn't matter. en_US_POSIX is a special locale that does not reflect the user device locale and settings. So the dateFormat wont be affected. https://developer.apple.com/library/archive/qa/qa1480/_index.html – Leo Dabus Sep 20 '20 at 14:33
  • **if you're working with fixed-format dates, you should first set the locale of the date formatter to something appropriate for your fixed format. In most cases the best locale to choose is "en_US_POSIX", a locale that's specifically designed to yield US English results regardless of both user and system preferences. "en_US_POSIX" is also invariant in time (if the US, at some point in the future, changes the way it formats dates, "en_US" will change to reflect the new behaviour, but "en_US_POSIX" will not), and between machines ("en_US_POSIX" works the same on iOS as it does on OS X)** – Leo Dabus Sep 20 '20 at 14:35
  • 1
    try printing the date result – Leo Dabus Sep 20 '20 at 14:36
  • I'm not sure who is downvoting this question... but @LeoDabus when I print that date it has an output?!.... why is it nil according to the debugger but it has a value? – Mark McGookin Sep 20 '20 at 14:40
  • 1
    That’s a bug in Xcode: https://stackoverflow.com/q/58108824/1187415 – Martin R Sep 20 '20 at 14:43
  • Not related to your question but what is the purpose of your string format that you are trying to return? If you intent is to display the time the the user you should use dateStyle and timeStyle to display it in local time and localized – Leo Dabus Sep 20 '20 at 14:44

1 Answers1

2

Use this format:

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

Demo

let dateTimeString = "2020-06-30T14:41:33.9"

let inputDateFormatter = DateFormatter()
inputDateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.S"
let date = inputDateFormatter.date(from: dateTimeString) // "Jun 30, 2020 at 2:41 PM"
Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278