¿Cómo agrego 1 día a un NSDate?


320

Básicamente, como dice el título. Me pregunto cómo podría agregar 1 día a un NSDate.

Entonces si fuera:

21st February 2011

Se convertiría en:

22nd February 2011

O si fuera:

31st December 2011

Se convertiría en:

1st January 2012.

44
Tenga en cuenta que un NSDate no representa una fecha, representa un punto en el tiempo. Por lo tanto, incluye una hora y una fecha.
Rog

44
De acuerdo: debería usar la respuesta de Zack German a continuación. Consulte la Guía de programación de fecha y hora de Apple .
Ash Furrow

¡Desplácese hacia abajo para encontrar soluciones más nuevas (y más cortas)!
Catanore

Respuestas:


711

Swift 5.0:

var dayComponent    = DateComponents()
dayComponent.day    = 1 // For removing one day (yesterday): -1
let theCalendar     = Calendar.current
let nextDate        = theCalendar.date(byAdding: dayComponent, to: Date())
print("nextDate : \(nextDate)")

C objetivo :

NSDateComponents *dayComponent = [[NSDateComponents alloc] init];
dayComponent.day = 1;

NSCalendar *theCalendar = [NSCalendar currentCalendar];
NSDate *nextDate = [theCalendar dateByAddingComponents:dayComponent toDate:[NSDate date] options:0];

NSLog(@"nextDate: %@ ...", nextDate);

Esto debería explicarse por sí mismo.


19
También puede usar componentes negativos para restar de una fecha.
DataGraham

58
Solución mucho mejor que la respuesta seleccionada
Justin Meiners

19
+1 por usar componentes de fecha en lugar de agregar el valor de un día de segundos.
Abizern

Sí funciona bien para el horario de verano. Consejo para la comprobación de DST: restablezca la fecha y la hora en su Mac y luego reinicie su simulador, luego seguirá la hora de su sistema.
Rob van den Berg

2
En Swift necesita cambiar el último parámetro de la dateByAddingComponents llamada aNSCalendarOptions(rawValue: 0)
gfpacheco

270

Desde iOS 8 puedes usar NSCalendar.dateByAddingUnit

Ejemplo en Swift 1.x:

let today = NSDate()
let tomorrow = NSCalendar.currentCalendar()
    .dateByAddingUnit(
         .CalendarUnitDay, 
         value: 1, 
         toDate: today, 
         options: NSCalendarOptions(0)
    )

Swift 2.0:

let today = NSDate()
let tomorrow = NSCalendar.currentCalendar()
    .dateByAddingUnit(
        .Day, 
        value: 1, 
        toDate: today, 
        options: []
    )

Swift 3.0:

let today = Date()
let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: today)

55
¿Soy solo yo, o no sería mucho más simple para Swift tener algo incorporado date.add(.days, 1)? * va y construye una extensión
1919

2
@quemeful extension Date { func adding(_ component: Calendar.Component, _ value: Int) -> Date? { return Calendar.current.date(byAdding: component, value: value, to: self) } }useDate().adding(.day, 1) // "Jun 6, 2019 at 5:35 PM"
Leo Dabus

82

Actualizado para Swift 5

let today = Date()
let nextDate = Calendar.current.date(byAdding: .day, value: 1, to: today)

C objetivo

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
 // now build a NSDate object for the next day
 NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
 [offsetComponents setDay:1];
 NSDate *nextDate = [gregorian dateByAddingComponents:offsetComponents toDate: [NSDate date] options:0];

34

iOS 8+, OSX 10.9+, Objective-C

NSCalendar *cal = [NSCalendar currentCalendar];    
NSDate *tomorrow = [cal dateByAddingUnit:NSCalendarUnitDay 
                                   value:1 
                                  toDate:[NSDate date] 
                                 options:0];

Tenga en cuenta que no puede enmascarar la unidad aquí (use solo una).
Catanore

31

Una implementación funcional de Swift 3+ basada en la respuesta de alto mantenimiento y el comentario de vikingosegundo . Esta extensión de fecha también tiene opciones adicionales para cambiar año, mes y hora:

extension Date {

    /// Returns a Date with the specified amount of components added to the one it is called with
    func add(years: Int = 0, months: Int = 0, days: Int = 0, hours: Int = 0, minutes: Int = 0, seconds: Int = 0) -> Date? {
        let components = DateComponents(year: years, month: months, day: days, hour: hours, minute: minutes, second: seconds)
        return Calendar.current.date(byAdding: components, to: self)
    }

