44

In the images below you can see the code I wrote and the values of all the variables:

class fun getCurrentShortDate() -> String {
    var todaysDate = NSDate()
    var dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "dd-MM-yyyy"
    var DateInFormat = dateFormatter.stringFromDate(todaysDate)

    return DateInFormat
}

Variable values

As you can see the current date is found no problem, but when I try to change the NSDate to a string, it just won't do it.

Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
Friso Buurman
  • 569
  • 1
  • 4
  • 7

8 Answers8

64

Xcode 11 or later • Swift 5.1 or later


extension TimeZone {
    static let gmt = TimeZone(secondsFromGMT: 0)!
}

extension Locale {
    static let ptBR = Locale(identifier: "pt_BR")
}

extension Formatter {
    static let date = DateFormatter()
}

extension Date {
    func localizedDescription(date dateStyle: DateFormatter.Style = .medium,
                              time timeStyle: DateFormatter.Style = .medium,
                              in timeZone: TimeZone = .current,
                              locale: Locale = .current,
                              using calendar: Calendar = .current) -> String {
        Formatter.date.calendar = calendar
        Formatter.date.locale = locale
        Formatter.date.timeZone = timeZone
        Formatter.date.dateStyle = dateStyle
        Formatter.date.timeStyle = timeStyle
        return Formatter.date.string(from: self)
    }
    var localizedDescription: String { localizedDescription() }
}

Date().localizedDescription  // "18 Dec 2021 06:43:50"
Date().localizedDescription(in: .gmt)  // "18 Dec 2021 06:43:50" UTC time
Date().localizedDescription(date: .short, time: .short)  // "18/12/21 03:43"
Date().localizedDescription(date: .full, time: .full)  // "Saturday, 18 December 2021 03:43:50 Brasilia Standard Time"
Date().localizedDescription(date: .full, time: .full, in: .gmt)  // "Saturday, 18 December 2021 06:43:50 Greenwich Mean Time"
Date().localizedDescription(date: .full, time: .full, locale: .ptBR)  // "sábado, 18 de dezembro de 2021 03:43:50 Horário Padrão de Brasília"

extension Date {

    var fullDate: String { localizedDescription(date: .full, time: .none) }
    var longDate: String { localizedDescription(date: .long, time: .none) }
    var mediumDate: String { localizedDescription(date: .medium, time: .none) }
    var shortDate: String { localizedDescription(date: .short, time: .none) }

    var fullTime: String { localizedDescription(date: .none, time: .full) }
    var longTime: String { localizedDescription(date: .none, time: .long) }
    var mediumTime: String { localizedDescription(date: .none, time: .medium) }
    var shortTime: String { localizedDescription(date: .none, time: .short) }

    var fullDateTime: String { localizedDescription(date: .full, time: .full) }
    var longDateTime: String { localizedDescription(date: .long, time: .long) }
    var mediumDateTime: String { localizedDescription(date: .medium, time: .medium) }
    var shortDateTime: String { localizedDescription(date: .short, time: .short) }
}

print(Date().fullDate)  // "Saturday, 18 December 2021\n"
print(Date().shortDate)  // "18/12/21\n"

print(Date().fullTime)  // "03:43:50 Brasilia Standard Time\n"
print(Date().shortTime)  // "03:43\n"

print(Date().fullDateTime)  // "Saturday, 18 December 2021 03:43:50 Brasilia Standard Time\n"
print(Date().shortDateTime)  // "18/12/21 03:43\n"
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • also can add var shortDateTime: String { return "\(self.shortDate) \(self.shortTime)" } – Booyah Feb 21 '17 at 19:54
  • This is cool. How bout getting date/time from a specific `UTC Offset`? – Codetard Oct 09 '18 at 02:29
  • Just pass the desired timezone for the localizedDescription method – Leo Dabus Oct 09 '18 at 10:17
  • how to add milliseconds? – alpha47 May 17 '20 at 17:10
  • There is no `timeStyle` option to add milliseconds but you can set a custom localized `dateFormat` using `DateFormatter`'s method `setLocalizedDateFormatFromTemplate` and pass the milliseconds component `SSS` if you want: `dateFormatter.setLocalizedDateFormatFromTemplate("HHmmssSSS")` – Leo Dabus May 17 '20 at 17:27
