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))
Documentación NSCalendar de Apple iOS . (Ver la Sección: Cálculos Calendricos )
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)!
}
}