Is there a date only (no time) class in Swift? (or Foundation classes)

23,106

Solution 1

There is no date only class that's part of the Foundation framework.

This is a quick way to get a date only representation of an NSDate object:

let now = NSDate()

let dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle
dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle

print(dateFormatter.stringFromDate(now)) // Mar 3, 2016

NSDate's always have times because a date is a single point in time. If you're so inclined you can create a date without a time component but it usually defaults to 12AM:

let dateString = "2016-03-03"
let dateFromStringFormatter = NSDateFormatter()
dateFromStringFormatter.dateFormat = "yyyy-MM-dd"

let dateFromString = dateFromStringFormatter.dateFromString(dateString)
// dateFromString shows "Mar 3, 2016, 12:00 AM"

For Swift 3.0+

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"

// optional
let date = dateFormatter.date(from: "2016-03-03") // Mar 3, 2015 at 12:00 AM

Solution 2

There isn't a date only class in Foundation, but you can strip the time off from a Date object, by using Calendar. In Swift 4:

func stripTime(from originalDate: Date) -> Date {
    let components = Calendar.current.dateComponents([.year, .month, .day], from: originalDate)
    let date = Calendar.current.date(from: components)
    return date!
}

Or as an extension:

extension Date {

    func stripTime() -> Date {
        let components = Calendar.current.dateComponents([.year, .month, .day], from: self)
        let date = Calendar.current.date(from: components)
        return date!
    }

}

Solution 3

Swift 3.0

let date = Date()

let dateFormatter = DateFormatter()
dateFormatter.timeStyle = DateFormatter.Style.none
dateFormatter.dateStyle = DateFormatter.Style.short

dateFormatter.string(from: date) // 12/15/16

Solution 4

If you want to get a Date object in Swift 4, like when you are trying to store a Date object in core data, you can use this method.

 private func getDate() -> Date {
let today = Date()

let dateFormatter = DateFormatter()
dateFormatter.timeStyle = DateFormatter.Style.none
dateFormatter .dateStyle = DateFormatter.Style.short

let dateAsString = dateFormatter.string(from: today)

return dateFormatter.date(from: dateAsString)!
}

based on @John R Perry's answer.

Share:
23,106
Greg
Author by

Greg

Updated on July 09, 2022

Comments

  • Greg
    Greg almost 2 years

    Is there a date only (no time) class in Swift? (or Foundation classes)

    (as an aside if there is not but there is a well known/popular open-source library that implements this if you could mention this)

    EDIT: Updated to clarify with " (or Foundation classes)"

  • Greg
    Greg about 8 years
    if you want to mention there is currently no existing specific date only class (which seems to be the answer) I can select your response
  • Fred Faust
    Fred Faust about 8 years
    Added that there is no foundation class that's date only.
  • Benjohn
    Benjohn about 6 years
    Note that if you encode a date using a time using this approach (Foundation's Date is a point in time as noted above, and is fairly misleadingly named), you must to be extremely careful and consistent about the time zone and calendar that you use for any conversions forwards and backwards and for any computations. If you are not consistent, it is extremely likely that you will get inconsistent behaviour.
  • Shadros
    Shadros almost 6 years
    The best solution to maintain the system's date and time format
  • David Monagle
    David Monagle almost 5 years
    This won't strip anything really. It will just return another date with the time set to 00:00 (midnight). You can achieve the same thing by using Calendar.current.startOfDay(for: date)
  • FateNuller
    FateNuller over 4 years
    Use "yyyy", not "YYYY". Capital Y indicates a "week year" which I believe really only applies to the last and first weeks of the year. This isn't historically correct but just an example: if January 1 of year 2 falls on a Thursday, and you use the YYYY format for the date December 31, year 1, then "YYYY" will return "0002" because the end of that week falls within year 2. You'll incorrectly format the date as 0002-12-31.
  • shim
    shim almost 3 years
    This wouldn't necessarily work if the date you're passing in has a different time zone than the local one (e.g. from a backend).
  • Vinayak Hejib
    Vinayak Hejib about 2 years
    Doesn't work, just returns an other string of the same value!