22

SWIFT 4 or 5

extension Date {

 static func getCurrentDate() -> String {

        let dateFormatter = DateFormatter()

        dateFormatter.dateFormat = "dd/MM/yyyy HH:mm:ss"

        return dateFormatter.string(from: Date())

    }
}

Using

print(Date.getCurrentDate())
luizMello
  • 2,793
  • 20
  • 17
16

Update for Swift 3.0: Create an extension for Date

extension Date {
    func string(format: String) -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = format
        return formatter.string(from: self)
    }
}

Usage:

Date().string(format: "yyyy-MM-dd")

Swift 2.2: Create an extension for NSDate

extension NSDate {  
    func dateStringWithFormat(format: String) -> String {
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = format
        return dateFormatter.stringFromDate(self)
    }   
}

Usage:

NSDate().dateStringWithFormat("yyyy-MM-dd")
doovers
  • 8,545
  • 10
  • 42
  • 70
  • This will create a new DateFormatter every single time you call this method. – Leo Dabus Oct 08 '19 at 13:42
  • Btw when working with most fixed date formats you should set your locale to `"en_US_POSIX"` otherwise your `DateFormatter` will be affected by the user device locale/settings. `extension Date { static let formatter: DateFormatter = { let formatter = DateFormatter() formatter.locale = Locale(identifier: "en_US_POSIX") return formatter }() func string(format: String) -> String { Date.formatter.dateFormat = format return Date.formatter.string(from: self) } }` – Leo Dabus Oct 08 '19 at 13:49
10

You can create a extension for easily transform a String into a NSDate.

extension NSDate {
    func dateFromString(date: String, format: String) -> NSDate {
        let formatter = NSDateFormatter()
        let locale = NSLocale(localeIdentifier: "en_US_POSIX")

        formatter.locale = locale
        formatter.dateFormat = format

        return formatter.dateFromString(date)!
    }
}

Than in your function you can NSDate().dateFromString("2015-02-04 23:29:28", format: "yyyy-MM-dd HH:mm:ss") and this should works. Input date don't need to be on the same format of output date.

func getCurrentShortDate() -> String {
    var todaysDate = NSDate().dateFromString("2015-02-04 23:29:28", format:  "yyyy-MM-dd HH:mm:ss")

    var dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "dd-MM-yyyy"
    var DateInFormat = dateFormatter.stringFromDate(todaysDate)

    return DateInFormat
}

println(getCurrentShortDate())

The output is 04-02-2015.

Heberti Almeida
  • 1,440
  • 18
  • 27
7

Swift 3

Using the extension created by @doovers and some format strings from this website, you get the following:

extension Date {
    func string(format: String) -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = format
        return formatter.string(from: self)
    }
}

Usage:

Date().string(format: "EEEE, MMM d, yyyy") // Saturday, Oct 21, 2017
Date().string(format: "MM/dd/yyyy")        // 10/21/2017
Date().string(format: "MM-dd-yyyy HH:mm")  // 10-21-2017 03:31

Date().string(format: "MMM d, h:mm a")     // Oct 21, 3:31 AM
Date().string(format: "MMMM yyyy")         // October 2017
Date().string(format: "MMM d, yyyy")       // Oct 21, 2017

Date().string(format: "E, d MMM yyyy HH:mm:ss Z") // Sat, 21 Oct 2017 03:31:40 +0000
Date().string(format: "yyyy-MM-dd'T'HH:mm:ssZ")   // 2017-10-21T03:31:40+0000
Date().string(format: "dd.MM.yy")                 // 21.10.17

