NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; [gregorian setFirstWeekday:2]; NSDate *fromDate = userInfo.birthDay; NSDate *toDate = [NSDate date]; NSDateComponents *components = [gregorian components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:fromDate toDate:toDate options:0]; NSInteger year = components.year; NSInteger month = components.month; NSInteger day = components.day; if (year > 0) { if (month > 0) { strAge = [NSString stringWithFormat:@"%ld歲%ld個月",(long)year,(long)month]; } else { strAge = [NSString stringWithFormat:@"%ld歲",(long)year]; } } else if (month > 0) { if (day > 0) { strAge = [NSString stringWithFormat:@"%ld個月%ld天",(long)month,(long)day]; } else { strAge = [NSString stringWithFormat:@"%ld個月",(long)month]; } } else { if (day >= 0) { strAge = [NSString stringWithFormat:@"%ld天",(long)day]; } }
計算某人生日,采用這樣的方式,可以有效的避免自己算月份的窘態,反正我不說你也知道,那月份存在28 29 30 31多樣式變化,有系統API,這么棒的爽感。。。
你要是想算時分秒,就把NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay 改為
NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond
若單純想只知道兩個日期相差多少天,就可以只傳遞一個NSCalendarUnitDay即可
這個方法有一個bug,懷疑是系統API的問題,即帶有31號的月份,31號和30號距離同一個時間的天數是一樣的。
比如說fromDate是2016-3-31,toDate是2016-5-9,那么month=1,day = 9
而fromDate是2016-3-30,toDate是2016-5-9,那么month=1,day = 9
經過思考,貌似這個解釋也是合理的,因為3月有30號、31號,4月只有30號,故而3月30號到4月30號,認為是1個月,3月31號到4月30號,也被認為是一個月。
每個月天數的不等,導致會有這樣的詭異事件出現