2

I am using a string extension function to convert a date string. The function is:

func convertDateString() -> String {
    let dateFormater = DateFormatter()
    var returnString = ""
    dateFormater.dateFormat = "yyyy-MM-dd'T'hh:mm:ss'Z'"    // Takes the format from the JSON journal entry for elite dangerous
    dateFormater.locale = Locale.current
    if let dateObj = dateFormater.date(from: self) {
    dateFormater.dateFormat = "dd MMM yyyy  hh:mm:ss"       // Converts it to a new string (as a date object)
        returnString = dateFormater.string(from: dateObj)   // Converts the date object back to a string
    } else {
        returnString = "Error converting date"
    }
    return returnString
}

I am using a data set which is an series of JSON objects calling the string extension to convert part of the result from the JSON reference file.

I am working on two machines - one a MACPRO and one a MacBookAir. Both are running the same version of MacOS (10.12.5) and the same version of Xcode.

When I run the app on the MACPRO it parses the JSON object file without an issue and converts each and every date correctly as expected in the function shown above. However, when I run the app on the MacBookAir, on exactly the same datafile, the JSON object file seems to be parsed without an issue however some (a few percent) of the dates do not convert as expected - they fail the if let dateObj = dateFormater.date(from: self) statement and are returned as "Error converting date".

I am at a loss to work out what is going on. I have tried removing the dateFormater.locale = Locale.current and it makes no difference.

The same JSON objects produce the error (i.e. each time I run the file it is the same JSON objects that produce the "Error converting date" response). When I look at the JSON object file in a text editor there appears to be no issues with the JSON object (I have also confirmed this in an online JSON object formatter and it reads the JSON object correctly.)

I should also add that I am using SwiftyJSON to parse the JSON objects.

Any help or suggestions gratefully received.

Is there a way to make my code more robust? Can anyone suggest why the different machine might make a difference given that the app the datafile, Xcode and MacOS are all the same.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Wolfstar
  • 111
  • 10
  • 2
    Apple wrote about a similar problem in [this article](https://developer.apple.com/library/content/qa/qa1480/_index.html). if you are targeting OS X 10.12 and above, use [`ISO8601DateFormatter`](https://developer.apple.com/reference/foundation/nsiso8601dateformatter) – Code Different May 25 '17 at 13:54
  • 1
    You should include the problematic strings in your question. – rmaddy May 25 '17 at 14:16
  • You should not scape the Z. hh is wrong (it is for 12h format). You need to use HH (00-23). And set your formatter locale to `"en_US_POSIX"`. You should check this https://stackoverflow.com/questions/28016578/swift-how-to-create-a-date-time-stamp-and-format-as-iso-8601-rfc-3339-utc-tim/28016692#28016692 – Leo Dabus May 25 '17 at 18:24

2 Answers2

2

Your error comes from this line: dateFormater.locale = Locale.current. Your two machines are probably set up to use different locales.

Click on run while holding down the option key and check what is the Application Region setting on both machines.

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • Hi David - thanks for the response. I have tried removing that line from the code and I still get the error. When I do as you suggested and selected Australia or the UK as the region (in lieu of the 'system' setting) I still get the same error - and this still seems to happen regardless of which locale I select. When both machines are set to the same specific locale - same result as described in my original question. – Wolfstar May 25 '17 at 13:56
0

My thanks to all who responded.

After reading the article referenced by Code Different and focusing on the issue that David raised is added the following lines to my code:

    dateFormater.calendar = Calendar(identifier: .iso8601)
    dateFormater.locale = Locale(identifier: "en_US_POSIX")
    dateFormater.timeZone = TimeZone(secondsFromGMT: 0)

in lieu of the 'dateFormater.locale = Locale.current' line. It now works perfectly and swaps between devices without a problem.

Wolfstar
  • 111
  • 10
  • And do not quote the "Z" in the format. And once you fix that issue you no longer need to set the formatter's `timeZone`. – rmaddy May 25 '17 at 20:32
  • timezone is needed in the way back to String if he wants it also to be +0000. Otherwise as noted by rmaddy just don't set the timezone to use the current one – Leo Dabus May 25 '17 at 22:05
  • Thanks for the additional comments. FYI - the 'Z' in the original string is contained in the JSON object that I am parsing. – Wolfstar May 26 '17 at 06:12