Search code examples
iosswiftdate-formatdateformatter

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


I'm working on an iOS project in swift 5. In one of my API, the date is coming in the format, "yyyy-MM-dd HH:mm:ss.m". And from this date, I need to fetch the time. But the issue is, suppose the date I'm getting from API is "1900-01-01 08:30:00.000000", and when I convert this date format to YYYY-MM-dd HH:mm:ss, the result is coming as "1900-01-01 08:00:00", the time before conversion is 08:30:00.000000 but after conversion 08:00:00. Why it is happening? Please help me.

I will add my code here,

    let dateTime = "1900-01-01 08:30:00.000000"
    let outFormatter = DateFormatter()
    outFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.m"

    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"
        outFormatter.locale = tempLocale
        let exactDate = outFormatter.string(from: date)
        //here the value of exactDate is 1900-01-01 08:00:00
    }

Solution

  • 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