iDeveloper
iDeveloper

Reputation: 2444

How to get previous and next month in Swift

I am trying to get previous and next month by click on button but this has changed my year, not month.

I am trying it from using this answer but it is in Objective-C.

func firstDateOfMonth() {
    let components = calendar.components([.Year, .Month], fromDate: date)
    let startOfMonth = calendar.dateFromComponents(components)!
    print(dateFormatatter.stringFromDate(startOfMonth)) // 2015-11-01
}

func lastDateOfMonth() {
    let components = calendar.components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: date)
    
    let month = components.month
    let year = components.year
    
    let startOfMonth1 = ("01-\(month)-\(year)")
    
    var startOfMonth : NSDate?
    var lengthOfMonth : NSTimeInterval = 0
    calendar.rangeOfUnit(.Month, startDate: &startOfMonth, interval: &lengthOfMonth, forDate: date)
    let endOfMonth = startOfMonth!.dateByAddingTimeInterval(lengthOfMonth - 1)
    print(dateFormatatter.stringFromDate(endOfMonth))
}

func monthCalculation() {
    firstDateOfMonth()
    lastDateOfMonth()
}

@IBAction func previousMonthBtnAction(sender: AnyObject) {
    let componen = calendar.components([.Day , .Month , .Year], fromDate: date)
    componen.month = -1
    self.date = calendar.dateFromComponents(componen)!
    print(self.date)
}

@IBAction func nextMonthBtnAction(sender: AnyObject) {

}

So how to do it for both previous and next month?

Upvotes: 32

Views: 39889

Answers (6)

Bayram Binbir
Bayram Binbir

Reputation: 2217

Use the below snippet to get any previous year or month date in Swift

private func getPreviousDate(monthOrYear: String, numberOfMonthOrYear: Int, dateFormat: String) -> String{
    var date : Date
    if(monthOrYear.lowercased().contains("month")){
        date = Calendar.current.date(byAdding: .month, value: -numberOfMonthOrYear, to: Date())!
    } else {
         date = Calendar.current.date(byAdding: .year, value: -numberOfMonthOrYear, to: Date())!
    }
    return dateFormatter(dateFormat: dateFormat, date:date)
}

func dateFormatter (dateFormat: String, date: Date) -> String{
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = dateFormat
    return dateFormatter.string(from: date)
}

Upvotes: 0

Leo Dabus
Leo Dabus

Reputation: 236340

Will add here in case people need next month as well. This works for any date:

Swift 5.1 or later • Xcode 11 or later


extension Calendar {
    static let iso8601 = Calendar(identifier: .iso8601)
}

extension Date {
    
    var year: Int {
        Calendar.iso8601.component(.year, from: self)
    }
    
    var lastDateOfPreviousMonth: Date? {
        DateComponents(calendar: .iso8601, year: year, month: month, day: 0).date
    }
    var previousMonth: Int {
        lastDateOfPreviousMonth?.month ?? 0
    }
    
    var firstDateOfMonth: Date? {
        DateComponents(calendar: .iso8601, year: year, month: month).date
    }
    var month: Int {
        Calendar.iso8601.component(.month, from: self)
    }

    var firstDateOfFollowingMonth: Date? {
        DateComponents(calendar: .iso8601, year: year, month: month+1).date
    }
    var followingMonth: Int {
        firstDateOfFollowingMonth?.month ?? 0
    }
}

Date().lastDateOfPreviousMonth    //  "Feb 28, 2022 at 12:00 AM"
Date().previousMonth              //  2

Date().firstDateOfMonth           //  "Mar 1, 2022 at 12:00 AM"
Date().month                      //  3

Date().firstDateOfFollowingMonth  // "Apr 1, 2022 at 12:00 AM"
Date().followingMonth             //  4

Upvotes: 3

Ariven Nadar
Ariven Nadar

Reputation: 1308

Swift 5

let date = Date()
let calendar = Calendar.current
let currentYear = Calendar.current.component(.year, from: Date())
let previousYear = currentYear + 1
let nextYear = currentYear + 1
print("\(previousYear)->\(currentYear)->\(nextYear)")

Output:
2018->2019->2020

Happy Coding :)

Upvotes: 2

Nirav D
Nirav D

Reputation: 72410

Try like this.

To get date of next month.

Swift 3 and Swift 4

let nextMonth = Calendar.current.date(byAdding: .month, value: 1, to: Date())

Swift 2.3 or lower

let nextMonth = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: 1, toDate: NSDate(), options: [])

To get date of previous month.

Swift 3

let previousMonth = Calendar.current.date(byAdding: .month, value: -1, to: Date())

Swift 2.3 or lower

let previousMonth = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: -1, toDate: NSDate(), options: [])

Note: To get date of next and previous month I have used todays date, you can use date from which you want next and previous month date, just change NSDate() with your NSDate object.

Edit: For continues traveling of next and previous months you need to store one date object currentDate and when you try to get next and previous month use that date object and update it.

For next month.

let currentDate = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: 1, toDate: currentDate, options: [])

For previous month.

let currentDate = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: -1, toDate: currentDate, options: [])

You can also use extension that will make thing easy.

Swift 3

extension Date {
    func getNextMonth() -> Date? {
        return Calendar.current.date(byAdding: .month, value: 1, to: self)
    }

    func getPreviousMonth() -> Date? {
        return Calendar.current.date(byAdding: .month, value: -1, to: self)
    }
}

Swift 2.3 or lower

extension NSDate {
    func getNextMonth() -> NSDate?{
        return NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: 1, toDate: self, options: [])
    }

    func getPreviousMonth() -> NSDate?{
        return NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: -1, toDate: self, options: [])
    }
}

Now just get date from currentDate.

currentDate = currentDate.getNextMonth()
currentDate = currentDate.getPreviousMonth()

Upvotes: 83

algrid
algrid

Reputation: 5954

I'd recommend using SwiftDate library:

let date = Date()
let nextMonthDate = date.nextMonth(at: .auto)
let prevMonthDate = date.prevMonth(at: .auto)

You can use .start and .end instead of .auto. Look at the info about nextMonth for example:

when .auto evaluated date is calculated by adding one month to the current date.

If you pass .start result date is the first day of the next month (at 00:00:00).

If you pass .end result date is the last day of the next month (at 23:59:59).

The library also contains prevWeek/nextWeek and many other useful methods.

Upvotes: 1

Tikhonov Aleksandr
Tikhonov Aleksandr

Reputation: 14329

var currentDate = NSDate()

func nextMonth() -> NSDate {
    let nextDate = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: 1, toDate: currentDate, options: [])!
    currentDate = nextDate
    return nextDate
}

print(nextMonth()) // 2016-11-01 20:11:15 +0000
print(nextMonth()) // 2016-12-01 21:11:15 +0000
print(nextMonth()) // 2017-01-01 21:11:15 +0000

Upvotes: 2

Related Questions