Odejmij 7 dni od bieżącej daty

119

Wygląda na to, że nie mogę odjąć 7 dni od aktualnej daty. Oto jak to robię:

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 otrzymuje tę samą wartość, co bieżąca data.

Proszę pomóż.

EDYCJA: W moim kodzie zapomniałem zamienić zmienną, która pobiera aktualną datę, na właściwą. Więc powyższy kod działa.

Alex Tau
źródło
3
[NSDate dateWithTimeIntervalSinceReferenceDate:[NSDate date].timeIntervalSinceReferenceDate - (7*24*60*60)]- Chociaż nie obsługuje zmian czasu letniego.
Hot Licks
To powinno działać. Czy to działa, jeśli dodasz 1 zamiast odjąć 7? Jak ustalasz, że sevenDaysAgo odnosi się do dnia dzisiejszego?
JeremyP

Odpowiedzi:

112

użyj metody dateByAddingTimeInterval:

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

wynik:

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

Mam nadzieję, że to pomoże

Novarg
źródło
45
Istnieją skrajne przypadki, w których nie będzie to działać poprawnie, na przykład jeśli czas letni zmieni się w ciągu tych siedmiu dni.
JeremyP
1
odpowiedzią dymv jest bezpieczniejszy sposób na zrobienie tego.
w3bshark
2
To jest zła odpowiedź z wyżej wymienionych powodów, użyj odpowiedzi dymv
BarrettJ
1
Właściwie można to zrobić po prostu przez:[now dateByAddingDays:-7]
CrashOverride
Wykonywanie tego rodzaju obliczeń jest niebezpieczne, preferuj wersję @ Dov.
ctietze
196

kod:

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

wynik:

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

W pełni zgadzam się z JeremyPem.

BR.
Eugene

dymv
źródło
2
W tej odpowiedzi jest jednak wyciek pamięci.
atuljangra
133

Jeśli masz co najmniej iOS 8 lub OS X 10.9, istnieje jeszcze prostszy sposób:

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

Lub w przypadku Swift 2:

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

A dzięki Swift 3 i nowszym jest jeszcze bardziej kompaktowy:

let sevenDaysAgo = Calendar.current.date(byAdding: .day, value: -7, to: Date())
Dov
źródło
3
To powinna być akceptowana odpowiedź, ponieważ obsługuje wszystkie przypadki skrajne za Ciebie.
Zhivko Bogdanov
@ZhivkoBogdanov Moja odpowiedź nadeszła kilka lat po zaakceptowanej odpowiedzi i nie wierzę, że możesz zmienić zaakceptowaną odpowiedź po fakcie.
Dov
Jest to bardziej przydatne w przyszłości niż cokolwiek innego.
Zhivko Bogdanov
56

Szybki 3

Calendar.current.date(byAdding: .day, value: -7, to: Date())
Marckaraujo
źródło
3
Nie używaj NSCalendar, zamiast tego użyj Kalendarza :)
Jonas
8

Swift 4.2 - Mutacja (aktualizacja) siebie

Oto inny sposób, w jaki oryginalny plakat może dostać się tydzień temu, jeśli ma już zmienną daty (aktualizuje / mutuje się).

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

Stosowanie

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

lub

// Iterate through one week
for i in 1...7 {
    myDate.changeDays(by: i)
    // Do something
}
Mark Moeykens
źródło
4

Odpowiedź dymv działa świetnie. Możesz to szybko wykorzystać

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

Możesz to nazwać za pomocą

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

Mam nadzieję, że to pomoże i dziękuję dymv

Babac
źródło
4

Swift 4.2 iOS 11.x Rozwiązanie Babeca , czysty 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
źródło
4

Szybkie rozszerzenie operatora:

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

Stosowanie

let today = Date()
let yesterday = today - 7
Sam
źródło
3

Wersja Swift 3.0+ oryginalnej zaakceptowanej odpowiedzi

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

Jednak używa to tylko wartości bezwzględnych. W większości przypadków bardziej odpowiednie jest użycie odpowiedzi z kalendarza.

oryginalność
źródło
-2

Swift 3:

Modyfikacja odpowiedzi Dova.

extension Date {

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

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

Stosowanie:

let dateBefore =  Date().dateBeforeOrAfterFromToday(numberOfDays : -7)
let dateAfter = Date().dateBeforeOrAfterFromToday(numberOfDays : 7)
print ("dateBefore : \(dateBefore), dateAfter :\(dateAfter)")
AG
źródło
1
Dlaczego jest numberOfDaysopcjonalne, a następnie rozpakowane na siłę? Czy nie powinno to być po prostu nieobowiązkowe Int?
Dov
Jest to właściwy sposób na zawarcie wartości opcjonalnej w funkcji swift.
AG
1
Ale dlaczego numberOfDays jest opcjonalne? Czy jest czas, kiedy ktoś wywoła tę metodę rozszerzenia i nie da czasu na dodanie lub usunięcie?
Dov
-3

DLA SWIFT 3.0

tu jest funkcja, możesz zredukować dni, miesiąc, dzień dowolną liczbą, jak na przykład tutaj, zmniejszyłem rok bieżącej daty systemowej o 100 lat, możesz to zrobić dla dnia, miesiąca również po prostu ustaw licznik i przechowuj go w tablica, możesz tę tablicę w dowolnym miejscu, a następnie 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
źródło