Get firstdate, lastdate of month?

18,210

Solution 1

Some NSDate category methods I wrote will help you:

Here's an easy way to find the start of a month:

 (NSDate *) startOfMonth
{
    NSCalendar * calendar = [NSCalendar currentCalendar];

    NSDateComponents * currentDateComponents = [calendar components: NSYearCalendarUnit | NSMonthCalendarUnit fromDate: self];
    NSDate * startOfMonth = [calendar dateFromComponents: currentDateComponents];

    return startOfMonth;
}

All it does is take the year and month components from the current day, then convert back to a date again.

For the end of the month, I use a couple of methods:

- (NSDate *) dateByAddingMonths: (NSInteger) monthsToAdd
{
    NSCalendar * calendar = [NSCalendar currentCalendar];

    NSDateComponents * months = [[NSDateComponents alloc] init];
    [months setMonth: monthsToAdd];

    return [calendar dateByAddingComponents: months toDate: self options: 0];
}

and

- (NSDate *) endOfMonth
{
    NSCalendar * calendar = [NSCalendar currentCalendar];

    NSDate * plusOneMonthDate = [self dateByAddingMonths: 1];
    NSDateComponents * plusOneMonthDateComponents = [calendar components: NSYearCalendarUnit | NSMonthCalendarUnit fromDate: plusOneMonthDate];
    NSDate * endOfMonth = [[calendar dateFromComponents: plusOneMonthDateComponents] dateByAddingTimeInterval: -1]; // One second before the start of next month

    return endOfMonth;
}

This is a 3 step process - add one month to the current date, find the start of the next month, then subtract 1 second to find the end of this month.


Swift 3

extension Date {

    func startOfMonth() -> Date? {

        let calendar = Calendar.current
        let currentDateComponents = calendar.dateComponents([.year, .month], from: self)
        let startOfMonth = calendar.date(from: currentDateComponents)

        return startOfMonth
    }

    func dateByAddingMonths(_ monthsToAdd: Int) -> Date? {

        let calendar = Calendar.current
        var months = DateComponents()
        months.month = monthsToAdd

        return calendar.date(byAdding: months, to: self)
    }

    func endOfMonth() -> Date? {

        guard let plusOneMonthDate = dateByAddingMonths(1) else { return nil }

        let calendar = Calendar.current
        let plusOneMonthDateComponents = calendar.dateComponents([.year, .month], from: plusOneMonthDate)
        let endOfMonth = calendar.date(from: plusOneMonthDateComponents)?.addingTimeInterval(-1)

        return endOfMonth

    }
}

Swift 2

extension NSDate {

    func startOfMonth() -> NSDate? {

        let calendar = NSCalendar.currentCalendar()
        let currentDateComponents = calendar.components(.CalendarUnitYear | .CalendarUnitMonth, fromDate: self)
        let startOfMonth = calendar.dateFromComponents(currentDateComponents)

        return startOfMonth
    }

    func dateByAddingMonths(monthsToAdd: Int) -> NSDate? {

        let calendar = NSCalendar.currentCalendar()
        let months = NSDateComponents()
        months.month = monthsToAdd

        return calendar.dateByAddingComponents(months, toDate: self, options: nil)
    }

    func endOfMonth() -> NSDate? {

        let calendar = NSCalendar.currentCalendar()
        if let plusOneMonthDate = dateByAddingMonths(1) {
            let plusOneMonthDateComponents = calendar.components(.CalendarUnitYear | .CalendarUnitMonth, fromDate: plusOneMonthDate)

            let endOfMonth = calendar.dateFromComponents(plusOneMonthDateComponents)?.dateByAddingTimeInterval(-1)

            return endOfMonth
        }

        return nil
    }
}

Solution 2

Try this trick.

Day Param: 1 is to Get first date of this month

Day Param: 0 is to Get last date of this month by getting last date of month previous to next month (means this month))

- (void)returnDate:(NSDate *)date {

    NSCalendar * calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit;
    NSDateComponents *comps = [calendar components:unitFlags fromDate:date];

    NSDate * firstDateOfMonth = [self returnDateForMonth:comps.month year:comps.year day:1];
    NSDate * lastDateOfMonth = [self returnDateForMonth:comps.month+1 year:comps.year day:0];

    NSLog(@"date %@", date);              // date 2013-06-20
    NSLog(@"First %@", firstDateOfMonth); // firstDateOfMonth 2013-06-01
    NSLog(@"Last %@", lastDateOfMonth);   // lastDateOfMonth  2013-06-30

}

Next

- (NSDate *)returnDateForMonth:(NSInteger)month year:(NSInteger)year day:(NSInteger)day {

    NSDateComponents *components = [[NSDateComponents alloc] init];

    [components setDay:day];
    [components setMonth:month];
    [components setYear:year];

    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSGregorianCalendar];
    return [gregorian dateFromComponents:components];
}

