Swift Date Formats

Download Your

Swift Date Formatting. Tag: swift,nsdateformatter. This one has me perplexed. I'm trying to pull a date string from a button and format is as a date to be store. Since the date calculation occurs here, By setting the minimum date in the calculation, we prevent and catch all backwards dates, and reset them to the current date in one statement. The Whole Code // // ViewController.swift // SwiftDatePickerDemo // // Created by Steven Lipton on 9/21/14.

Free Copy of
The Missing Manual
for Swift Development

The Guide I Wish I Had When I Started Out

Join 20,000+ Developers Learning About Swift Development

Download Your Free Copy

The Foundation framework makes it painless to convert a string to a date, but there are a few pitfalls you need to watch out for. The class we use to convert a string to a date in Swift is DateFormatter (or NSDateFormatter if you are using Objective-C). I encourage you to follow along with me. Fire up Xcode and create a playground.

As I mentioned in the introduction, the DateFormatter class is defined in the Foundation framework. This means we add an import statement for Foundation at the top of the playground.

Let's define the string we plan to convert to a Date object. We start simple. I show you a more advanced example later in this post.

We create a DateFormatter instance to convert the string to a date.

To convert the string to a date, we pass it to the date(from:) method of the DateFormatter class. Let's give that a try.

The method seems to work fine since we don't see any errors or warnings. The problem is that it returns nil. Something is missing.

What is missing isn't too surprising. We passed a string to the date formatter's date(from:) method without specifying the date format of the string. The DateFormatter is powerful, but it isn't magical. It cannot infer the date format of the string. That is something we need to do. Let's set the dateFormat property of the DateFormatter instance and give it another try.

This looks much better.

The dateFormat property is of type String. The value you assign to the dateFormat property needs to conform to UTS or Unicode Technical Standard. The format is quite simple. Here are a few examples.

Pitfalls

You always need to be careful when using the date(from:) method of the DateFormatter class. If the string you pass to the date formatter doesn't match the date format of the date formatter, then date(from:) returns nil. Take a look at this example. Can you spot the mistake?

The date format of the string that is passed to date(from:) method is MM/dd/yy while the dateFormat property has a value of dd/MM/yy. In the eyes of the date formatter, the string that is passed to the date(from:) method is invalid.

This means that you should never forced unwrap the value returned by the date(from:) method. The return type is of type String?, an optional. There is a valid reason for that.

A More Complex Example

The DateFormatter class supports more complex date formats than the one we explored earlier. Take a look at this example. It includes the time and the time zone.

More to Explore

I encourage you to explore the documentation of DateFormatter to explore the other options this class has to offer. We only scratched the surface in this post.

Download Your Free Copy of

Swift Date Formatter

The Missing Manual
for Swift Development

The Guide I Wish I Had When I Started Out

Join 20,000+ Developers Learning About Swift Development

Download Your Free Copy

In the wild world of 2019 SwiftUI development, lots of things aren't documented. One such thing I ran into recently was the usage of RelativeDateTimeFormatter in a Text view.

RelativeDateTimeFormatter is a new formatter which is available in iOS 13+ and macOS 10.15+. Though it's not documented at the time of writing (just like 14.6% of Foundation), there have been a fairamount of folks online writing about it. This formatter formats dates relative each other as well as relative DateComponents - its output looks like 'one minute ago' or 'two minutes from now'.

Swift Date Format

Most blog posts about RelativeDateTimeFormatter show its usage like this:

SwiftUI declares a custom string interpolation (which is a new feature in Swift 5) called LocalizedStringKey.StringInterpolation (also undocumented at the time of writing, like 59.4% of SwiftUI) which allows you to write Text views with formatters like so:

Let's assume I want to show the relative time from the Unix Epoch until now. I'll just write a Text the same way, right?

Unfortunately this doesn't work - the middle text doesn't show up:

Convert european date to us date
Interesting

There's also an error in the console!

As far as I can tell, the reason this happens is because RelativeDateTimeFormatter has a few different methods, with different signatures, for formatting its relative dates:

Only one of those matches the Formatter superclass definition that SwiftUI's string interpolation uses. I'm guessing that RelativeDateTimeFormatter's string(for:) method doesn't call into the same code that localizedString(from:) uses - it seems like string(for:) handles the Date case, but not the DateComponents case.

Swift date from string

Swift Parse Date From String

Hopefully this changes in a future version of iOS, but for now, we can solve the problem in a couple of ways:

Solution #1

Since what we want is the date relative to right now, and that's the default behavior of RelativeDateTimeFormatter, we can just pass in epochTime:

This gets us the result we want:

Note: if you want minutes, seconds, etc, set the formatter's dateTimeStyle and unitStyle

Also note: even though nothing at the surface level is calling localizedString, the string will be properly localized as long as you set the formatter's locale.

Solution #2

We can also ignore the custom string interpolation, and just call the formatter's localizedString:

🎉
Ios date formatter

Either of the solutions above would work for this specific issue, though if you want to output the relative time between two dates (instead of between one date and now) with the formatter: string interpolation, looks like you're out of luck.

Sample code for this post is available on GitHub .