I am trying to store Date
data for user actions and set it to always be at start of the day no matter what time user performed the action i.e. User can perform 30 different actions and all of them are stored under the same Date
.
However following produces weird results (it's 29th June at the moment of writing this), but for some reason calendars .startOfDay
produces 28th?
print(Date())
print(Calendar.current.startOfDay(for: Date()))
// 2024-06-29 14:30:18 +0000
// 2024-06-28 21:00:00 +0000
Is there a way to ensure same day is respected?
Followup, I tried this alternative and it produces same result (28th)
let calendar = Calendar.current
var components = calendar.dateComponents([.year, .month, .day], from: date)
components.hour = 0
components.minute = 0
components.second = 0
return calendar.date(from: components) ?? .now
Date
is a very poorly named type. It has nothing to do with dates, and its description
(what you see when you print it) only makes things worse by hinting that it might. A Date
is an instant in time, unrelated to location or calendar. It does not have a time zone (that requires a location). It is not "on a day" (that requires a calendar).
.startOfDay
is not returning the 28th. It's returning the 29th in your time zone. Note that the description
that is printed is in UTC. You're likely running this in UTC+3.
Your example of using .dateComponents
is on the right path (this is basically what .startOfDay
does). You just got in trouble by printing the Date
again. Instead, you'd want to use a Calendar
to fetch the component(s) you want:
Calendar.current.component(.day, from: date)