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
类而不是NSDate
和Calender
而不是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)! } }