-(NSDate *)beginningOfDay:(NSDate *)date
{
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components = [cal components:( NSMonthCalend
Since iOS 8.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+
there is a built in function in the Foundation, which you can use out of the box. No need to implement own functions.
public func startOfDay(for date: Date) -> Date
So you can use it this way:
let midnightDate = Calendar(identifier: .gregorian).startOfDay(for: Date())
It's worth to remember, that this takes upon consideration the device time zone. You can set .timeZone
on calendar
if you want to have eg UTC zone.
Link to the Apple reference pages: https://developer.apple.com/reference/foundation/nscalendar/1417161-startofday.
I think the most succinct way to do this in Swift is as follows:
extension Date {
func startOfDay() -> Date {
return Calendar.current.startOfDay(for: self)
}
func endOfDay() -> Date {
return Calendar.current.date(bySettingHour: 23, minute: 59, second: 59, of: self) ?? self
}
}
In Swift 5.3, both Calendar.current.startOfDay() and Calendar.current.date(bySettingHour:, minute:, second:, of:) are timezone specific. If you want your date to normalize to the same time regardless of timezone, you should use GMT time like this.
// Normalize time of aDate to 12:00 GMT
let aDate = Date()
let twelveGMT = 12 + TimeZone.current.secondsFromGMT() / 3600
let normalizedDate = Calendar.current.date(bySettingHour: twelveGMT, minute: 0, second: 0, of: aDate)
In Swift 3 and above
extension Date {
var startOfDayDate: Date {
return Calendar.current.startOfDay(for: self)
}
var endOfDayDate: Date {
let nextDayDate = Calendar.current.date(byAdding: .day, value: 1, to: self.startOfDayDate)!
return nextDayDate.addingTimeInterval(-1)
}
}
Usage:
var currentDayStart = Date().startOfDayDate
var currentDayEnd = Date().endOfDayDate
One more way to get result:
NSDate *date = [NSDate date];
NSDateComponents *components = [[NSDateComponents alloc] init];
components.day = [[NSCalendar currentCalendar] ordinalityOfUnit:(NSCalendarUnitDay) inUnit:(NSCalendarUnitEra) forDate:date];
NSDate *dayBegin = [[NSCalendar currentCalendar] dateFromComponents:components];
components.day += 1;
NSDate *dayEnd = [[NSCalendar currentCalendar] dateFromComponents:components];
extension Date {
func stringFrom(dateFormat: String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = dateFormat
return formatter.string(from: self)
}
func firstSecondInDay() -> Date {
let dayStr = self.stringFrom(dateFormat: "yyyy-MM-dd")
let firstSecondStr = "\(dayStr) 00:00:00"
let format = DateFormatter()
format.dateFormat = "yyyy-MM-dd HH:mm:ss"
return format.date(from: firstSecondStr)!
}
func lastSecondInDay() -> Date {
let dayStr = self.stringFrom(dateFormat: "yyyy-MM-dd")
let laseSecondStr = "\(dayStr) 23:59:59"
let format = DateFormatter()
format.dateFormat = "yyyy-MM-dd HH:mm:ss"
return format.date(from: laseSecondStr)!
}
}