¿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.
Andrés
fuente
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.

Zaky German
fuente
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)
Ben Sinclair
fuente
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];
iHS
fuente
34

iOS 8+, OSX 10.9+, Objective-C

NSCalendar *cal = [NSCalendar currentCalendar];    
NSDate *tomorrow = [cal dateByAddingUnit:NSCalendarUnitDay 
                                   value:1 
                                  toDate:[NSDate date] 
                                 options:0];
vikingosegundo
fuente
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)
Benno Kress
fuente
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
22

Swift 4.0 (igual que Swift 3.0 en esta maravillosa respuesta, solo dejándolo claro para los novatos como yo)

let today = Date()
let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: today)
Joshua Dance
fuente
3
¿Olvidó cambiar el nombre de su variable?
Rakesha Shastri
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;
}
Bhupendra
fuente
10

En rápido

var dayComponenet = NSDateComponents()
dayComponenet.day = 1

var theCalendar = NSCalendar.currentCalendar()
var nextDate = theCalendar.dateByAddingComponents(dayComponenet, toDate: NSDate(), options: nil)
Steve Ng
fuente
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];
DenZhukov
fuente
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)!
}
AmJa
fuente
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];
Rahul Gupta
fuente
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.

malicioso
fuente
3

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

Tiago
fuente
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)
Dharmesh
fuente
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
n.by.n
fuente
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.

Carl Hine
fuente
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]);
Shrikant Tanwade
fuente
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)
Muhammad Aamir Ali
fuente
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
Ryan
fuente
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!

Paul Lehn
fuente
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))

John Robi
fuente
1

actualización para swift 5

let nextDate = fromDate.addingTimeInterval(60*60*24)
Manish
fuente
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);
Vũ Ngọc Giang
fuente
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];
}
slashlos
fuente
0

Swift 2.0

let today = NSDate()    
let calendar = NSCalendar.currentCalendar()
let tomorrow = calendar.dateByAddingUnit(.Day, value: 1, toDate: today, options: NSCalendarOptions.MatchFirst)
Sébastien REMY
fuente
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
Enamul Haque
fuente
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)

Muhammad Asyraf
fuente
-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.

Hemang
fuente
3
los días pueden tener 23, 24 o 25 horas, debido al horario de verano
vikingosegundo