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]];
Я получаю первое число месяца ... Почему? Я использую эти два метода, потому что мне нужен интервал, который находится от первой секунды первой даты (beginningOfDay:date1) до последней секунды второй даты (endOfDay:Date2) ...
16 ответов:
вы пропали без вести
NSDayCalendarUnitinNSDateComponents *components = [cal components:( NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];
Начало Дня / Конец Дня-Swift 4
// Extension 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)! } var startOfMonth: Date { let components = Calendar.current.dateComponents([.year, .month], from: startOfDay) return Calendar.current.date(from: components)! } var endOfMonth: Date { var components = DateComponents() components.month = 1 components.second = -1 return Calendar.current.date(byAdding: components, to: startOfMonth)! } } // End of day = Start of tomorrow minus 1 second // End of month = Start of next month minus 1 second
в iOS 8+ это действительно удобно; вы можете сделать:
let startOfDay = NSCalendar.currentCalendar().startOfDayForDate(date)чтобы получить конец дня, просто используйте методы NSCalendar в течение 23 часов, 59 минут, 59 секунд, в зависимости от того, как вы определяете конец дня.
// 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))документация Apple iOS NSCalendar. (См. Раздел:Календарным Расчетам)
мои расширения Swift для NSDate:
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 } }
Swift 4 Простой и более точный ответ.
время начала: 00:00:00
время окончания: 23:59:59.5
var date = Date() // current date or replace with a specific date var calendar = Calendar.current let dateAtMidnight = calendar.startOfDay(for: date) let dateAtEnd = calendar.date(bySettingHour: 23, minute: 59, second: 59, of: date)
Swift 4-XCode 9 С
Dateкласс вместоNSDateиCalenderвместоNSCalenderextension 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]; }
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) }
для меня ни один из ответов здесь, и еще где на сайте 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]];.при создании календаря он инициализируется текущим часовым поясом, а когда дата извлекается из его компонентов, поскольку NSDate не имеет часового пояса, дата из текущего часового пояса считается часовым поясом UTC. Поэтому нам нужно установить часовой пояс перед извлечением компонентов и позже при извлечении даты из этих компонентов.
Swift3 используя * XCode8
Apple удаляетNSот имени класса, так чтоNSDateможет быть заменен наDate. Вы можете получить предупреждение компилятора, если вы попытаетесь бросить их, говоря, что они всегда будут терпеть неудачу, но они отлично работают, когда вы запускаете их на игровой площадке.Я заменил мой сгенерированный
NSDateв модели основных данных сDateи они все еще работают.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())! } }
еще один способ получить результат:
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];
С
iOS 8.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+в фундаменте есть встроенная функция, которую вы можете использовать из коробки. Нет необходимости реализовывать собственные функции.
public func startOfDay(for date: Date) -> Dateтак что вы можете использовать его таким образом:
let midnightDate = Calendar(identifier: .gregorian).startOfDay(for: Date())стоит помнить, что при этом учитывается часовой пояс устройства. Вы можете установить
.timeZoneoncalendarесли вы хотите иметь, например, зону UTC.ссылка на справочные страницы Apple: https://developer.apple.com/reference/foundation/nscalendar/1417161-startofday.
просто другой способ использования
dateInterval(of:start:interval:for:)ofCalendarо возврате
startDateсодержит начало дня иintervalколичество секунд в день.func startAndEnd(of date : Date) -> (start : Date, end : Date) { var startDate = Date() var interval : TimeInterval = 0.0 Calendar.current.dateInterval(of: .day, start: &startDate, interval: &interval, for: date) var endDate = startDate.addingTimeInterval(interval-1) return (start : startDate, end : endDate) } let (start, end) = startAndEnd(of: Date()) print(start, end)
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)! } }
С
NSCalendar * calendar = [NSCalendar currentCalendar]; NSDate * startDate = [calendar startOfDayForDate:[NSDate date]]; NSLog(@"start date is %@", startDate);
Comments