获取一个月的最后一天

52

如何将当前月份的最后一天获取为 NSDate 对象?


1
重复?https://dev59.com/t3I-5IYBdhLWcg3wq6do - littlegreen
这并不是一个“完全相同”的副本。 - Marcelo Cantos
这现在非常容易:https://dev59.com/cVwX5IYBdhLWcg3wnwgy#45150320 - Fattie
9个回答

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

应该也能工作。


4
为什么将day设为0会得到上个月的最后一天日期? - Raj Pawan Gumdal
2
这就是为什么有月份+1的原因,Raj。 - Rob van der Veer

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

1
对于那些追求一行代码的人 :P days = [NSCalendar.currentCalendar rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:myDate].length - mojuba

10
将此放入一个类别中:
-(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;
}

1
我正在使用类似的东西,谢谢,但是你为什么要使用NSGregorianCalendar而不是[NSCalendar currentCalendar]呢? - Christopher King
当前的日历可能不是 NSGregorian 日历,而我想要明确一点以保证安心。 - user1951992
如果你想获取某个月的最后一天的最后一秒,只需添加 comp.hour = 24; comp.minute = 0; comp.second = 0;。 - lucianoenrico

3

Swift版本

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

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

2023年仍然完美运作,谢谢! - undefined

0

iOS 7 版本

只是为了摆脱过时的内容...稍微添加了一点,以获取当天的最后一秒。

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

0

Swift 3.0.1 版本

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

0

使用Swift 3和iOS 10,我发现最简单的方法是使用CalendardateInterval(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 }

然后,您可以使用interval.startinterval.end来获取所需的日期。


-2

解决方法函数:

-(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;
}

循环不是必需的。 - Rob van der Veer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接