    /// Returns a Date with the specified amount of components subtracted from the one it is called with
    func subtract(years: Int = 0, months: Int = 0, days: Int = 0, hours: Int = 0, minutes: Int = 0, seconds: Int = 0) -> Date? {
        return add(years: -years, months: -months, days: -days, hours: -hours, minutes: -minutes, seconds: -seconds)
    }

}

El uso para agregar solo un día según lo solicitado por OP sería:

let today = Date() // date is then today for this example
let tomorrow = today.add(days: 1)

2
Puede acortar el código de forma masiva utilizando componentes de fecha.
vikingosegundo

Tienes razón, aunque tiene inconvenientes en mi opinión: el código que usa la extensión no parece tan limpio, abre algunas opciones innecesarias con componentes que tienen poco sentido como let foo = Date().add([.calendar: 1, .yearForWeekOfYear: 3] si estuviera agregando la solución alternativa a mi respuesta . Gracias por su sugerencia, @vikingosegundo!
Benno Kress

3
bueno, en realidad quise decir algo diferente: gist.github.com/vikingosegundo/31ddb14920415ef444a9ab550411d4ff
vikingosegundo


13

Use la siguiente función y use el parámetro de días para obtener la fecha daysAhead / daysBehind simplemente pase el parámetro como positivo para una fecha futura o negativo para fechas anteriores:

+ (NSDate *) getDate:(NSDate *)fromDate daysAhead:(NSUInteger)days
{
    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    dateComponents.day = days;
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDate *previousDate = [calendar dateByAddingComponents:dateComponents
                                                     toDate:fromDate
                                                    options:0];
    [dateComponents release];
    return previousDate;
}

10

En rápido

var dayComponenet = NSDateComponents()
dayComponenet.day = 1

var theCalendar = NSCalendar.currentCalendar()
var nextDate = theCalendar.dateByAddingComponents(dayComponenet, toDate: NSDate(), options: nil)

8

¡Es trabajo!

    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSCalendarUnit unit = NSCalendarUnitDay;
    NSInteger value = 1;
    NSDate *today = [NSDate date];
    NSDate *tomorrow = [calendar dateByAddingUnit:unit value:value toDate:today options:NSCalendarMatchStrictly];

Bueno, aparentemente esta pregunta es el código de descarga del cielo. Así que no hay razón para destacarte.
Dibujó

2
mi respuesta es más correcta porque si usa la opción NSCalendarWrapComponents (0) puede crear la fecha solo en el rango del mes actual. Significa que si agrega 1 día con NSCalendarWrapComponents al 31 de enero de 2016 obtendrá el 1 de enero de 2016. Con la opción NSCalendarMatchStrictly obtendrá la próxima fecha del calendario.
DenZhukov

8

La implementación muy simple de Swift 3.0 sería:

func dateByAddingDays(inDays: Int) -> Date {
    let today = Date()
    return Calendar.current.date(byAdding: .day, value: inDays, to: today)!
}

5
NSDate *today=[NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *components=[[NSDateComponents alloc] init];
components.day=1;
NSDate *targetDate =[calendar dateByAddingComponents:components toDate:today options: 0];

5

Swift 4.0

extension Date {
    func add(_ unit: Calendar.Component, value: Int) -> Date? {
        return Calendar.current.date(byAdding: unit, value: value, to: self)
    }
}

Uso

date.add(.day, 3)!   // adds 3 days
date.add(.day, -14)!   // subtracts 14 days

Nota: Si no sabe por qué las líneas de código terminan con un signo de exclamación, busque "Swift Optionals" en Google.


3

Puede usar el método de NSDate - (id)dateByAddingTimeInterval:(NSTimeInterval)secondsdonde secondsestaría60 * 60 * 24 = 86400


3
AddByTimeInterval de NSDate fue desaprobado en iOS 4 ( bit.ly/vtOzvU ). Utilice dateByAddingTimeInterval ( bit.ly/vRkFrN ) en su lugar.
billmaya

44
los días pueden tener 23, 24 o 25 horas, debido al horario de verano.
vikingosegundo

3

En Swift 2.1.1 y xcode 7.1 OSX 10.10.5, puede agregar cualquier número de días hacia adelante y hacia atrás utilizando la función

func addDaystoGivenDate(baseDate:NSDate,NumberOfDaysToAdd:Int)->NSDate
{
    let dateComponents = NSDateComponents()
    let CurrentCalendar = NSCalendar.currentCalendar()
    let CalendarOption = NSCalendarOptions()

    dateComponents.day = NumberOfDaysToAdd

    let newDate = CurrentCalendar.dateByAddingComponents(dateComponents, toDate: baseDate, options: CalendarOption)
    return newDate!
}

llamada a la función para incrementar la fecha actual en 9 días

var newDate = addDaystoGivenDate(NSDate(), NumberOfDaysToAdd: 9)
print(newDate)

llamada a la función para disminuir la fecha actual en 80 días

newDate = addDaystoGivenDate(NSDate(), NumberOfDaysToAdd: -80)
 print(newDate)

3

Aquí hay un método de propósito general que le permite sumar / restar cualquier tipo de unidad (Año / Mes / Día / Hora / Segundo, etc.) en la fecha especificada.

Usando Swift 2.2

func addUnitToDate(unitType: NSCalendarUnit, number: Int, date:NSDate) -> NSDate {

    return NSCalendar.currentCalendar().dateByAddingUnit(
        unitType,
        value: number,
        toDate: date,
        options: NSCalendarOptions(rawValue: 0))!

}

print( addUnitToDate(.Day, number: 1, date: NSDate()) ) // Adds 1 Day To Current Date
print( addUnitToDate(.Hour, number: 1, date: NSDate()) ) // Adds 1 Hour To Current Date
print( addUnitToDate(.Minute, number: 1, date: NSDate()) ) // Adds 1 Minute To Current Date

// NOTE: You can use negative values to get backward values too

3
NSDateComponents *dayComponent = [[[NSDateComponents alloc] init] autorelease];
dayComponent.day = 1;

NSCalendar *theCalendar = [NSCalendar currentCalendar];
dateToBeIncremented = [theCalendar dateByAddingComponents:dayComponent toDate:dateToBeIncremented options:0];

Ok, pensé que esto iba a funcionar para mí. Sin embargo, si lo usa para agregar un día al 31 de marzo de 2013, devolverá una fecha que solo tiene 23 horas agregadas. Es muy posible que tenga 24, pero usarlo en los cálculos tiene solo 23:00 horas agregadas.

Del mismo modo, si avanzas hasta el 28 de octubre de 2013, el código agrega 25 horas, lo que da como resultado una fecha y hora de 2013-10-28 01:00:00.

Para agregar un día, estaba haciendo lo que estaba arriba, agregando:

NSDate *newDate1 = [now dateByAddingTimeInterval:60*60*24*daysToAdd];

Complicado, principalmente debido al horario de verano.


una vez al año al día tiene solo 23 horas. una vez 25. y cada pocos años tiene la duración 60*60*24 + 1de los segundos bisiestos. las fechas deben cubrir todo esto, y es por eso que el manejo de la fecha del cacao es realmente genial
vikingosegundo

2
NSDate *now = [NSDate date];
int daysToAdd = 1;
NSDate *tomorrowDate = [now dateByAddingTimeInterval:60*60*24*daysToAdd];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"EEEE, dd MMM yyyy"];
NSLog(@"%@", [dateFormatter stringFromDate:tomorrowDate]);

2

En Swift puede hacer una extensión para agregar el método en NSDate

extension NSDate {
    func addNoOfDays(noOfDays:Int) -> NSDate! {
        let cal:NSCalendar = NSCalendar.currentCalendar()
        cal.timeZone = NSTimeZone(abbreviation: "UTC")!
        let comps:NSDateComponents = NSDateComponents()
        comps.day = noOfDays
        return cal.dateByAddingComponents(comps, toDate: self, options: nil)
    }
}

puedes usar esto como

NSDate().addNoOfDays(3)

2

Actualización para Swift 4:

let now = Date() // the current date/time
let oneDayFromNow = Calendar.current.date(byAdding: .day, value: 1, to: now) // Tomorrow with same time of day as now

1

para swift 2.2:

let today = NSDate()
let tomorrow = NSCalendar.currentCalendar().dateByAddingUnit(
        .Day,
        value: 1,
        toDate: today,
        options: NSCalendarOptions.MatchStrictly)

¡Espero que esto ayude a alguien!


1

Swift 4, si todo lo que realmente necesita es un turno de 24 horas (60 * 60 * 24 segundos) y no "1 día calendario"

Futuro: let dayAhead = Date(timeIntervalSinceNow: TimeInterval(86400.0))

Pasado: let dayAgo = Date(timeIntervalSinceNow: TimeInterval(-86400.0))


1

actualización para swift 5

let nextDate = fromDate.addingTimeInterval(60*60*24)

0
NSDate *now = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:now];
NSDate *startDate = [calendar dateFromComponents:components];
NSLog(@"StartDate = %@", startDate);

