How do I find the number of days in given month and year using swift

Swift

Swift Problem Overview


I want to find the total number days on given month and year. Example: I want to find total number of days on year = 2015, month = 7

Swift Solutions


Solution 1 - Swift

First create an NSDate for the given year and month:

let dateComponents = NSDateComponents()
dateComponents.year = 2015
dateComponents.month = 7

let calendar = NSCalendar.currentCalendar()
let date = calendar.dateFromComponents(dateComponents)!

Then use the rangeOfUnit() method, as described in https://stackoverflow.com/questions/1179945/number-of-days-in-the-current-month-using-iphone-sdk:

// Swift 2:
let range = calendar.rangeOfUnit(.Day, inUnit: .Month, forDate: date)
// Swift 1.2:
let range = calendar.rangeOfUnit(.CalendarUnitDay, inUnit: .CalendarUnitMonth, forDate: date)

let numDays = range.length
print(numDays) // 31

Update for Swift 3 (Xcode 8):

let dateComponents = DateComponents(year: 2015, month: 7)
let calendar = Calendar.current
let date = calendar.date(from: dateComponents)!

let range = calendar.range(of: .day, in: .month, for: date)!
let numDays = range.count
print(numDays) // 31

Solution 2 - Swift

Updated for Swift 3.1, Xcode 8+, iOS 10+
let calendar = Calendar.current
let date = Date()

// Calculate start and end of the current year (or month with `.month`):
let interval = calendar.dateInterval(of: .year, for: date)! //change year it will no of days in a year , change it to month it will give no of days in a current month

// Compute difference in days:
let days = calendar.dateComponents([.day], from: interval.start, to: interval.end).day!
print(days)

Solution 3 - Swift

In extension format, using self to be able to return the number of days more dynamically (Swift 3).

extension Date {

func getDaysInMonth() -> Int{
    let calendar = Calendar.current

    let dateComponents = DateComponents(year: calendar.component(.year, from: self), month: calendar.component(.month, from: self))
    let date = calendar.date(from: dateComponents)!
    
    let range = calendar.range(of: .day, in: .month, for: date)!
    let numDays = range.count
    
    return numDays
}

}

Solution 4 - Swift

Swift 5.0

func getDaysInMonth(month: Int, year: Int) -> Int? {
        let calendar = Calendar.current

        var startComps = DateComponents()
        startComps.day = 1
        startComps.month = month
        startComps.year = year

        var endComps = DateComponents()
        endComps.day = 1
        endComps.month = month == 12 ? 1 : month + 1
        endComps.year = month == 12 ? year + 1 : year

        
        let startDate = calendar.date(from: startComps)!
        let endDate = calendar.date(from:endComps)!

        
        let diff = calendar.dateComponents([Calendar.Component.day], from: startDate, to: endDate)

        return diff.day
    }
    if let numberOfDays = getDaysInMonth(month: 1, year: 2015) {
     print(numberOfDays)

     }

Swift 2.0

func getDaysInMonth(month: Int, year: Int) -> Int
{
    let calendar = NSCalendar.currentCalendar()

    let startComps = NSDateComponents()
    startComps.day = 1
    startComps.month = month
    startComps.year = year

    let endComps = NSDateComponents()
    endComps.day = 1
    endComps.month = month == 12 ? 1 : month + 1
    endComps.year = month == 12 ? year + 1 : year

    let startDate = calendar.dateFromComponents(startComps)!
    let endDate = calendar.dateFromComponents(endComps)!

    let diff = calendar.components(NSCalendarUnit.Day, fromDate: startDate, toDate: endDate, options: NSCalendarOptions.MatchFirst)

    return diff.day
}

let days = getDaysInMonth(4, year: 2015) // April 2015 has 30 days
print(days) // Prints 30

Swift 1.2

