ios nsdate nsdatecomponents

ios - NSDate principio del día y fin del día



nsdatecomponents (16)

Comienzo del día / fin del día

// 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()) } }

Descompostura

// 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 *)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]; }

Cuando llamo: [self endOfDay: [NSDate date]]; Me llevo el primero del mes ... ¿Por qué es eso? Utilizo estos dos métodos porque necesito un intervalo que sea desde el primer segundo de la primera fecha (beginOfDay: date1) hasta el último segundo de la segunda fecha (endOfDay: Date2) ...


Desde iOS 8.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+ existe una función incorporada en la Fundación, que puede usar de manera inmediata. No es necesario implementar funciones propias.

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

Entonces puedes usarlo de esta manera:

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

Vale la pena recordar que esto toma en consideración la zona horaria del dispositivo. Puede configurar .timeZone en el calendar si desea tener, por ejemplo, la zona UTC.

Enlace a las páginas de referencia de Apple: https://developer.apple.com/reference/foundation/nscalendar/1417161-startofday .


En iOS 8+ esto es realmente conveniente; tu puedes hacer:

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

Para obtener el final del día, simplemente use los métodos de NSCalendar durante 23 horas, 59 minutos, 59 segundos, dependiendo de cómo defina el final del día.

// 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))

Fecha matemática

Documentación NSCalendar de Apple iOS . (Ver la Sección: Cálculos Calendricos )

Métodos NSCalendar discutidos por NSHipster .


Mis extensiones Swift para 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 } }


No tiene que configurar los componentes a cero, simplemente ignórelos:

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


Otra forma de usar rangeOfUnit:startDate:interval:options: de 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: [])


Para mí, ninguna de las respuestas aquí y en otras partes de funcionó. Para comenzar hoy, hice esto.

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

Tenga en cuenta esto [gregorian setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; y [components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; .

Cuando se crea un calendario, se inicializa con la zona horaria actual y cuando se extrae la fecha de sus componentes, dado que NSDate no tiene zona horaria, la fecha de la zona horaria actual se considera zona horaria UTC. Entonces, debemos establecer la zona horaria antes de extraer los componentes y más adelante al extraer la fecha de estos componentes.


Te estás perdiendo NSDayCalendarUnit en

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


Te falta NSDayCalendarUnit en los componentes.


Una forma más de obtener el resultado:

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


C objetivo

NSCalendar * calendar = [NSCalendar currentCalendar]; NSDate * startDate = [calendar startOfDayForDate:[NSDate date]]; NSLog(@"start date is %@", startDate);


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


Swift 4 - XCode 9 con clase Date lugar de NSDate y Calender lugar de NSCalender

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

Uso:

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


Swift 4 Respuesta simple y más precisa de 00:00:00 a 23: 59: 59.5 en la zona local

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)


Swift3 Usando * XCode8
Apple está eliminando el NS del nombre de clase para que NSDate se pueda intercambiar hasta la Date . Puede obtener una advertencia de compilador si intenta lanzarlos diciendo que siempre fallarán, pero funcionan bien cuando los ejecuta en el patio de recreo.

NSDate mi NSDate generado en el modelo de datos básicos con Date y todavía funcionan.

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


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