components.day += 1;
NSDate *endDate = [calendar dateFromComponents:components];
NSLog(@"EndDate = %@", endDate);

0

Yo tuve el mismo problema; use una extensión para NSDate:

- (id)dateByAddingYears:(NSUInteger)years
                 months:(NSUInteger)months
                   days:(NSUInteger)days
                  hours:(NSUInteger)hours
                minutes:(NSUInteger)minutes
                seconds:(NSUInteger)seconds
{
    NSDateComponents * delta = [[[NSDateComponents alloc] init] autorelease];
    NSCalendar * gregorian = [[[NSCalendar alloc]
                               initWithCalendarIdentifier:NSCalendarIdentifierGregorian] autorelease];

    [delta setYear:years];
    [delta setMonth:months];
    [delta setDay:days];
    [delta setHour:hours];
    [delta setMinute:minutes];
    [delta setSecond:seconds];

    return [gregorian dateByAddingComponents:delta toDate:self options:0];
}

0

Swift 2.0

let today = NSDate()    
let calendar = NSCalendar.currentCalendar()
let tomorrow = calendar.dateByAddingUnit(.Day, value: 1, toDate: today, options: NSCalendarOptions.MatchFirst)

0

En swift 4 o swift 5, puede usar como abajo:

    let date = Date()
    let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: date)
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd"
    let yesterday_date = dateFormatter.string(from: yesterday!)
    print("yesterday->",yesterday_date)

