Como adiciono 1 dia a um NSDate?

320

Basicamente, como o título diz. Eu estou querendo saber como eu poderia adicionar 1 dia para um NSDate.

Então, se fosse:

21st February 2011

Seria:

22nd February 2011

Ou se fosse:

31st December 2011

Seria:

1st January 2012.
Andrew
fonte
4
Observe que um NSDate não representa uma data, ele representa um ponto no tempo. Portanto, inclui um horário e uma data.
Rog
4
Concordo - você deve usar a resposta de Zack German abaixo. Consulte o Guia de programação de data e hora da Apple .
Ash Furrow
Role para baixo para obter soluções mais novas (e mais curtas)!
precisa saber é

Respostas:

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

Objetivo C:

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

Isso deve ser auto-explicativo.

Zaky German
fonte
19
Você também pode usar componentes negativos para subtrair de uma data.
DataGraham
58
Solução melhor tanto do que a resposta escolhida
Justin Meiners
19
+1 por usar os componentes Data em vez de adicionar o valor de um dia em segundos.
Abizern
Sim funciona bem para o horário de verão. Dica para a verificação do horário de verão: redefina a data e a hora no seu mac e, em seguida, reinicie o simulador, seguindo a hora do sistema.
Rob van den Berg
2
Em Swift você precisa mudar o último parâmetro da dateByAddingComponents chamada paraNSCalendarOptions(rawValue: 0)
gfpacheco
270

Desde o iOS 8, você pode usar NSCalendar.dateByAddingUnit

Exemplo no 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
fonte
5
Sou apenas eu, ou não seria muito mais simples para Swift ter algo assim date.add(.days, 1)? * vai e cria uma extensão
quemeful 15/03/19
2
@quemeful extension Date { func adding(_ component: Calendar.Component, _ value: Int) -> Date? { return Calendar.current.date(byAdding: component, value: value, to: self) } }usoDate().adding(.day, 1) // "Jun 6, 2019 at 5:35 PM"
Leo Dabus
82

Atualizado para o Swift 5

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

Objetivo C

 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
fonte
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
fonte
Observe que você não pode mascarar a unidade aqui (use apenas uma).
precisa saber é
31

Uma implementação do Swift 3+ em funcionamento, com base na resposta da alta manutenção e no comentário do vikingosegundo . Essa extensão de data também possui opções adicionais para alterar ano, mês e 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)
    }

}

O uso para adicionar apenas um dia, conforme solicitado pelo OP, seria:

let today = Date() // date is then today for this example
let tomorrow = today.add(days: 1)
Benno Kress
fonte
2
Você pode encurtar o código massivamente usando componentes de data.
vikingosegundo
Você está certo, embora tenha desvantagens na minha opinião: - o código que usa a extensão não parece tão limpo - ele abre algumas opções desnecessárias com componentes que fazem pouco sentido, como se let foo = Date().add([.calendar: 1, .yearForWeekOfYear: 3] eu estivesse adicionando a solução alternativa à minha resposta . Obrigado pela sua sugestão, @vikingosegundo!
Benno Kress
3
bem, eu realmente quis dizer algo diferente: gist.github.com/vikingosegundo/31ddb14920415ef444a9ab550411d4ff
vikingosegundo
22

Swift 4.0 (o mesmo que o Swift 3.0 nesta resposta maravilhosa, deixando claro para novatos como eu)

let today = Date()
let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: today)
Joshua Dance
fonte
3
Você esqueceu de mudar o nome da variável?
Rakesha Shastri
13

Use a função abaixo e use days paramater para obter a data daysAhead / daysBehind apenas passe o parâmetro como positivo para data futura ou negativo para datas 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
fonte
10

Em rápido

var dayComponenet = NSDateComponents()
dayComponenet.day = 1

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

Isso funciona!

    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
fonte
Bem, aparentemente, esta pergunta é o paraíso de despejo de código. Portanto, não há razão para destacar você.
Drew
2
minha resposta está mais correta porque se você usar a opção NSCalendarWrapComponents (0), poderá criar a data apenas no intervalo do mês atual. Isso significa que se você adicionar 1 dia com NSCalendarWrapComponents a 31 de janeiro de 2016, receberá 1 de janeiro de 2016. Com a opção NSCalendarMatchStrictly, você receberá a próxima data do calendário.
DenZhukov 26/02
8

