使用Cocoa确定两个日期之间的月数

问题描述:

如何使用Cocoa计算两个日期之间的月数?使用Cocoa确定两个日期之间的月数

感谢, 斯坦

看NSCalendars components:fromDate:toDate:options方法。它可以让你减去日期,然后提取几个月属性值

NSInteger month = [[[NSCalendar currentCalendar] components: NSCalendarUnitMonth 
                fromDate: yourFirstDate 
                toDate: yourSecondDate 
                options: 0] month]; 
+0

正是我需要的 - 谢谢。 – 2010-01-24 21:07:26

组件:FROM日期:TODATE:选择不正确的以下示例工作:

开始日期:2012年1月1日 结束日期:3月31日,使用上述方法个月2012

NUM = 2

正确答案应为3个月。

我用很长的计算方法如下: 1.查找开始月份的天数。将它添加到月份的小数部分。如果第一个日期是月初,请将其计为整月。 2.找到月底的天数。将其添加到月份的小数部分如果日期是本月的最后一个月,则将其计为整月。 3.查找2个日期之间的整个/整个月份并添加到月份的整数部分。 4.将月份的小数部分加上整数&以获得正确的值。

要获得包括每月的分数的回答以下可用于:

- (NSNumber *)numberOfMonthsBetweenFirstDate:(NSDate *)firstDate secondDate:(NSDate *)secondDate { 

if ([firstDate compare:secondDate] == NSOrderedDescending) { 
    return nil; 
} 

NSCalendar *calendar = [NSCalendar currentCalendar]; 

NSDateComponents *firstDateComponents = [calendar components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit 
                fromDate:firstDate]; 

NSInteger firstDay = [firstDateComponents day]; 

NSRange rangeOfFirstMonth = [calendar rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:firstDate]; 
NSUInteger numberOfDaysInFirstMonth = rangeOfFirstMonth.length; 
CGFloat firstMonthFraction = (CGFloat)(numberOfDaysInFirstMonth - firstDay)/(CGFloat)numberOfDaysInFirstMonth; 

// last month component 
NSDateComponents *lastDateComponents = [calendar components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit 
                   fromDate:secondDate]; 
NSInteger lastDay = [lastDateComponents day]; 
NSRange rangeOfLastMonth = [calendar rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:secondDate]; 
NSUInteger numberOfDaysInLastMonth = rangeOfLastMonth.length; 
CGFloat lastMonthFraction = (CGFloat)(lastDay)/(CGFloat)numberOfDaysInLastMonth; 

// Check if the two dates are within the same month 
if (firstDateComponents.month == lastDateComponents.month 
     && firstDateComponents.year == lastDateComponents.year) { 
    NSDateComponents *dayComponents = [calendar components:NSDayCalendarUnit 
                  fromDate:firstDate 
                  toDate:secondDate 
                  options:0]; 

    NSRange rangeOfMonth = [calendar rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:firstDate]; 
    NSUInteger numberOfDaysInMonth = rangeOfMonth.length; 
    return [NSNumber numberWithFloat:(CGFloat)dayComponents.day/(CGFloat)numberOfDaysInMonth]; 
} 

// Start date of the first complete month 
NSDateComponents *firstDateFirstDayOfNextMonth = firstDateComponents; 
firstDateFirstDayOfNextMonth.month +=1; 
firstDateFirstDayOfNextMonth.day = 1; 

// First day of the last month 
NSDateComponents *secondDateFirstDayOfMonth = lastDateComponents; 
secondDateFirstDayOfMonth.day = 1; 

NSInteger numberOfMonths = secondDateFirstDayOfMonth.month - firstDateFirstDayOfNextMonth.month 
     + (secondDateFirstDayOfMonth.year - firstDateFirstDayOfNextMonth.year) * 12; 

return [NSNumber numberWithFloat:(firstMonthFraction + numberOfMonths + lastMonthFraction)]; 
} 

我不得不计算两个日期之间的月变化。这意味着,从一月份的31日至2月1日本月1日已通过了NSCalendar.components将返回0

import UIKit 

func monthsSince(from: NSDate, to: NSDate) -> Int { 
    let fromComponents = NSCalendar.currentCalendar().components([.Month, .Year], fromDate: from) 
    let toComponents = NSCalendar.currentCalendar().components([.Month, .Year], fromDate: to) 

    return ((toComponents.year - fromComponents.year) * 12) + (toComponents.month - fromComponents.month) 
} 

let tests = [ 
    (from: (day: 1, month: 1, year: 2016), to: (day: 31, month: 1, year: 2016), result: 0), 
    (from: (day: 22, month: 1, year: 2016), to: (day: 5, month: 2, year: 2016), result: 1), 
    (from: (day: 22, month: 12, year: 2015), to: (day: 1, month: 1, year: 2016), result: 1), 
    (from: (day: 1, month: 1, year: 2016), to: (day: 1, month: 2, year: 2016), result: 1), 
    (from: (day: 1, month: 1, year: 2016), to: (day: 1, month: 3, year: 2016), result: 2) 
] 

for test in tests { 
    let from = NSCalendar.currentCalendar().dateWithEra(1, year: test.from.year, month: test.from.month, day: test.from.day, hour: 0, minute: 0, second: 0, nanosecond: 0)! 
    let to = NSCalendar.currentCalendar().dateWithEra(1, year: test.to.year, month: test.to.month, day: test.to.day, hour: 0, minute: 0, second: 0, nanosecond: 0)! 

    if monthsSince(from, to: to) == test.result { 
     print("Test \(test), Passed!") 
    } else { 
     print("Test \(test), Failed!") 
    } 
}