I'm making an api call to randomuser.me and getting back a json file containing (amongst other data):
"dob": { "date": "1993-07-20T09:44:18.674Z", "age": 26 }
I'd like to display the date string in a text label as "dd-MMM-yyyy" but can't figure out how to format the string to achieve this.
I'v tried converting it into a date using ISO8601DateFormatter and then back into a string but have had no luck so far.
Can anyone help?
func getUserData() {
let config = URLSessionConfiguration.default
config.urlCache = URLCache.shared
let session = URLSession(configuration: config)
let url = URL(string: "https://randomuser.me/api/?page=\(page)&results=20&seed=abc")!
let urlRequest = URLRequest(url: url, cachePolicy: .returnCacheDataElseLoad, timeoutInterval: 15.0)
let task = session.dataTask(with: urlRequest) { data, response, error in
// Check for errors
guard error == nil else {
print ("error: \(error!)")
return
}
// Check that data has been returned
guard let content = data else {
print("No data")
return
}
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let fetchedData = try decoder.decode(User.self, from: content)
for entry in fetchedData.results {
self.usersData.append(entry)
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch let err {
print("Err", err)
}
}
// Execute the HTTP request
task.resume()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "userInfoCell") as! UserInfoCell
let user: Result
if isFiltering {
user = filteredData[indexPath.row]
} else {
user = usersData[indexPath.row]
}
cell.nameLabel.text = "\(user.name.first) \(user.name.last)"
cell.dateOfBirthLabel.text = user.dob.date
cell.genderLabel.text = user.gender.rawValue
cell.thumbnailImage.loadImageFromURL(user.picture.thumbnail)
return cell
}
pass your date into this
let dateFormatterPrint = DateFormatter()
dateFormatterPrint.dateFormat = "dd-MM-yyyy"
let val = dateFormatterPrint.string(from: "pass your date")
import Foundation
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
let theDate = dateFormatter.date(from: "1993-07-20T09:44:18.674Z")!
let newDateFormater = DateFormatter()
newDateFormater.dateFormat = "dd-MMM-yyyy"
print(newDateFormater.string(from: theDate))
First convert the string to date using proper date format. Then convert it back to string using the format you want.
You can use extensions for you to be able to convert the date to your desired format.
var todayDate = "1993-07-20T09:44:18.674Z"
extension String {
func convertDate(currentFormat: String, toFormat : String) -> String {
let dateFormator = DateFormatter()
dateFormator.dateFormat = currentFormat
let resultDate = dateFormator.date(from: self)
dateFormator.dateFormat = toFormat
return dateFormator.string(from: resultDate!)
}
}
Then you can implement like this:
cell.dateOfBirthLabel.text = self.todayDate.convertDate(currentFormat: "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", toFormat: "dd-MMM-yyyy")
Generally, if manually converting 1993-07-20T09:44:18.674Z
to a Date
, we'd use ISO8601DateFormatter
:
let formatter = ISO8601DateFormatter()
formatter.formatOptions.insert(.withFractionalSeconds)
In this approach, it takes care of time zones and locales for us.
That having been said, if you're using JSONDecoder
(and its dateDecodingStrategy
outlined below), then we should define our model objects to use Date
types, not String
for all the dates. Then we tell the JSONDecoder
to decode our Date
types for us, using a particular dateDecodingStrategy
.
But that can't use the ISO8601DateFormatter
. We have to use a DateFormatter
with a dateFormat
of "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
and a locale
of Locale(identifier: "en_US_POSIX")
:
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0) // this line only needed if you ever use the same formatter to convert `Date` objects back to strings, e.g. in `dateEncodingStrategy` of `JSONEncoder`
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .formatted(formatter)
See the “Working With Fixed Format Date Representations” sections of the DateFormatter
documentation .
Then, for your formatter for your UI, if you absolutely want dd-MMM-yyyy
format, you would have a separate formatter for that, eg:
let formatter = DateFormatter()
formatter.dateFormat = "dd-MMM-yyyy"
Note, for this UI date formatter, we don't set a locale
or a timeZone
, but rather let it use the device's current defaults.
That having been said, we generally like to avoid using dateFormat
for date strings presented in the UI. We generally prefer dateStyle
, which shows the date in a format preferred by the user:
let formatter = DateFormatter()
formatter.dateStyle = .medium
This way, the US user will see “Nov 22, 2019”, the UK user will see “22 Nov 2019”, and the French user will see “22 nov. 2019”. Users will see dates in the formats with which they are most accustomed.
See “Working With User-Visible Representations of Dates and Times” in the aforementioned DateFormatter
documentation .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.