A implementação muito simples do Swift 3.0 seria:

func dateByAddingDays(inDays: Int) -> Date {
    let today = Date()
    return Calendar.current.date(byAdding: .day, value: inDays, to: today)!
}
AmJa
fonte
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
fonte
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: Se você não sabe por que as linhas de código terminam com um ponto de exclamação, procure "Swift Optionals" no Google.

quemeful
fonte
3

Você pode usar o método do NSDate - (id)dateByAddingTimeInterval:(NSTimeInterval)secondsonde secondsseria60 * 60 * 24 = 86400

Tiago
fonte
3
O addByTimeInterval do NSDate foi descontinuado no iOS 4 ( bit.ly/vtOzvU ). Use dateByAddingTimeInterval ( bit.ly/vRkFrN ).
billmaya
4
os dias podem ter 23, 24 ou 25 horas, devido ao horário de verão.
Vikingosegundo
3

No Swift 2.1.1 e no xcode 7.1 OSX 10.10.5, você pode adicionar qualquer número de dias para frente e para trás usando a função

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

chamada de função para aumentar a data atual em 9 dias

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

chamada de função para diminuir a data atual em 80 dias

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

Aqui está um método de uso geral que permite adicionar / subtrair qualquer tipo de unidade (ano / mês / dia / hora / segundo etc.) na data especificada.

Usando o 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
fonte
3
NSDateComponents *dayComponent = [[[NSDateComponents alloc] init] autorelease];
dayComponent.day = 1;

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

Ok - eu pensei que isso iria funcionar para mim. No entanto, se você usá-lo para adicionar um dia a 31 de março de 2013, ele retornará uma data que possui apenas 23 horas. Pode muito bem ter os 24, mas o uso em cálculos tem apenas 23:00 horas adicionadas.

Da mesma forma, se você avançar para 28 de outubro de 2013, o código adicionará 25 horas, resultando em um horário de 28-10-2013 01:00:00.

Para adicionar um dia, eu estava fazendo a coisa no topo, adicionando o:

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

Complicado, principalmente devido ao horário de verão.

Carl Hine
fonte
uma vez por ano por dia tem apenas 23 horas. uma vez 25. e a cada poucos anos tem a duração de 60*60*24 + 1por causa de segundos bissextos. As datas devem cobrir tudo isso, e é por isso que o manuseio de cacau na data é realmente ótimo!
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]);
Tanwade Shrikant
fonte
2

No Swift você pode fazer a extensão para adicionar método no 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)
    }
}

você pode usar isso como

NSDate().addNoOfDays(3)
Muhammad Aamir Ali
fonte
2

Atualização para o 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
fonte
1

para o swift 2.2:

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

Espero que isso ajude alguém!

Paul Lehn
fonte
1

Swift 4, se tudo o que você realmente precisa é de um turno de 24 horas (60 * 60 * 24 segundos) e não "1 dia de calendário"

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

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

John Robi
fonte
1

atualização para o swift 5

let nextDate = fromDate.addingTimeInterval(60*60*24)
Manish
fonte
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
fonte
0

Eu tive o mesmo problema; use uma extensão para o 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
fonte
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
fonte
0

No swift 4 ou swift 5, você pode usar como abaixo:

    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)

resultado:

Current date: 2020-03-02
yesterday date: 2020-03-01
Enamul Haque
fonte
0

Extensão de string: Converter String_Date> Data

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

Extensão de data: Converter Data> String

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

Extensão de data: obter +/- data

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

referência: de várias perguntas
Como adiciono 1 dia a um NSDate?
função matemática para converter positivo int em negativo e negativo em positivo?
Convertendo NSString em NSDate (e vice-versa)

Muhammad Asyraf
fonte
-1

Use o seguinte código:

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

Como

addTimeInterval

agora está obsoleto.

Hemang
fonte
3
dias pode ter 23, 24 ou 25 horas, por causa do horário de verão vezes
vikingosegundo