Restar 7 días de la fecha actual

118

Parece que no puedo restar 7 días de la fecha actual. Así es como lo estoy haciendo:

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 obtiene el mismo valor que la fecha actual.

Por favor ayuda.

EDITAR: En mi código olvidé reemplazar la variable que obtiene la fecha actual con la correcta. Entonces, el código anterior es funcional.

Alex Tau
fuente
3
[NSDate dateWithTimeIntervalSinceReferenceDate:[NSDate date].timeIntervalSinceReferenceDate - (7*24*60*60)]- Aunque no maneja los cambios de horario de verano.
Hot Licks
Eso debería funcionar. ¿Funciona si suma 1 en lugar de restar 7? ¿Cómo determina que se refiere a sevenDaysAgo hoy?
JeremyP

Respuestas:

112

use el método dateByAddingTimeInterval:

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

salida:

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

Espero eso ayude

Novarg
fuente
45
Hay casos extremos en los que esto no funcionará correctamente, por ejemplo, si el horario de verano cambia durante los siete días en cuestión.
JeremyP
1
La respuesta de dymv es la forma más segura de hacer esto.
w3bshark
2
Esta es la respuesta incorrecta por las razones antes mencionadas, use la respuesta de dymv
BarrettJ
1
En realidad, esto se puede hacer simplemente por:[now dateByAddingDays:-7]
CrashOverride
Hacer este tipo de cálculo es peligroso, prefiero la versión de @ Dov.
ctietze
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];

salida:

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

Y estoy totalmente de acuerdo con JeremyP.

BR.
Eugenio

dymv
fuente
2
Sin embargo, hay una pérdida de memoria en esta respuesta.
Atuljangra
132

Si está ejecutando al menos iOS 8 u OS X 10.9, hay una forma aún más limpia:

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

O, con Swift 2:

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

Y con Swift 3 en adelante, se vuelve aún más compacto:

let sevenDaysAgo = Calendar.current.date(byAdding: .day, value: -7, to: Date())
Dov
fuente
3
Esta debería ser la respuesta aceptada, ya que maneja todos los casos extremos por usted.
Zhivko Bogdanov
@ZhivkoBogdanov Mi respuesta llegó unos años después de la respuesta aceptada, y no creo que puedas cambiar tu respuesta aceptada después del hecho.
Dov
Es más para referencia futura que cualquier otra cosa.
Zhivko Bogdanov
56

Swift 3

Calendar.current.date(byAdding: .day, value: -7, to: Date())
Marckaraujo
fuente
3
No use NSCalendar, use Calendar en su lugar :)
Jonas
8

Swift 4.2 - Mutar (actualizar) uno mismo

Aquí hay otra forma en que el póster original puede obtener hace una semana si ya tiene una variable de fecha (se actualiza / muta).

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

o

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

La respuesta de dymv funciona muy bien. Esto lo puedes usar en rápido

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

Puedes llamar a esto con

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

Espero que ayude y gracias a dymv

Babac
fuente
4

Swift 4.2 iOS 11.x Solución de 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)!
  }
}
usuario3069232
fuente
4

Extensión de 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
fuente
3

Versión Swift 3.0+ de la respuesta aceptada original

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

Sin embargo, esto usa solo valores absolutos. Usar respuestas de calendario probablemente sea más adecuado en la mayoría de los casos.

mito original
fuente
-2

Swift 3:

Una modificación a la respuesta 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
fuente
1
¿Por qué es numberOfDaysopcional y luego se desenvuelve a la fuerza? ¿No debería ser simplemente no opcional Int?
Dov
Es la forma correcta de contener valor opcional en función rápida.
AG
1
Pero, ¿por qué numberOfDays es opcional? ¿Hay algún momento en el que alguien llame a este método de extensión y no dé una cantidad de días para agregar o eliminar?
Dov
-3

PARA SWIFT 3.0

aquí está la función, puede reducir días, mes, día en cualquier recuento como, por ejemplo, aquí, he reducido el año de la fecha actual del sistema en 100 años, puede hacerlo por día, mes también simplemente configure el contador y guárdelo en un matriz, puede esta matriz en cualquier lugar luego 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
fuente