NSDate开始的一天和结束的一天

-(NSDate *)beginningOfDay:(NSDate *)date { NSCalendar *cal = [NSCalendar currentCalendar]; NSDateComponents *components = [cal components:( NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date]; [components setHour:0]; [components setMinute:0]; [components setSecond:0]; return [cal dateFromComponents:components]; } -(NSDate *)endOfDay:(NSDate *)date { NSCalendar *cal = [NSCalendar currentCalendar]; NSDateComponents *components = [cal components:( NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date]; [components setHour:23]; [components setMinute:59]; [components setSecond:59]; return [cal dateFromComponents:components]; } 

当我打电话时:[self endOfDay:[NSDate date]]; 我得到这个月的第一个…为什么呢? 我使用这两个方法,因为我需要从第一个date(beginningOfDay:date1)的第一秒到第二个date(endOfDay:Date2)的最后一秒的间隔…

你错过了“NSDayCalendarUnit”中

 NSDateComponents *components = [cal components:( NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date]; 

开始的一天/结束的一天

  // Extension extension NSDate { var startOfDay: NSDate { return NSCalendar.currentCalendar().startOfDayForDate(self) } var endOfDay: NSDate? { let components = NSDateComponents() components.day = 1 components.second = -1 return NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: startOfDay, options: NSCalendarOptions()) } } 

分解

 // Given date let date = NSDate() // First moment of a given date let startOfDay = NSCalendar.currentCalendar().startOfDayForDate(date) // Components to calculate end of day let components = NSDateComponents() components.day = 1 components.second = -1 // Last moment of a given date let endOfDay = NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: startOfDay, options: NSCalendarOptions()) 

SWIFT 3

 extension Date { var startOfDay: Date { return Calendar.current.startOfDay(for: self) } var endOfDay: Date? { var components = DateComponents() components.day = 1 components.second = -1 return Calendar.current.date(byAdding: components, to: startOfDay) } } 

我的NSDate的Swift扩展:

Swift 1.2

 extension NSDate { func beginningOfDay() -> NSDate { var calendar = NSCalendar.currentCalendar() var components = calendar.components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay, fromDate: self) return calendar.dateFromComponents(components)! } func endOfDay() -> NSDate { var components = NSDateComponents() components.day = 1 var date = NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: self.beginningOfDay(), options: .allZeros)! date = date.dateByAddingTimeInterval(-1)! return date } } 

Swift 2.0

 extension NSDate { func beginningOfDay() -> NSDate { let calendar = NSCalendar.currentCalendar() let components = calendar.components([.Year, .Month, .Day], fromDate: self) return calendar.dateFromComponents(components)! } func endOfDay() -> NSDate { let components = NSDateComponents() components.day = 1 var date = NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: self.beginningOfDay(), options: [])! date = date.dateByAddingTimeInterval(-1) return date } } 

在iOS 8+中,这非常方便。 你可以做:

 let startOfDay = NSCalendar.currentCalendar().startOfDayForDate(date) 

为了获得一天的结束,那么只需使用NSCalendar方法23小时59分59秒,这取决于你如何定义结束date。

 // Swift 2.0 let components = NSDateComponents() components.hour = 23 components.minute = 59 components.second = 59 let endOfDay = NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: startOfDay, options: NSCalendarOptions(rawValue: 0)) 

datemath

Apple iOS NSCalendar文档 。 (参见章节: 日历计算

由NSHipster讨论的NSCalendar方法 。

Swift 4 –Date类而不是NSDateCalender而不是NSCalender XCode 9

 extension Date { var startOfDay : Date { let calendar = Calendar.current let unitFlags = Set<Calendar.Component>([.year, .month, .day]) let components = calendar.dateComponents(unitFlags, from: self) return calendar.date(from: components)! } var endOfDay : Date { var components = DateComponents() components.day = 1 let date = Calendar.current.date(byAdding: components, to: self.startOfDay) return (date?.addingTimeInterval(-1))! } } 

用法:

  let myDate = Date() let startOfDate = myDate.startOfDay let endOfDate = myDate.endOfDay 

您不必将组件设置为零,只需忽略它们:

 -(NSDate *)beginningOfDay:(NSDate *)date { NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:date]; return [calendar dateFromComponents:components]; } 

对于我来说,没有在这里的答案,而且在stackoverflow工作。 为了开始今天我做到了这一点。

 NSCalendar * gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; [gregorian setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; NSDateComponents *components = [gregorian components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:[NSDate date]]; [components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; NSDate *beginningOfToday = [gregorian dateFromComponents:components]; 

注意这个[gregorian setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];[components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

创build日历时,会使用当前时区进行初始化,并且从其组件中提取date,因为NSDate没有时区,所以将当前时区的date视为UTC时区。 所以我们需要在提取组件之前设置时区,之后再从这些组件提取date。

Swift 3

  class func today() -> NSDate { return NSDate() } class func dayStart() -> NSDate { return NSCalendar.current.startOfDay(for: NSDate() as Date) as NSDate } class func dayEnd() -> NSDate { let components = NSDateComponents() components.day = 1 components.second = -1 return NSCalendar.current.date(byAdding: components as DateComponents, to: self.dayStart() as Date) } 

Swift3使用* XCode8
苹果正在从类名称中删除NS ,以便NSDate可以换出到Date 。 如果你试图施放它们说它们总是失败,你可能会得到一个编译器警告,但是当它们在操场上运行时,它们可以正常工作。

我用Date生成了核心数据模型中生成的NSDate ,他们仍然可以工作。

 extension Date { func startTime() -> Date { return Calendar.current.startOfDay(for: self) } func endTime() -> Date { var components = DateComponents() components.day = 1 components.second = -1 return Calendar.current.date(byAdding: components, to: startTime())! } } 

您在组件中错过了NSDayCalendarUnit

还有一种获得结果的方法:

 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]; 

另一种使用rangeOfUnit:startDate:interval:options: NSCalendar

 let calendar = NSCalendar.currentCalendar() var startDate : NSDate? var interval : NSTimeInterval = 0 calendar.rangeOfUnit(.Day, startDate: &startDate, interval: &interval, forDate: NSDate()) let startOfDay = startDate let endOfDay = calendar.dateByAddingUnit(.Second, value: Int(interval) - 1, toDate: startOfDay!, options: []) 

由于iOS 8.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+在Foundation中有内置的function,您可以直接使用。 无需执行自己的function。

public func startOfDay(for date: Date) -> Date

所以你可以这样使用它:

let midnightDate = Calendar(identifier: .gregorian).startOfDay(for: Date())

值得一提的是,这需要考虑设备时区。 如果你想有例如UTC区域,你可以在calendar上设置.timeZone

链接到Apple参考页面: https : //developer.apple.com/reference/foundation/nscalendar/1417161-startofday 。

 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)! } }