Creepy output of Date()-Function!

let dateString = "03/01/2018"

let dateFormatter = DateFormatter()

dateFormatter.dateFormat = "mm/dd/yyyy"

let cl = dateFormatter.date(from: dateString)  ->outputs:   Jan 1, 2018 at 12:03 AM

print (cl!)   ->    outputs:   2017-12-31 23:03:00 +0000\n

Does someone have an idea what is happening here???

The date/time format for the (two-digit) month is "MM" (with capital "M"):

let dateString = "03/01/2018"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy"
let cl = dateFormatter.date(from: dateString)
print (cl!) // 2018-02-28 23:00:00 +0000

which is correct for my timezone.

That is actually unrelated to the Swift language. DateFormatter uses (as far as I know) the ICU library under the hood. The date format patterns are documented e.g. here http: //userguide.icu-project.org/formatparse/datetime and here: UTS #35: Unicode LDML: Dates .

Thank you! Now I have to figure out how to put the correct timezone...

extension Locale {
    static var current : Locale { return Locale.init(identifier: "de_De") }
}

...should be the correct date in Berlin, Germany

I’m not sure what your goal is, but setting a fixed-format date string without pinning the locale to en_US_POSIX is almost always a mistake. The three standard approaches for DateFormatter are:

  • If the date is meant to be seen (or input) by users, you should be using one of the predefined formats:

      let d = Date()
      let s1 = DateFormatter.localizedString(from: d, dateStyle: .short, timeStyle: .none)
      print(s1) // -> 04/03/2019
    
  • If you need more control over user-visible date strings, use a template:

      let df = DateFormatter()
      df.setLocalizedDateFormatFromTemplate("MM/yyyy")
      let s2 = df.string(from: d)
      print(s2) // -> 03/2019
    
  • If you’re dealing with date strings that aren’t user visible (from a network protocol header, for example), use either ISO8601DateFormatter or the en_US_POSIX locale.

Trying to mix’n’match these approaches generally doesn’t end well. QA1480 NSDateFormatter and Internet Dates has a specific example of how things can go wrong (but there are many others).

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

3 Likes

thanks a lot!
my goal is actually to output the time between a given date (set by the user)
und the actual date (today) in days, weeks, months and years.
problem is that I can only output one value for the hole distance...
and weeks isn't possible at all :frowning:

let cal = Calendar.current

let d1 = Date()

let d2 = Date.init(timeIntervalSince1970: 1524787201-1591201-100740)

let hours = cal.dateComponents([.hour], from: d2 , to: d1)

let days = cal.dateComponents([.day], from: d2 , to: d1)

let months = cal.dateComponents([.month], from: d2 , to: d1)

let years = cal.dateComponents([.year], from: d2 , to: d1)

let diff1 = days.day!

let diff2 = months.month

let diff3 = years.year

print (diff1)

print (diff2!)

print (diff3!)

my goal is actually to output the time between a given date [and] the
actual date

Thanks for the high-level explanation. Have you looked at DateIntervalFormatter? It may not be flexible enough to meet your needs, but it’s definitely worth looking at before you start doing this by hand.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

2 Likes

I will definitely check that! thanks a lot!