I have a table view which has few cells. I need to display the date in a human-readable format whose raw format is retrieved from the API call. I am using the below code to call the convertToDate function which takes care of taking raw date string of format "yyyy-MM-dd'T'HH:mm:ssX" and converting it to "MMMM dd, yyyy 'at' hh:mm a". However as we know Date formatters can be expensive. Can anyone please help me answer a few questions looking at the below code implementation?
Note : I am calling the function convertToDate from my cellForRowAt method inside tableView
Is it good practice to create a singleton class so that only one Dateformatter instance is created ( so it is less expensive )
I am also creating a DispatchQueue which is concurrent so that Dateformatter is thread-safe. Is that good practice?
Will calling convertToDate with convertToDate which is concurrent cause any lag in performance when scroll table views?
Are there any standard references to handle/create Dateformatter in general?
Below code converts: "2023-12-22T13:17:27Z" to "December 22, 2023 at 01:17 PM"
Code
import Foundation
class DateUtils {
static let shared = DateUtils()
let dateFormatter = DateFormatter()
// Date formatter are not thread safe and adding this to a concurrent queue makes if safer.
// For table views cells this may have minimal impact and needs to have performance tested in different cases where used.
private let dateFormatterQueue = DispatchQueue(label: "com.example.dateformatter",
attributes: .concurrent)
private init(){}
func convertToDate(from date: String,
with format: String = "yyyy-MM-dd'T'HH:mm:ssX",
to: String = "MMMM dd, yyyy 'at' hh:mm a") -> String? {
var formattedDate: String?
dateFormatter.dateFormat = format
guard let date = dateFormatter.date(from: date) else {
return nil
}
dateFormatter.dateFormat = to
dateFormatterQueue.sync {
formattedDate = dateFormatter.string(from: date)
}
return formattedDate
}
}
DateFormatter
would be the better choice.Dateformatter
neededThe API call returns most likely JSON.
In the model define the property representing the date
let date: Date
and add the .iso8601
strategy to the decoder to convert the ISO string to Date
on the fly
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
In the cell format the date the modern way
cell.date = item.date.formatted( Date.FormatStyle()
.year()
.month(.wide)
.day(.twoDigits)
.hour(.twoDigits(amPM: .abbreviated))
.minute()
.locale(.init(identifier: "en_US")))
The style can also be defined externally.