8

I'm trying create a Date object with day, month and year, but the function of Calendar is returning nil.

let calendar = Calendar.current
let date = calendar.dateComponents([.day,.month,.year], from: Date()).date! // <- nil

How I create a Date object only with day, month and year?

Augusto
  • 3,825
  • 9
  • 45
  • 93
  • 4
    You don't. A `Date` is a point in time. The closest you can get is midnight (locale time or UTC time or some other specific timezone of your choosing). – rmaddy Sep 14 '18 at 19:03
  • 4
    if you don't care about time, Apple recommends that you set the time to noon. Daylight Saving Time may cause certain locations to have no midnight or two midnights in a day. As for how to set the time part of a date, see [this answer](https://stackoverflow.com/questions/36073704/how-to-change-the-current-days-hours-and-minutes-in-swift/36082867#36082867) – Code Different Sep 14 '18 at 19:13
  • https://developer.apple.com/videos/play/wwdc2013/227/ – Leo Dabus Sep 14 '18 at 19:18

2 Answers2

17

As a supplement to rmaddy's answer, the reason why your code returns nil is that you try to convert DateComponents to a Date without specifying a Calendar.

If that conversion is done with a calendar method

let calendar = Calendar.current
let components = calendar.dateComponents([.day, .month, .year], from: Date())
let date = calendar.date(from: components)

or if you add the calendar to the date components

let calendar = Calendar.current
let date = calendar.dateComponents([.day, .month, .year, .calendar], from: Date()).date

then you'll get the expected result.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
8

If you want to strip off the time portion of a date (set it to midnight), then you can use Calendar startOfDay:

let date = Calendar.current.startOfDay(for: Date())

This will give you midnight local time for the current date.

If you want midnight of the current date for a different timezone, create a new Calendar instance and set its timeZone as needed.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • 1
    For time insensitive calendrical calculations it is better to use noon – Leo Dabus Sep 14 '18 at 19:14
  • @LeoDabus That should be a comment on the question, not this answer. The OP simply asked how to create a date with no time. We have no idea how it is to be used. – rmaddy Sep 14 '18 at 19:16
  • @rmaddy A date with "no time" should be using noon – Leo Dabus Sep 14 '18 at 19:16
  • That's what I needed. – Augusto Sep 14 '18 at 19:17
  • A `Date` (As in a `Date` object) with no time does not exist. A `Date` object describes an instant in time. You can convert it to a string with just the date, or you can extract the time components from a `Date`, but a `Date` always has an associated time. – Duncan C Sep 14 '18 at 21:55
  • There are scenarios where a calendar program (or other time-management) software is trying to point to "a day" (and not a literal point-initime). The question might have been better with more context, rather than leaving us to speculate. – benc Aug 03 '23 at 12:41