salida:

Current date: 2020-03-02
yesterday date: 2020-03-01

0

Extensión de cadena: Convertir String_Date> Fecha

extension String{
  func DateConvert(oldFormat:String)->Date{ // format example: yyyy-MM-dd HH:mm:ss 
    let isoDate = self
    let dateFormatter = DateFormatter()
    dateFormatter.locale = Locale(identifier: "en_US_POSIX") // set locale to reliable US_POSIX
    dateFormatter.dateFormat = oldFormat
    return dateFormatter.date(from:isoDate)!
  }
}

Extensión de fecha: Convertir fecha> Cadena

extension Date{
 func DateConvert(_ newFormat:String)-> String{
    let formatter = DateFormatter()
    formatter.dateFormat = newFormat
    return formatter.string(from: self)
 }
}

Extensión de fecha: Obtener +/- Fecha

extension String{
  func next(day:Int)->Date{
    var dayComponent    = DateComponents()
    dayComponent.day    = day
    let theCalendar     = Calendar.current
    let nextDate        = theCalendar.date(byAdding: dayComponent, to: Date())
    return nextDate!
  }

 func past(day:Int)->Date{
    var pastCount = day
    if(pastCount>0){
        pastCount = day * -1
    }
    var dayComponent    = DateComponents()
    dayComponent.day    = pastCount
    let theCalendar     = Calendar.current
    let nextDate        = theCalendar.date(byAdding: dayComponent, to: Date())
    return nextDate!
 }
}

Uso:

let today = Date()
let todayString = "2020-02-02 23:00:00"
let newDate = today.DateConvert("yyyy-MM-dd HH:mm:ss") //2020-02-02 23:00:00
let newToday = todayString.DateConvert(oldFormat: "yyyy-MM-dd HH:mm:ss")//2020-02-02
let newDatePlus = today.next(day: 1)//2020-02-03 23:00:00
let newDateMinus = today.past(day: 1)//2020-02-01 23:00:00

referencia: de múltiples preguntas
¿Cómo agrego 1 día a un NSDate?
¿Función matemática para convertir positivo int a negativo y negativo a positivo?
Convertir NSString a NSDate (y viceversa)


-1

Use el siguiente código:

NSDate *now = [NSDate date];
int daysToAdd = 1;
NSDate *newDate1 = [now dateByAddingTimeInterval:60*60*24*daysToAdd];

Como

addTimeInterval

ahora está en desuso.


3
los días pueden tener 23, 24 o 25 horas, debido al horario de verano
vikingosegundo
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.