9

I am trying to get only date that means hours, mins, seconds are zeroes. This is what i am trying

extension Date {

    var onlyDate: Date? {
        get {
            let calender = Calendar.current
            var dateComponents = calender.dateComponents([.year, .month, .day], from: self)
            dateComponents.timeZone = NSTimeZone.system
            return calender.date(from: dateComponents)
        }
    }

}

When i try

date = Date().onlyDate 

My Output

It returns the previous date. You can check the screenshot that its giving me 14th April while it should have been 15th

Ahsan Aasim
  • 1,177
  • 3
  • 14
  • 40
  • 1
    please check this same Question https://stackoverflow.com/questions/35700281/date-format-in-swift – Ahtazaz Apr 15 '19 at 11:51
  • 1
    For a “timeless” date you should use noon instead of midnight – Leo Dabus Apr 15 '19 at 12:08
  • Does this answer your question? [Date Format in Swift](https://stackoverflow.com/questions/35700281/date-format-in-swift) – mahan Jun 10 '21 at 15:04

2 Answers2

12

Let me guess, you are in the GMT+6 time zone, aren't you?

When Dates are printed, they always show up in UTC.

2019-04-14 18:00 UTC is the same as 2019-04-15 00:00 in your local time zone.

Your code is not wrong. It works fine.

To see it in your time zone, use a DateFormatter and set the timeZone property:

let formatter = DateFormatter()
formatter.timeStyle = .none
formatter.dateStyle = .full
formatter.timeZone = TimeZone.current
print(formatter.string(from: Date().onlyDate))
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • will it work with date? formatter.date(from: yourDate) will not work – dinesh sharma Apr 15 '19 at 14:03
  • What do you mean? Note that a `Date` is just a point in time. `2019-04-14 18:00 UTC` is the same point in time as `2019-04-15 00:00 GMT+6`. You don't need to change anything about your `Date` object. You just need to change your way of displaying the date. @dineshsharma – Sweeper Apr 15 '19 at 14:12
  • extension Date { var onlyDate: Date { get { let calender = Calendar.current var dateComponents = calender.dateComponents([.year, .month, .day], from: self) let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy:MM:dd" let date = calender.date(from: dateComponents) let stringDate = dateFormatter.string(from: date!) print(stringDate) print(dateFormatter.date(from: stringDate)) return dateFormatter.date(from: stringDate)! } } } – dinesh sharma Apr 15 '19 at 14:15
  • you can run it by:- let date = Date().onlyDate line. please try it – dinesh sharma Apr 15 '19 at 14:16
  • No you don't need to change anything in the extension.Your extension is correct. The `date` object you get from `Date().onlyDate` is correct. The thing that's wrong is how you display it. See the edit. @dineshsharma – Sweeper Apr 15 '19 at 14:19
  • Now i got the concept. Thanks – Ahsan Aasim Apr 16 '19 at 08:10
0

Date is a point in time. Making some of its components zero can only work in conjunction with given time zone, calendar.

What you did looks correctly. But the problem is how your debugger shows date. It again needs to use a certain time zone, calendar which probably matches to what you have on your computer (or device).

To make more sense let's say I am using UTC but am debugging this in -1. Then if I create a date 15.4.2019 at 0:00:00 but debug it I will see 14.4.2019 at 23:00:00.

So Date itself is let's say not human readable. Underneath is I believe a double precision floating value counting seconds from EPOCH 1.1.1970 UTC. You need to apply a calendar and time zone to Date instance and use formatter to convert it to something that you can read (as in 14.4.2019 at 23:00:00 is readable). And if the calendars or time zones are not the same then the results will not be the same. Because at some point 14.4.2019 at 23:00:00 and 15.4.2019 at 0:00:00 were exactly the same moment for 2 different locations on earth.

Matic Oblak
  • 16,318
  • 3
  • 24
  • 43