In a previous tip you learned about the
TimeInterval classes. However they don’t help with specific times or localization of time zones. That’s where the
TimeZone classes comes into play. A date component provides a way to add components for a date. We’ll add a few functions to get a date.
Download and open the example playground. I set up a date and a date formatter. It probably runs by itself now, so set it to Manual Run and make the viewer pane a bit bigger
To change time zones,
DateFormatters has a
timeZone property, which takes a
TimeZone object. The simplest
TimeZone object is the
current time zone, which gives you the time zone based on localization settings.
var timeZone = TimeZone.current
Playgrounds returns an identifier. Identifiers for a time zone takes the form of a country, In my case America and a large city, Chicago. Identifiers give a time zone based on a location. There’s a dictionary of identifiers in the system along with abbreviations for time zones. You can also set the
timeZone with an identifier. For example the identifier for Pacific Time in the U.S. Is :
timeZone = TimeZone(identifier: "America/Los Angeles")!
I added the exclamation point here as this is an optional value, returning
nil if that identifier is not found as it is here. Running this you’ll find the value is
nil. For cities with spaces in their names use an underscore
timeZone = TimeZone(identifier: "America/Los_Angeles")!
You can also use an abbreviation of the time zone such as:
timeZone = TimeZone(abbreviation: "PDT")!
Change your date formatter by assigning the time zone to the date formatter’s time zone property:
dateFormatter.timeZone = timeZone
You’ll see in the console we’ve changed the time zone of the date displayed. But what if I know a date and time, say June 4 2018 at 10:00 AM in Cupertino California, and want to know the time of this event in Chicago? The
Date object can’t do that easily, but
DateComponents can. You’ll need to instantiate a date component object, and they can be a bit of a pain. Try instantiating one with the
var dateComponents = DateComponents(calendar: Calendar?, timeZone: TimeZone, era: Int?, year: Int?, month: Int?, day: Int?, hour: Int?, minute: Int?, second: Int?, nanosecond: Int?, weekday: Int?, weekdayOrdinal: Int?, quarter: Int?, weekOfMonth: Int?, weekOfYear: Int?, yearForWeekOfYear: Int?)
There’s 16 parameters in its initializers. Even though they are optional values,
dateComponents won’t work easily without filling them all out. Delete that mess.
So here’s a trick: get the current
dateComponents from the
var dateComponents = Calendar.current.dateComponents(in: TimeZone.current, from: Date())
This takes a
TimeZone and a
Date. I took the current ones to start with. Now I can change the properties of
dateComponents to June 4 2018 at 10:00:00 PDT
dateComponents.timeZone = timeZone dateComponents.year = 2018 dateComponents.month = 6 dateComponents.day = 4 dateComponents.hour = 10 dateComponents.minute = 0 dateComponents.second = 0
To use the date formatter or any of the
Date object functions, I’ll get the date property from the date components
date = dateComponents.date!
Again, it’s optional, in case all the components are not filled out, so I need to unwrap it.
That give me my date in Cupertino. I’ll change my
DateFormatter to my current time zone, which is Chicago
dateFormatter.timeZone = TimeZone.current
Run this and the date is noon in Chicago. This is a simple demo of a very robust series of objects in Foundation. Between all your date options, you’ll find one that works for you.
The Whole Code
Here’s a listing of the code used above. You can also download the finished project on Github at http://bit.ly/TimeZoneEnd
//:# Time Zones and Date Components //: A playground to play with advanced date classes import UIKit //: A date and a date formatter for use with this lesson var date = Date() let dateFormatter = DateFormatter() dateFormatter.dateStyle = .medium dateFormatter.timeStyle = .full //: Type your code here var timeZone = TimeZone.current timeZone = TimeZone(identifier: "America/Los_Angeles")! timeZone = TimeZone(abbreviation: "PDT")! dateFormatter.timeZone = TimeZone.current var dateComponents = Calendar.current.dateComponents(in: timeZone, from: Date()) dateComponents.year = 2018 dateComponents.month = 6 dateComponents.day = 4 dateComponents.hour = 10 dateComponents.minute = 0 dateComponents.second = 0 date = dateComponents.date! //: This will print the date print(dateFormatter.string(from: date))