Soustraire 7 jours de la date actuelle

119

Il semble que je ne peux pas soustraire 7 jours de la date actuelle. Voici comment je fais:

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 obtient la même valeur que la date actuelle.

Veuillez aider.

EDIT: Dans mon code, j'ai oublié de remplacer la variable qui obtient la date actuelle par la bonne. Le code ci-dessus est donc fonctionnel.

Alex Tau
la source
3
[NSDate dateWithTimeIntervalSinceReferenceDate:[NSDate date].timeIntervalSinceReferenceDate - (7*24*60*60)]- Bien qu'il ne gère pas les changements d'heure d'été.
Hot Licks
Cela devrait fonctionner. Cela fonctionne-t-il si vous ajoutez 1 au lieu de soustraire 7? Comment déterminez-vous que sevenDaysAgo se réfère aujourd'hui?
JeremyP

Réponses:

112

utilisez la méthode dateByAddingTimeInterval:

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

production:

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

J'espère que ça aide

Novarg
la source
45
Il existe des cas extrêmes où cela ne fonctionnera pas correctement, par exemple si l'heure d'été change pendant les sept jours en question.
JeremyP
1
La réponse de dymv est la manière la plus sûre de le faire.
w3bshark
2
C'est la mauvaise réponse pour les raisons susmentionnées, utilisez la réponse de dymv
BarrettJ
1
En fait, cela peut être fait simplement par:[now dateByAddingDays:-7]
CrashOverride
Faire ce genre de calcul est dangereux, préférez la version de @ Dov.
ctietze
196

code:

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

production:

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

Et je suis entièrement d'accord avec JeremyP.

BR.
Eugène

dymv
la source
2
Il y a cependant une fuite de mémoire dans cette réponse.
atuljangra
133

Si vous utilisez au moins iOS 8 ou OS X 10.9, il existe un moyen encore plus propre:

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

Ou, avec Swift 2:

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

Et avec Swift 3 et plus, il devient encore plus compact:

let sevenDaysAgo = Calendar.current.date(byAdding: .day, value: -7, to: Date())
Dov
la source
3
Cela devrait être la réponse acceptée car elle gère tous les cas extrêmes pour vous.
Zhivko Bogdanov
@ZhivkoBogdanov Ma réponse est venue quelques années après la réponse acceptée, et je ne crois pas que vous puissiez changer votre réponse acceptée après coup.
Dov
C'est plus pour référence future qu'autre chose.
Zhivko Bogdanov
56

Swift 3

Calendar.current.date(byAdding: .day, value: -7, to: Date())
Marckaraujo
la source
3
N'utilisez pas NSCalendar, utilisez plutôt Calendar :)
Jonas
8

Swift 4.2 - Mutation (mise à jour) Self

Voici une autre façon dont l'affiche d'origine peut obtenir il y a une semaine s'il a déjà une variable de date (se met à jour / se mute).

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

Usage

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
la source
4

La réponse de dymv fonctionne très bien. Vous pouvez l'utiliser rapidement

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

Vous pouvez appeler ça avec

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

J'espère que ça aide et merci de dymv

Babac
la source
4

Swift 4.2 iOS 11.x La solution Babec , pure Swift

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
la source
4

Extension opérateur Swift:

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

Usage

let today = Date()
let yesterday = today - 7
Sam
la source
3

Version Swift 3.0+ de la réponse initiale acceptée

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

Cependant, cela n'utilise que des valeurs absolues. Utiliser des réponses de calendrier est probablement plus approprié dans la plupart des cas.

originalmyth
la source
-2

Swift 3:

Une modification de la réponse de Dov.

extension Date {

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

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

Usage:

let dateBefore =  Date().dateBeforeOrAfterFromToday(numberOfDays : -7)
let dateAfter = Date().dateBeforeOrAfterFromToday(numberOfDays : 7)
print ("dateBefore : \(dateBefore), dateAfter :\(dateAfter)")
AG
la source
1
Pourquoi est-il numberOfDaysfacultatif puis déballé de force? Ne devrait-il pas être simplement non facultatif Int?
Dov
C'est la bonne façon de contenir une valeur facultative dans la fonction swift.
AG
1
Mais pourquoi numberOfDays est-il facultatif? y a-t-il un moment où quelqu'un appellera cette méthode d'extension et ne donnera pas un certain nombre de jours pour ajouter ou supprimer?
Dov
-3

POUR SWIFT 3.0

voici la fonction, vous pouvez réduire les jours, les mois, les jours de n'importe quel nombre, comme par exemple ici, j'ai réduit l'année de la date système actuelle de 100 ans, vous pouvez le faire pour le jour, le mois, il suffit de définir le compteur et de le stocker dans un array, vous pouvez ce tableau n'importe où puis 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
la source