-
If you’re really looking for direct analog to the method in your question, you could do something like:
class MyObject { // define static variable private static let formatter: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "EEE MMM dd HH:mm:ss Z yyyy" return formatter }() // you could use it like so func someMethod(date: Date) -> String { return MyObject.formatter.string(from: date) } }
The
static
properties, like globals, enjoydispatch_once
behavior for their default values. For more information, see thedispatch_once
discussion at the end of the Files and Initialization entry in Apple’s Swift blog. -
Regarding best practices with date formatters, I would suggest:
-
Yes, it is prudent to not unnecessarily create and destroy formatters that you’re likely to need again. In WWDC 2012 video, iOS App Performance: Responsiveness, Apple explicitly encourages us to
-
Cache one formatter per date format;
-
Add observer for
NSLocale.currentLocaleDidChangeNotification
through theNotificationCenter
, and clearing/resetting cached formatters if this occurs; and -
Note that resetting a format is as expensive as recreating, so avoid repeatedly changing a formatter’s format string.
Bottom line, reuse date formatters wherever possible if you’re using the same date format repeatedly.
-
-
If using
DateFormatter
to parse date strings to be exchanged with a web service (or stored in a database), you should useen_US_POSIX
locale to avoid problems with international users who might not be using Gregorian calendars. See Apple Technical Q&A #1480 or the “Working With Fixed Format Date Representations” discussion in theDateFormatter
documentation. (Or in iOS 10 and macOS 10.12, useISO8601DateFormatter
.)But when using
dateFormat
withDateFormatter
, use the current locale for creating strings to be presented to the end user, but useen_US_POSIX
local when creating/parsing strings to be used internally within the app or to be exchanged with a web service. -
If formatting date strings for the user interface, localize the strings by avoiding using string literals for
dateFormat
if possible. UsedateStyle
andtimeStyle
where you can. And if you must use customdateFormat
, use templates to localize your strings. For example, rather than hard-codingE, MMM d
, in Swift 3 and later, you would usedateFormat(fromTemplate:options:locale:)
:formatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "EdMMM", options: 0, locale: Locale.current)
This will automatically show, for example, “Mon, Sep 5” for US users, but “Mon 5 Sep” for UK users.
-
The
DateFormatter
is now thread safe on iOS 7 and later and 64-bit apps running on macOS 10.9 and later.
-
For Swift 2 examples, see previous revision of this answer.