How do you create a Swift Date object?

Swift has its own Date type. No need to use NSDate.

Creating a Date and Time in Swift

In Swift, dates and times are stored in a 64-bit floating point number measuring the number of seconds since the reference date of January 1, 2001 at 00:00:00 UTC. This is expressed in the Date structure. The following would give you the current date and time:

let currentDateTime = Date()

For creating other date-times, you can use one of the following methods.

Method 1

If you know the number of seconds before or after the 2001 reference date, you can use that.

let someDateTime = Date(timeIntervalSinceReferenceDate: -123456789.0) // Feb 2, 1997, 10:26 AM

Method 2

Of course, it would be easier to use things like years, months, days and hours (rather than relative seconds) to make a Date. For this you can use DateComponents to specify the components and then Calendar to create the date. The Calendar gives the Date context. Otherwise, how would it know what time zone or calendar to express it in?

// Specify date components
var dateComponents = DateComponents()
dateComponents.year = 1980
dateComponents.month = 7
dateComponents.day = 11
dateComponents.timeZone = TimeZone(abbreviation: "JST") // Japan Standard Time
dateComponents.hour = 8
dateComponents.minute = 34

// Create date from components
let userCalendar = Calendar(identifier: .gregorian) // since the components above (like year 1980) are for Gregorian
let someDateTime = userCalendar.date(from: dateComponents)

Other time zone abbreviations can be found here. If you leave that blank, then the default is to use the user's time zone.

Method 3

The most succinct way (but not necessarily the best) could be to use DateFormatter.

let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm"
let someDateTime = formatter.date(from: "2016/10/08 22:31")

The Unicode technical standards show other formats that DateFormatter supports.

Notes

See my full answer for how to display the date and time in a readable format. Also read these excellent articles:

  • How to work with dates and times in Swift 3, part 1: Dates, Calendars, and DateComponents
  • How to work with dates and times in Swift 3, part 2: DateFormatter
  • How to work with dates and times in Swift 3, part 3: Date arithmetic

This is best done using an extension to the existing NSDate class.

The following extension adds a new initializer which will create a date in the current locale using the date string in the format you specified.

extension NSDate
{
    convenience
      init(dateString:String) {
      let dateStringFormatter = NSDateFormatter()
      dateStringFormatter.dateFormat = "yyyy-MM-dd"
      dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
      let d = dateStringFormatter.dateFromString(dateString)!
      self.init(timeInterval:0, sinceDate:d)
    }
 }

Now you can create an NSDate from Swift just by doing:

NSDate(dateString:"2014-06-06")

Please note that this implementation does not cache the NSDateFormatter, which you might want to do for performance reasons if you expect to be creating many NSDates in this way.

Please also note that this implementation will simply crash if you try to initialize an NSDate by passing in a string that cannot be parsed correctly. This is because of the forced unwrap of the optional value returned by dateFromString. If you wanted to return a nil on bad parses, you would ideally use a failible initializer; but you cannot do that now (June 2015), because of a limitation in Swift 1.2, so then you're next best choice is to use a class factory method.

A more elaborate example, which addresses both issues, is here: https://gist.github.com/algal/09b08515460b7bd229fa .


Update for Swift 5

extension Date {
    init(_ dateString:String) {
        let dateStringFormatter = DateFormatter()
        dateStringFormatter.dateFormat = "yyyy-MM-dd"
        dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale
        let date = dateStringFormatter.date(from: dateString)!
        self.init(timeInterval:0, since:date)
    }
}