How can I get the last day of the current month as an NSDate
?
Asked
Active
Viewed 2.8k times
52
-
1duplicate? http://stackoverflow.com/questions/1731322/get-all-days-of-any-month-with-objective-c – littlegreen May 05 '10 at 10:36
-
It isn't an _exact_ duplicate. – Marcelo Cantos May 05 '10 at 10:46
-
**This is now very easy:** https://stackoverflow.com/a/45150320/294884 – Fattie Jul 17 '17 at 21:40
9 Answers
71
NSDate *curDate = [NSDate date];
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* comps = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:curDate]; // Get necessary date components
// set last of month
[comps setMonth:[comps month]+1];
[comps setDay:0];
NSDate *tDateMonth = [calendar dateFromComponents:comps];
NSLog(@"%@", tDateMonth);
should also work.

VisioN
- 143,310
- 32
- 282
- 281

Jonas Schnelli
- 9,965
- 3
- 48
- 60
44
// Adapted from running code in my app
NSDate *curDate = [NSDate date];
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSRange daysRange =
[currentCalendar
rangeOfUnit:NSDayCalendarUnit
inUnit:NSMonthCalendarUnit
forDate:curDate];
// daysRange.length will contain the number of the last day
// of the month containing curDate
NSLog(@"%i", daysRange.length);

StCredZero
- 461
- 4
- 6
-
1For those obsessed with one-liners :P `days = [NSCalendar.currentCalendar rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:myDate].length` – mojuba Aug 26 '16 at 12:48
10
Put this in a category:
-(NSDate*)lastDayOfMonth
{
NSInteger dayCount = [self numberOfDaysInMonthCount];
NSDateComponents *comp = [[self calendar] components:
NSCalendarUnitYear |
NSCalendarUnitMonth |
NSCalendarUnitDay fromDate:self];
[comp setDay:dayCount];
return [[self calendar] dateFromComponents:comp];
}
-(NSInteger)numberOfDaysInMonthCount
{
NSRange dayRange = [[self calendar] rangeOfUnit:NSCalendarUnitDay
inUnit:NSCalendarUnitMonth
forDate:self];
return dayRange.length;
}
-(NSCalendar*)calendar
{
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[calendar setTimeZone:[NSTimeZone timeZoneWithName:TIMEZONE]];
return calendar;
}

Cai
- 3,609
- 2
- 19
- 39
-
I'm using something similar to this, thanks, but any reason why your are using NSGregorianCalendar instead of `[NSCalendar currentCalendar]`? – Christopher King Oct 13 '15 at 23:30
-
Current calendar may not be NSGregorian calendar, and at the time I wanted to be explicit for peace of mind. – Oct 14 '15 at 08:52
-
if you want the very last second of the last day of the month just add comp.hour = 24; comp.minute = 0; comp.second = 0; – lucianoenrico Jan 08 '16 at 10:56
3
Swift version
extension NSDate {
func lastDayOfMonth() -> NSDate {
let calendar = NSCalendar.currentCalendar()
let dayRange = calendar.rangeOfUnit(.Day, inUnit: .Month, forDate: self)
let dayCount = dayRange.length
let comp = calendar.components([.Year, .Month, .Day], fromDate: self)
comp.day = dayCount
return calendar.dateFromComponents(comp)!
}
}

SoftDesigner
- 5,640
- 3
- 58
- 47
0
Version from iOS 7
just to get rid of the deprecations... with a minor addition to get the last second of the day.
// current date
NSDate *now = [NSDate new];
// get last day of the current month
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
[calendar setTimeZone:[NSTimeZone systemTimeZone]];
NSRange dayRange = [ calendar rangeOfUnit:NSCalendarUnitDay
inUnit:NSCalendarUnitMonth
forDate:now];
NSInteger numberOfDaysInCurrentMonth = dayRange.length;
NSDateComponents *comp = [calendar components:
NSCalendarUnitYear |
NSCalendarUnitMonth |
NSCalendarUnitDay fromDate:now];
comp.day = numberOfDaysInCurrentMonth;
comp.hour = 24;
comp.minute = 0;
comp.second = 0;
NSDate *endOfMonth = [calendar dateFromComponents:comp];

lucianoenrico
- 1,486
- 1
- 13
- 21
0
Swift 3.0.1 Version
extension Date {
func lastDayOfMonth() -> Date {
let calendar = NSCalendar.current
let dayRange = calendar.range(of: .day, in: .month, for: self)
let dayCount = dayRange?.count
var comp = calendar.dateComponents([.year, .month, .day], from: self)
comp.day = dayCount
return calendar.date(from: comp)!
}
}

help-info.de
- 6,695
- 16
- 39
- 41

burakyldz
- 1
- 1
0
With Swift 3 & iOS 10 the easiest way I found to do this is Calendar
's dateInterval(of:for:)
:
func monthInterval() -> DateInterval? {
let calendar = Calendar.current
guard let interval = calendar.dateInterval(of: .month, for: Date()) else { return nil }
let duration = interval.duration
// Subtract one second because dateInterval(of:for:)'s end date returns the beginning of the following month
return DateInterval(start: interval.start, duration: duration - 1)
}
guard let interval = monthInterval() else { return }
You can then use interval.start
and interval.end
to get the dates you need.

LuisCien
- 6,362
- 4
- 34
- 42
0
NSDate *curDate = [NSDate date];
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSRange daysRange = [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth
forDate:curDate];
NSDateComponents* comps = [currentCalendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:curDate];
[comps setDay:daysRange.length];
NSDate *maximumDate = [[NSCalendar currentCalendar] dateFromComponents:comps];

Amritpal
- 59
- 1
- 6
-2
Workaround Function:
-(int)GetLastDayOfMonth:(NSDate *)date
{
int last_day = 27;
NSCalendar *cal=[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *compsMonth = [cal components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:date];
[compsMonth setDay:last_day];
int month = [compsMonth month];
while(TRUE){
[compsMonth setDay:last_day+1];
NSDate *dateFuture = [cal dateFromComponents:compsMonth];
NSDateComponents *futureComps = [cal components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:dateFuture];
if(month != [futureComps month]){
return last_day;
}
last_day+=1;
}
return last_day;
}

pradox
- 533
- 1
- 4
- 5