skip to Main Content

I am not quiet sure how to make dateFormatter that is reusable, since I read that dateFormatter is really expensive to do multiple times and that I should reuse it if its possible. Currently my function looks like this:

    func formatDate(date: String) -> String {
    let dateFormatterGet = DateFormatter()

    //this is format I get from my response
    dateFormatterGet.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
    let dateFormatterSet = DateFormatter()

    //this is format I would like to show on my screen
    dateFormatterSet.dateFormat = "EEE, dd MMM YYYY, HH:mm a"
    let dateObj: Date? = dateFormatterGet.date(from: date)
    return dateFormatterSet.string(from: dateObj!)
}

I wouldn’t be bothered if I would use it on one screen, but I am using on two, yet maybe its not to expensive either, but I want to know for future cases how to do it properly.

This is function from my other screen, only difference is dateFormatterSet, which I use for showing different format on my screen.

    func formatDate(date: String) -> String {
    let dateFormatterGet = DateFormatter()
    dateFormatterGet.dateFormat = "YYYY-MM-dd'T'HH:mm:ss.SSS'Z'"
    let dateFormatterSet = DateFormatter()
    dateFormatterSet.dateFormat = "EEE, dd MMM"
    guard let dateObj = dateFormatterGet.date(from: date) else { return "Start date 
    unknown"}
    return dateFormatterSet.string(from: dateObj)
}

Thanks in advance.

2

Answers


  1. You don’t need two date formatters to convert one date string to another.

    My suggestion is to create one persistent date formatter with a fixed locale

    let dateFormatter : DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        return formatter
    }()
    

    This could be also an extension

    extension DateFormatter {
        static let posixFormatter : DateFormatter = {
            let formatter = DateFormatter()
            formatter.locale = Locale(identifier: "en_US_POSIX")
            return formatter
        }()
    }
    

    And secondly a function with parameters for input format with a default value and output format

    func formatDate(dateString: String, inFormat: String = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", outFormat: String) -> String? {
    
        // let dateFormatter = DateFormatter.posixFormatter
       
        //this is format I get from my response
        dateFormatter.dateFormat = inFormat
        guard let date = dateFormatter.date(from: dateString) else { return nil }
    
        dateFormatter.dateFormat = outFormat
        return dateFormatter.string(from: date)
    }
    

    You have to check if a date could be created from the string so the return value is an optional.

    Side note:

    The Z in an ISO8601 string is the time zone specifier. It must not be wrapped in single quotes. And the year specifier is always lowercase yyyy.

    Login or Signup to reply.
  2. I was reading about how expensive date formatting is and found a good article that proves why they are expensive and how they are expensive. Based on my understanding I created a solution by using a singleton class and an extension of Dateformatter. You can find it below.

    Article I read: https://sarunw.com/posts/how-expensive-is-dateformatter/

    class MyDateFormatter {
        static let sharedInstance = DateFormatter()
        private init() {
        }
    }
    
    extension DateFormatter{
        func getDateFrom(stringDate:String,format dateFormat:String)->Date?{
            let dateFormatter = MyDateFormatter.sharedInstance
            dateFormatter.dateFormat = dateFormat
            let dateObj: Date? = dateFormatter.date(from: stringDate)
            return dateObj
        }
        
        func getStringFrom(date:Date,format dateFormat:String)->String?{
            let dateFormatter = MyDateFormatter.sharedInstance
            dateFormatter.dateFormat = dateFormat
            let dateString: String? = dateFormatter.string(from: date)
            return dateString
        }
    }
    
    func formatDate(date: String) -> String {
        let dateObj:Date? = MyDateFormatter.sharedInstance.getDateFrom(stringDate: date, format: "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
        let formattedDate:String? = MyDateFormatter.sharedInstance.getStringFrom(date: dateObj!, format: "EEE, dd MMM YYYY, HH:mm a")
        return formattedDate ?? ""
    }
    
    formatDate(date: "2011-11-02T02:50:12.208Z")
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search