Subtraia 7 dias da data atual

117

Parece que não consigo subtrair 7 dias da data atual. É assim que estou fazendo:

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
[offsetComponents setDay:-7];
NSDate *sevenDaysAgo = [gregorian dateByAddingComponents:offsetComponents toDate:[NSDate date] options:0];

SevenDaysAgo obtém o mesmo valor da data atual.

Por favor ajude.

EDIT: No meu código esqueci de substituir a variável que obtém a data atual com a correta. Portanto, o código acima é funcional.

Alex Tau
fonte
3
[NSDate dateWithTimeIntervalSinceReferenceDate:[NSDate date].timeIntervalSinceReferenceDate - (7*24*60*60)]- Embora não lide com alterações de horário de verão.
Hot Licks de
Isso deve funcionar. Funciona se você adicionar 1 em vez de subtrair 7? Como você determina que sevenDaysAgo se refere a hoje?
JeremyP

Respostas:

112

use o método dateByAddingTimeInterval:

NSDate *now = [NSDate date];
NSDate *sevenDaysAgo = [now dateByAddingTimeInterval:-7*24*60*60];
NSLog(@"7 days ago: %@", sevenDaysAgo);

resultado:

7 days ago: 2012-04-11 11:35:38 +0000

Espero que ajude

Novarg
fonte
45
Existem casos extremos em que isso não funcionará corretamente, por exemplo, se o horário de verão mudar durante os sete dias em questão.
JeremyP
1
A resposta de dymv é a maneira mais segura de fazer isso.
w3bshark de
2
Esta é a resposta errada pelas razões mencionadas, use a resposta de
dymv
1
Na verdade, isso pode ser feito simplesmente por:[now dateByAddingDays:-7]
CrashOverride
Fazer esse tipo de cálculo é perigoso, prefira a versão de @Dov.
ctietze 01 de
196

código:

NSDate *currentDate = [NSDate date];
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setDay:-7];
NSDate *sevenDaysAgo = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:currentDate options:0];
NSLog(@"\ncurrentDate: %@\nseven days ago: %@", currentDate, sevenDaysAgo);
[dateComponents release];

resultado:

currentDate: 2012-04-22 12:53:45 +0000
seven days ago: 2012-04-15 12:53:45 +0000

E estou totalmente de acordo com JeremyP.

BR.
Eugene

dymv
fonte
2
No entanto, há um vazamento de memória nesta resposta.
atuljangra
132

Se você estiver executando pelo menos iOS 8 ou OS X 10.9, há uma maneira ainda mais limpa:

NSDate *sevenDaysAgo = [[NSCalendar currentCalendar] dateByAddingUnit:NSCalendarUnitDay
                                                                value:-7
                                                               toDate:[NSDate date]
                                                              options:0];

Ou, com Swift 2:

let sevenDaysAgo = NSCalendar.currentCalendar().dateByAddingUnit(.Day, value: -7,
    toDate: NSDate(), options: NSCalendarOptions(rawValue: 0))

E com o Swift 3 e superior, ele fica ainda mais compacto:

let sevenDaysAgo = Calendar.current.date(byAdding: .day, value: -7, to: Date())
Dov
fonte
3
Essa deve ser a resposta aceita, pois trata de todos os casos extremos para você.
Zhivko Bogdanov
@ZhivkoBogdanov Minha resposta veio alguns anos depois da resposta aceita, e não acredito que você possa mudar sua resposta aceita depois do fato.
Dov
É mais para referência futura do que qualquer outra coisa.
Zhivko Bogdanov
56

Swift 3

Calendar.current.date(byAdding: .day, value: -7, to: Date())
Marckaraujo
fonte
3
Não use NSCalendar, use Calendário em vez :)
Jonas
8

Swift 4.2 - Mutate (Atualizar) Self

Esta é outra maneira que o postador original pode obter uma semana atrás, se ele já tiver uma variável de data (se atualiza / muda).

