132

It seems that I can't subtract 7 days from the current date. This is how i am doing it:

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 gets the same value as the current date.

Please help.

EDIT: In my code I forgot to replace the variable which gets the current date with the right one. So above code is functional.

Alex Tau
  • 2,639
  • 4
  • 26
  • 30
  • 3
    `[NSDate dateWithTimeIntervalSinceReferenceDate:[NSDate date].timeIntervalSinceReferenceDate - (7*24*60*60)]` -- Though it doesn't handle DST changes. – Hot Licks Apr 18 '12 at 12:36
  • That should work. Does it work if you add 1 instead of subtract 7? How do you determine that sevenDaysAgo refers to today? – JeremyP Apr 18 '12 at 13:19

12 Answers12

199

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

output:

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

And I'm fully agree with JeremyP.

BR.
Eugene

dymv
  • 3,252
  • 2
  • 19
  • 29
144

If you're running at least iOS 8 or OS X 10.9, there's an even cleaner way:

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

Or, with Swift 2:

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

And with Swift 3 and up it gets even more compact:

let sevenDaysAgo = Calendar.current.date(byAdding: .day, value: -7, to: Date())
Dov
  • 15,530
  • 13
  • 76
  • 177
115

use dateByAddingTimeInterval method:

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

output:

7 days ago: 2012-04-11 11:35:38 +0000
starball
  • 20,030
  • 7
  • 43
  • 238
Novarg
  • 7,390
  • 3
  • 38
  • 74
68

Swift 3

Calendar.current.date(byAdding: .day, value: -7, to: Date())
Marckaraujo
  • 7,422
  • 11
  • 59
  • 97
11

Swift operator extension:

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

Usage

let today = Date()
let sevenDayAgo = today - 7
tanmoy
  • 1,276
  • 1
  • 10
  • 28
shbedev
  • 1,875
  • 17
  • 28
9

Swift 4.2 - Mutate (Update) Self

Here is another way the original poster can get one week ago if he already has a date variable (updates/mutates itself).

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

or

// Iterate through one week
for i in 1...7 {
    myDate.changeDays(by: i)
    // Do something
}
Mark Moeykens
  • 15,915
  • 6
  • 63
  • 62
5

dymv's answer work great. This you can use in swift

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

You can call this with

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

Hope it helps and thx to dymv

Babac
  • 931
  • 11
  • 21
5

Swift 4.2 iOS 11.x Babec's solution, 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
  • 8,587
  • 7
  • 46
  • 87
4

Swift 3.0+ version of the original accepted answer

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

However, this uses absolute values only. Use calendar answers is probably more suitable in most cases.

originalmyth
  • 129
  • 6
1

Swift 5

Function to add or subtract day from current date.

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

Now calling the function

var dayAddedDate = addOrSubtructDay(7)
var daySubtractedDate = addOrSubtructDay(-7)
  • To Add date pass prospective day value
  • To Subtract pass negative day value
Md. Enamul Haque
  • 926
  • 8
  • 14
-2

Swift 3:

A modification to Dov's answer.

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)")
Dov
  • 15,530
  • 13
  • 76
  • 177
Alvin George
  • 14,148
  • 92
  • 64
  • 1
    Why is `numberOfDays` optional and then force-unwrapped? Shouldn't it just be a non-optional `Int`? – Dov Sep 06 '17 at 14:50
  • Its the proper way of containing optional value in swift function. – Alvin George Sep 07 '17 at 06:03
  • 1
    But why is numberOfDays optional? is there any time when someone will call this extension method and not give a number of days to add or remove? – Dov Sep 07 '17 at 14:51
-3

FOR SWIFT 3.0

here is fucntion , you can reduce days , month ,day by any count like for example here , i have reduced the current system date's year by 100 year , you can do it for day , month also just set the counter and store it in an array , you can this array anywhere then 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)
        }