تحديد عدد الأشهر بين تاريخين باستخدام الكاكاو

StackOverflow https://stackoverflow.com/questions/1489436

سؤال

كيف يمكنني حساب عدد الأشهر بين تاريخين باستخدام الكاكاو؟

شكرا، ستان

هل كانت مفيدة؟

المحلول

انظر إلى Nscalendars. المكونات: fromdate: ToDate: خيارات طريقة. يتيح لك طرح التواريخ ثم استخراج قيمة الممتلكات بالأشهر

نصائح أخرى

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

للحصول على إجابة تتضمن جزء بسيط من شهر يمكن استخدام ما يلي:

- (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 يناير إلى 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!")
    }
}

المكونات: fromdate: ToDate: لا تعمل الخيارات بشكل صحيح على سبيل المثال التالي:

تاريخ البدء: Jan 01، 2012 تاريخ الانتهاء: 31 مارس 2012.

عدد الأشهر التي تستخدم الطريقة أعلاه = 2

يجب أن تكون الإجابة الصحيحة 3 أشهر.

أنا أستخدم الطريق الطويل للحسابات على النحو التالي: 1. ابحث عن عدد الأيام في الشهر البداية. أضفها إلى جزء الكسر من الشهر. إذا كان التاريخ الأول هو بداية الشهر، عدها شهر كامل. 2. العثور على عدد الأيام في الشهر النهائي. أضفها إلى جزء الكسر من شهر Month التاريخ هو الأخير من الشهر عدها شهر كامل. 3. ابحث عن أشهر / كاملة بين التواريخ 2 وأضف إلى الجزء الأمثل من الشهر. 4. إضافة أجزاء عدد صحيح والكسر من الأشهر للحصول على قيمة صحيحة.

فيما يلي إصدار الهدف من Eleiocs الإجابة المحدثة ل IOS11:

- (NSInteger)monthsSince:(NSDate *)from to:(NSDate *)to {
    NSDateComponents *fromComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:from];
    NSDateComponents *toComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:to];

    return ((toComponents.year - fromComponents.year) * 12) + (toComponents.month - fromComponents.month);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top