You could also pass milliseconds to date object like this:

Date(1508577868947).string(format: "EEEE, MMM d, yyyy") // Saturday, Oct 21, 2017
SpaceX
  • 2,814
  • 2
  • 42
  • 68
4
 let dateformatter1 = DateFormatter()
    dateformatter1.dateFormat = "ccc, d MMM yyy"

    let dateString1 = dateformatter1.string(from: datePicker.date)
    print("Date Selected \(dateString1)")
    labelDate.text = dateString1

    let dateformatter2 = DateFormatter()
    dateformatter2.dateFormat = "dd-MM-yyyy"
    let dateString2 = dateformatter2.string(from: datePicker.date)
    print("Date Selected \(dateString2)")


    let dateformatter3 = DateFormatter()
    dateformatter3.dateFormat = "dd/MM/yyyy"
    let dateString3 = dateformatter3.string(from: datePicker.date)
    print("Date Selected \(dateString3)")

    let dateformatter4 = DateFormatter()
    dateformatter4.dateFormat = "dd MMMM yyyy hh:mm a"
    let dateString4 = dateformatter4.string(from: datePicker.date)
    print("Date Selected \(dateString4)") 

I referred this article on Codzify.com. Really helpful.

Darshan Kunjadiya
  • 3,323
  • 1
  • 29
  • 31
Manish Methani
  • 245
  • 2
  • 7
3

Here's the way Apple suggests

    let formatter = DateFormatter()
    formatter.locale = Locale.current
    formatter.dateStyle = .short
    let dateString = formatter.string(from: date)

or if the pre-defined format of .short, .medium, .long and .full are quite right create the template in a locale

    let formatter = DateFormatter()
    formatter.locale = Locale.current
    formatter.setLocalizedDateFormatFromTemplate("MM/dd/yyyy")
    let dateString = formatter.string(from: date)

Here's the link

Maria
  • 4,471
  • 1
  • 25
  • 26
3

Here is easiest way to change date format.

1. Create one swift class for Date extension.

extension Date {
    func today(format : String = "yyyy-MM-dd'T'HH:mm:ss.SSS") -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = format
        return formatter.string(from: self)
    }
} 
  1. How to use extension.

    let date = Date().today(format: "dd/MM/yy HH:mm:ss")

    print(date)

Parth Patel
  • 915
  • 11
  • 33
  • This is wrong. `YYYY` is for YearForWeekOfYear. You need to use `yyyy`. Besides that creating a DateFormatter is "expensive". This will create a new date formatter every time you call this method. Second you should always set the date formatter's locale to "en_US_POSIX" before setting the dateFormat when using a fixed date format. – Leo Dabus Dec 18 '21 at 06:17
  • try this `DateComponents(calendar: .current, year: 2022, month: 1, day: 1).date!.today()` // "2021-12-18T03:21:18.422" You are creating a instance method and discarding self. If the date doesn't matter it is only for today declare it as static. The usage would be `Date.today()` – Leo Dabus Dec 18 '21 at 06:21
  • if you want to keep it as an instance method and change it to `return formatter.string(from: self)` make sure to fix the year otherwise `DateComponents(calendar: .current, year: 2022, month: 1, day: 1).date!.today()` would result in `"2021-01-01T00:00:00.000"` – Leo Dabus Dec 18 '21 at 06:26
  • 1
    I would also add the timezone to the default dateFormat `"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"` and set it to UTC (zero seconds from GMT). Check this [post](https://stackoverflow.com/a/28016692/2303865) – Leo Dabus Dec 18 '21 at 06:29
  • 1
    you are still using `YYYY` which is wrong. This will result in wrong years when the date is in the first or last week of the year. Again you should use `yyyy` – Leo Dabus Dec 23 '21 at 01:16
  • @LeoDabus This is just an example. You can customize it and get results as per your requirement. – Parth Patel Jan 31 '22 at 05:53