DEV Community

emin
emin

Posted on

Converting Date to String and back

There you are, coding away, all is fine, birds are chirping, keys are not getting stuck on your 2018 MBPro...but in the distance, Date() approaches . . .

scary image

Jokes aside dates are not that hard to work with most of the time. Accuracy isn't that important for majority of apps, but if you go down the rabbit hole of dates, there is no telling where you might end up.

Computerfile said it best in this video, so do check it out as it is quite fun and it will gives you a bit more insight.


If you create a Date() in your code, and print it, you will get something like so ↙️

var today = Date()
print(today)

// prints -> "2020-04-22 19:34:58 +0000"
Enter fullscreen mode Exit fullscreen mode

When working with an API you will most probably get 2020-04-22T19:34:58+0000

Looks like a long string of...something...right? But fear not, it's actually very well structured, and quite logical once you know what to look for.

The most common standard or standard standard is ISO 8601, and this is how it is constructed

ISO

And now all of that makes complete sense. Except for that Z thing. Like...Zee UTC? πŸ€ͺ


Get that Date!

Now that we know what we are looking at, first, we need to convert String -> Date.

// Info we got from backend.
let stringDateFromAPI = "2007-01-09T09:41:00-0700"

// Creating a formatter and setting the current locale
let formatter = DateFormatter()
formatter.locale = .current

// Telling the formatter what what kind of format we are expecting.
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"

// Creating the date object
let dateFromAPI = formatter.date(from: stringDateFromAPI)

print(dateFromAPI ?? "Unknown")
// πŸ–¨ 2007-01-09 16:41:00 +0000 // But now its a date, not a string.
Enter fullscreen mode Exit fullscreen mode

We got our Date() all nice and tidy. From here on, we have LOADS of choices for time formatting.

Keep in mind that the hours and minutes are based on the current user location since we used .current for the .locale setting. In case that you want to use the source time, just omit that formatter setting.

This date can be converted to a proper string now, in various ways. Here I will show you 2 main approaches that I use:


Going Native ο£Ώ (βŒ₯#1)

Swift DateFormatter already has some pre-defined formats that might get the job done. Take a look at the print output for each. If you don't need a lot of control of your date, feel free to use these ⬇️

// Since dateFromAPI is an optional Date,
// I am using todays date as a default.

let nativeFormatter = DateFormatter()
nativeFormatter.locale = .current

nativeFormatter.dateStyle = .full
print(nativeFormatter.string(from: dateFromAPI ?? Date()))
// πŸ–¨ Tuesday, January 9, 2007

nativeFormatter.dateStyle = .long
print(nativeFormatter.string(from: dateFromAPI ?? Date()))
// πŸ–¨ January 9, 2007

nativeFormatter.dateStyle = .medium
print(nativeFormatter.string(from: dateFromAPI ?? Date()))
// πŸ–¨ Jan 9, 2007

nativeFormatter.dateStyle = .none
print(nativeFormatter.string(from: dateFromAPI ?? Date()))
// πŸ–¨

nativeFormatter.dateStyle = .short
print(nativeFormatter.string(from: dateFromAPI ?? Date()))
// πŸ–¨ 1/9/07
Enter fullscreen mode Exit fullscreen mode

Custom Formatting πŸ›  (βŒ₯#2)

In case you need a more granulated control, just create your own custom formatter. Maybe even add some emojis to it? πŸ€·β€β™‚οΈ

let customFormater = DateFormatter()
customFormater.locale = .current
customFormater.dateFormat = "πŸ—“ MMM d yyyy πŸ“²"
print(customFormater.string(from: dateFromAPI ?? Date()))
// πŸ—“ Jan 9 2007 πŸ“²
Enter fullscreen mode Exit fullscreen mode

When creating a custom format, pay attention which notation you are using for the .dateFormat. It can get a wee bit touchy feely.

For example, lower-caps m is used for minutes, while capital M for months. Here are some examples below and their output. ⬇️


Input Output
MMM Jan
MM 01
M 1
d 9
dd 09
y 2007
yy 07
yyy 2007
yyyy 2007
HH:mm 17:41
hh:mm 05:41
hh:mm a 05:41 PM
E Tue

You are now able to mix-n-match to create your custom DateFormatter!

You will fear the dates no longer!


As promised, here is the extension on String you can use for your projects and handle most API responses.

extension String {
    func convertToReadableDate() -> String? {

        let formatter = DateFormatter()
        formatter.locale = .current

        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
        guard let dateFromAPI = formatter.date(from: self) else { return nil}

        formatter.dateFormat = "MMM d yyyy"
        return formatter.string(from: dateFromAPI)
    }
}

// Usage: 
// label.text = "someDateString".convertToReadableDate()
Enter fullscreen mode Exit fullscreen mode

Thank you for reading! Feel free to get in touch on Twitter

Cheers! 🍻

Top comments (0)