extension Date {
    mutating func changeDays(by days: Int) {
        self = Calendar.current.date(byAdding: .day, value: days, to: self)!
    }
}

Uso

var myDate = Date()       // Jan 08, 2019
myDate.changeDays(by: 7)  // Jan 15, 2019
myDate.changeDays(by: 7)  // Jan 22, 2019
myDate.changeDays(by: -1) // Jan 21, 2019

ou

// Iterate through one week
for i in 1...7 {
    myDate.changeDays(by: i)
    // Do something
}
Mark Moeykens
fonte
4

A resposta de dymv funciona muito bem. Isso você pode usar rapidamente

extension NSDate {    
    static func changeDaysBy(days : Int) -> NSDate {
        let currentDate = NSDate()
        let dateComponents = NSDateComponents()
        dateComponents.day = days
        return NSCalendar.currentCalendar().dateByAddingComponents(dateComponents, toDate: currentDate, options: NSCalendarOptions(rawValue: 0))!
    }
}

Você pode ligar para isso com

NSDate.changeDaysBy(-7) // Date week earlier
NSDate.changeDaysBy(14) // Date in next two weeks

Espero que ajude e obrigado dymv

Babac
fonte
4

Swift 4.2 iOS 11.x Solução da Babec , Swift puro

extension Date {
  static func changeDaysBy(days : Int) -> Date {
    let currentDate = Date()
    var dateComponents = DateComponents()
    dateComponents.day = days
    return Calendar.current.date(byAdding: dateComponents, to: currentDate)!
  }
}
user3069232
fonte
4

Extensão do operador Swift:

extension Date {
    
    static func -(lhs: Date, rhs: Int) -> Date {
        return Calendar.current.date(byAdding: .day, value: -rhs, to: lhs)!
    }
}

Uso

let today = Date()
let yesterday = today - 7
Sam
fonte
3

Versão do Swift 3.0+ da resposta original aceita

Date (). AddTimeInterval (-7 * 24 * 60 * 60)

No entanto, isso usa apenas valores absolutos. Usar respostas de calendário é provavelmente mais adequado na maioria dos casos.

mito original
fonte
-2

Swift 3:

Uma modificação na resposta de Dov.

extension Date {

    func dateBeforeOrAfterFromToday(numberOfDays :Int?) -> Date {

        let resultDate = Calendar.current.date(byAdding: .day, value: numberOfDays!, to: Date())!
        return resultDate
    }
}

Uso:

let dateBefore =  Date().dateBeforeOrAfterFromToday(numberOfDays : -7)
let dateAfter = Date().dateBeforeOrAfterFromToday(numberOfDays : 7)
print ("dateBefore : \(dateBefore), dateAfter :\(dateAfter)")
AG
fonte
1
Por que é numberOfDaysopcional e então desembrulhado à força? Não deveria ser apenas não opcional Int?
Dov
É a maneira correta de conter o valor opcional na função swift.
AG
1
Mas por que numberOfDays é opcional? há algum momento em que alguém chamará esse método de extensão e não dará um número de dias para adicionar ou remover?
Dov
-3

PARA SWIFT 3.0

aqui está a função, você pode reduzir dias, mês, dia por qualquer contagem como por exemplo aqui, eu reduzi o ano da data do sistema atual em 100 anos, você pode fazer isso para dia, mês também basta definir o contador e armazená-lo em um array, você pode usar este array em qualquer lugar, então func currentTime ()

 {

    let date = Date()
    let calendar = Calendar.current
    var year = calendar.component(.year, from: date)
    let month = calendar.component(.month, from: date)
    let  day = calendar.component(.day, from: date)
    let pastyear = year - 100
    var someInts = [Int]()
    printLog(msg: "\(day):\(month):\(year)" )

    for _ in pastyear...year        {
        year -= 1
                     print("\(year) ")
        someInts.append(year)
    }
          print(someInts)
        }
Aditya Panse
fonte