Don't forget for right Date Formater

Updated for IOS 8.0

- (void)returnDate:(NSDate *)date { 
    NSCalendar * calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth;
    NSDateComponents *comps = [calendar components:unitFlags fromDate:date];

    NSDate * firstDateOfMonth = [self returnDateForMonth:comps.month year:comps.year day:1];
    NSDate * lastDateOfMonth = [self returnDateForMonth:comps.month+1 year:comps.year day:0];

    NSLog(@"date %@", date);              // date 2013-06-20
    NSLog(@"First %@", firstDateOfMonth); // firstDateOfMonth 2013-06-01
    NSLog(@"Last %@", lastDateOfMonth);   // lastDateOfMonth  2013-06-30

}

Next

- (NSDate *)returnDateForMonth:(NSInteger)month year:(NSInteger)year day:(NSInteger)day {

    NSDateComponents *components = [[NSDateComponents alloc] init];

    [components setDay:day];
    [components setMonth:month];
    [components setYear:year];

    NSCalendar *gregorian = [[NSCalendar alloc]
                         initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    return [gregorian dateFromComponents:components];
}

Now your are working with:

  • NSCalendarUnitYear
  • NSCalendarUnitWeekOfMonth
  • NSCalendarIdentifierGregorian

Solution 3

Ok, since I'm rolling my own calendar control, I went ahead and created a NSCalendar category. Here's my lastOfMonth method:

- (NSDate *)lastOfMonth:(NSDate *)date
{
    NSDateComponents *dc = [self components:NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit fromDate:date];

    NSRange dim = [self rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];
    dc.day = dim.length;

    return [self dateFromComponents:dc];
}

Solution 4

For Swift 2.0 to get the first day of the current month:

    let date = NSDate()
    let calendar = NSCalendar.currentCalendar()
    let dateComponents = calendar.components([NSCalendarUnit.Month, NSCalendarUnit.Year], fromDate: date)
    let firstDay = self.returnDateForMonth(dateComponents.month, year: dateComponents.year, day: 1)
    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "dd-MMM-yy"

    print("First day of this month: \(firstDay)") // 01-Sep-15

And the function to do this:

 func returnDateForMonth(month:NSInteger, year:NSInteger, day:NSInteger)->NSDate{
    let comp = NSDateComponents()
    comp.month = month
    comp.year = year
    comp.day = day

    let grego = NSCalendar.currentCalendar()
    return grego.dateFromComponents(comp)!
}

Solution 5

Swift 5 getting last day of month - base on different sources

// -------------------------------------------------------
// lastDayOfMonth
// -------------------------------------------------------
static func lastDayOfMonth(year:Int, month:Int) -> Int {
    let calendar:Calendar = Calendar.current
    var dc:DateComponents = DateComponents()
    dc.year = year
    dc.month = month + 1
    dc.day = 0
    let lastDateOfMonth:Date = calendar.date(from:dc)!
    let lastDay = calendar.component(Calendar.Component.day, from: lastDateOfMonth)
    return lastDay
}
Share:
18,210

Related videos on Youtube

Alice Chen
Author by

Alice Chen

Updated on October 30, 2022

Comments

  • Alice Chen
    Alice Chen over 1 year

    I want to get firstdate、lastdate of month,I try

    NSDateComponents *components = [calendar components:units fromDate:[NSDate date]];
    [components setDay:1];
    self.currentDate = [calendar dateFromComponents:components];
    int m = components.month;
    int y = components.year;
    int d = components.day;
    
    log: 2012,5,1
    

    How can i get lastdate od month?

    please give me some advice,thank you!!

  • Yevhen Dubinin
    Yevhen Dubinin over 9 years
    One point to add is NSCalendar has a timeZone property which, by default, set to current timezone. In order to get these conversion in GMT, you should add [calendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"];
  • Thomas Kremmel
    Thomas Kremmel almost 9 years
    Adding GMT timezone in Swift: calendar.timeZone = NSTimeZone(name: "GMT")!
  • halbano
    halbano over 8 years
    Use: NSCalendarUnitYear and NSCalendarUnitMonth to avoid deprecation warnings
  • jenish
    jenish over 7 years
    its not working same mont last date and first date . need to change i.e. NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay its give perfect result .
  • Nazir
    Nazir over 7 years
    @jenish thanks, on updating to ios8, placed wrong component - week of month. The correct is NSCalendarUnitMonth updated the answer. NSCalendarUnitDay is no need to place as we are not using it in next code.
  • Admin
    Admin about 7 years
    I'm getting previous date... Current month is Feb but the first and last date am getting are 31 jan and 27 feb
  • Admin
    Admin about 7 years
    set timeZone to UTC in returnDateForMonth method solves the issue