Search code examples
iosswiftswift4date-format

When I set `HH:mm:ss` on DateFormat, I get `22:42:31 AM` in rare case. ` AM` is unexpected. How can I fix it?


I released an global application. I found a strange formatted timestamp in the log. It is rare cases less than 1% and I can't find the condition. Do you know how I fix it?

  • Expected: most of log

    2018-05-24T06:10:20.22220430Z
    
  • Unexpected: rare cases

    2018-05-24T06:10:20 AM.22220430Z
    
  • code

    public class sample {
        private let formatter = DateFormatter()
    
        private init() {
            self.formatter.timeZone = TimeZone(secondsFromGMT: 0)
            self.formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.AAAAAAAZZZZZ"
        }
        public func timestamp() -> String {
            return self.formatter.string(from: Date())
        }
    }
    

Solution

  • A represents "Milliseconds in day". It is not the same thing as the fractional seconds that you want. For that, use S.

    ZZZZZ gives a timezone in the format such as -08:00. Since you want the actual Z to appear in the output to represent Zulu time, Use X. X combined with the timezone set to 0 seconds from GMT results in Z in the output.

    The above is based on the assumption that the .22220430 in your desired output is all the fractional seconds.

    Your final format should be yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSX.

    And you must also set the formatter's locale to en_US_POSIX. You should always use that locale when using dateFormat to ensure user preferences don't result in unexpected results.

    Also note that you are not really going to get 8 significant digits of fractional seconds. Anything beyond three S is probably pointless.