How dashing you look; is the key factor when you have Date[s] 😜. Same goes with our Date
also when we are in the Swift arena. Although dashing may not be the proper term, rather presenting thyself is more appropriate. DateFormatter
comes into play on this occasion. Swift Date formatter is one of the confusing item that we pass by regularly. At the end of this blog post we will make ourself dashing when it comes to Swift Date formatter 😎.
Background:
- What type of formatter are you,
DateFormatter
? - Preparation of using
DateFormatter
. - Example, Example…. want it now !!!!
- Graphical representation of
DateFormatter
. DateFormatter
says: “Do you mind, homie”?- Defining Skeleton of
DateFormatter
DateFormatter
As we can guess from the formatter keyword of DateFormatter
, that it formats the Date into some representing way and that way is textual representation. It turns out that we can also construct Date
from a textual representation also. So basically DateFormatter
is the converter of Date and textual representation.
We already talked in details on Date on our love or hate talk 😉. Free fell to pay a visit.
Pre talk of DateFormatter()
We have to set the following two, after initializing and before using DateFormatter
.
- set the locale for the
DateFormatter
. If not set, then it will use the system provided locale. - set the format style. Now there is two way to do this.
- By setting the dateFormat property.
- Or by setting the dateStyle and/or timeStyle. One or both need to be set based on the provided input.
Such as:
On the following code we will format some random date.
let date = Date(timeIntervalSinceReferenceDate: 60*60*60*24*30*3.5) //"Apr 2, 2018 at 6:00 AM"
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "BD") // BD stands for Bangladesh
formatter.dateStyle = .medium
formatter.timeStyle = .medium
formatter.string(from: date)
formatter.date(from: "Apr 2, 2018 at 6:00:00 AM")
We can always visit the First blog post to read more about ReferenceDate.
Pictorial view
If we want have a pictorial view:
Pretty self explanatory. Though last two methods need some attention. .string(from:)
converts Date
to String
, on the other hand date(from:)
converts String
to Date
.
And also date(from:)
returns an optional Date, Date?
.
yo homie
Localization is a must have for DateFormatter
. Because without knowing the locale the formatter can not represent the Date
on String
or make a Date
from String
formatted date.
In a nutshell: Local
is basically a structure; which provides necessary formatters and symbols, those are define for a specific Locale. Example $
is the currency code on USA
and for UK
it is £
. On Sweden it is common to have ,
as a decimal separator example 123,23 where on Asia it is .
example 123.23. Local
provides us all those and also many others. May be on some future post we will have some more talk on Locale
.
Now back to our Localization discussion on Date
: So on worst case scenario we did not set the locale
for our DateFormatter
, as a result the DateFormatter
will use the system-provided-locale.
And we can imagine the consequences: In some distinct future there is a probable Date
related bug which happens to some user; if lucky we know that it is a group of people having this bug. Too difficult to find out among such possibilities.
OH Come on, we are better than this. We always know, how our program gonna behave. We don’t let other programs to do some uninvited operation on our own program; thats become a guess based bug for us.
Always set the locale
just after DateFormatter
initialization and must be before using that DateFormatter
. Setting the locale
should be the very second line of our DateFormatter
task.
dateFormat vs dateStyle with/without timeStyle
To retrieve or relinquish Date
, we need to have a skeleton based on which we can get and set the date.
There are two ways to achieve this.
- One was is to respect the locale and set the formatter style by defining
dateStyle
and/ortimeStyle
. - Another way is to use a fixed format irrespective of locale.
For the next section discussion, I am confident that we already set the local
for our Date
instance. 🧐
Let’s talk about the first option first.
dateStyle
and timeStyle
Example is the best way to start. You can find the date format by countries on wikipedia. What does this list means? It means, a specific country follows a/multiple fixed format for Date. Let’s pick Iceland and Panama, as our example. We can list the following:
- Iceland:
dd.mm.yyyy
- Panama: Short format:
mm/dd/yyyy
and Long format:d
de
mmmm
de
yyyy
Now dateStyle
and timeStyle
both are enum
. Having values like none
, short
, medium
, long
, full
.
So after setting the corresponding locale, Iceland or Panama, if we set the dateStyle
according to the value such as short
long
then we should be able to represent the Date
into String
and vice versa using our dateFormatter.
let date = Date(timeIntervalSinceReferenceDate: 60*60*60*24*30*3.5)
let icelandFormatter = DateFormatter()
icelandFormatter.locale = Locale(identifier: "IS") // IS stands for Iceland
icelandFormatter.dateStyle = .short
let stringDate = icelandFormatter.string(from: date) // "2.4.2018"
let formattedDate = icelandFormatter.date(from: "5.11.2018") //"Nov 5, 2018 at 12:00 AM"
We are skipping the TimeStyle
here.
Now the good thing about using the dateStyle
is: the end user is happy, because he/she is seeing the comfortable date presentation. The user need not to look for another round to figure out the date.
dateFormatter
But the happy story will not be same for all the requirements. In some times we need to have a fixed format of date regardless on the user Locale. In this case we have to use the fixed-date-formatter, dateFormatter
.
For dateFormatter
we will use a fixed String
, EEEE, MMM d, yyyy
, for identifying the date-string. EEEE
stands for day name. There is the ref section at the bottom if we need some help with the symbolic representation of Date component.
let date = Date(timeIntervalSinceReferenceDate: 60*60*60*24*30*3.5)
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "BD")
formatter.dateFormat = "EEEE, MMM d, yyyy"
formatter.string(from: date) // "Monday, Apr 2, 2018"
formatter.date(from: "5.11.2018") // nil
Just small note: as the 5.11.2018
does not have a format of EEEE, MMM d, yyyy
, thus calling the formatter.date(from: "5.11.2018")
yields nil
.
When to use which one
The choice among dateFormat
and dateStyle
is actually based on requirement.
- When the requirement is to have the user preferred way or respecting the user locale then we must use
dateStyle
. - On the other hand if the requirement is some fixed format irrespective of user’s locale, then we have no other choice but to use the
dateFormat
. - Another case we have to consider, when the format is locale to a group of people and also the format is fixed then again we have to use
dateFormat
.
So on the next time we gonna work with date, we have to ask the question of, will we support the locale for date? If not then what is the fixed format of date?
Also keep in mind that, probably we will always need multiple DateFormatter
for our apps, so be prepared for that. Also DateFormatter
are expensive to create, so we will try to reuse them as much as we can.
Conclusion
So here we are at the end of Swift Date formatter talk. This blog post comes to an end of our Date talk on Swift. Inshallah In recent future we will have another case study based talk where we will implement our knowledge on Swift Date and Swift Date formatter. Till then be dashed with your Date[s] 🤓.
One thought on “Format your Date[s]”