func getDaysInMonth(month: Int, year: Int) -> Int
{
    let calendar = NSCalendar.currentCalendar()

    let startComps = NSDateComponents()
    startComps.day = 1
    startComps.month = month
    startComps.year = year

    let endComps = NSDateComponents()
    endComps.day = 1
    endComps.month = month == 12 ? 1 : month + 1
    endComps.year = month == 12 ? year + 1 : year

    let startDate = calendar.dateFromComponents(startComps)!
    let endDate = calendar.dateFromComponents(endComps)!

    let diff = calendar.components(NSCalendarUnit.CalendarUnitDay, fromDate: startDate, toDate: endDate, options: NSCalendarOptions.allZeros)

    return diff.day
}

let days = getDaysInMonth(4, 2015) // There were 30 days in April 2015
println(days) // Prints 30

Solution 5 - Swift

In order to get number of days and all the dates on given month and year, try this.

func getAllDates(month: Int, year: Int) -> [Date] {
    let dateComponents = DateComponents(year: year, month: month)
    let calendar = Calendar.current
    let date = calendar.date(from: dateComponents)!
        
    let range = calendar.range(of: .day, in: .month, for: date)!
    let numDays = range.count
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy MM dd"
    formatter.timeZone = TimeZone(abbreviation: "GMT+0:00")
    var arrDates = [Date]()
    for day in 1...numDays {
        let dateString = "\(year) \(month) \(day)"
        if let date = formatter.date(from: dateString) {
            arrDates.append(date)
        }
    }
        
    return arrDates
}

Usage:

let arrDatesInGivenMonthYear = getAllDates(month: 1, year: 2018)
debugPrint(arrDatesInGivenMonthYear)
//Output: [2018-01-01 00:00:00 +0000, 2018-01-02 00:00:00 +0000, ... , 2018-01-31 00:00:00 +0000]

let numberOfDays = arrDatesInGivenMonthYear.count
debugPrint(numberOfDays)
//Output: 31

Solution 6 - Swift

here is the swift 4.0 version

func getTotalDate(){
    // choose the month and year you want to look
    var dateComponents = DateComponents()
    dateComponents.year = 2018
    dateComponents.month = 10
    
    let calendar = Calendar.current
    let datez = calendar.date(from: dateComponents)
    // change .month into .year to see the days available in the year
    let interval = calendar.dateInterval(of: .month, for: datez!)!
    
    let days = calendar.dateComponents([.day], from: interval.start, to: interval.end).day!
    print(days)
}

Solution 7 - Swift

Swift 5

Another way to approach this:

extension Date {
	
	func daysInMonth(_ monthNumber: Int? = nil, _ year: Int? = nil) -> Int {
		var dateComponents = DateComponents()
		dateComponents.year = year ?? Calendar.current.component(.year,  from: self)
		dateComponents.month = monthNumber ?? Calendar.current.component(.month,  from: self)
		if
			let d = Calendar.current.date(from: dateComponents),
			let interval = Calendar.current.dateInterval(of: .month, for: d),
			let days = Calendar.current.dateComponents([.day], from: interval.start, to: interval.end).day
		{ return days } else { return -1 }
	}

}

Solution 8 - Swift

What about for a given year?

The following is printing the number of days in the date's month:

let range = userCalendar.range(of: .day, in: .year, for: Date())!
print("Days In Year: \(range.count)") // prints 31

... and not the number of days in the date's year as expected :/

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShrestha AsheshView Question on Stackoverflow
Solution 1 - SwiftMartin RView Answer on Stackoverflow
Solution 2 - SwiftAbdul KarimView Answer on Stackoverflow
Solution 3 - Swiftspogebob92View Answer on Stackoverflow
Solution 4 - SwiftmbottoneView Answer on Stackoverflow
Solution 5 - SwiftMohammad Zaid PathanView Answer on Stackoverflow
Solution 6 - Swiftuser9426229View Answer on Stackoverflow
Solution 7 - SwiftJimmy_mView Answer on Stackoverflow
Solution 8 - SwiftChris AllinsonView Answer on Stackoverflow