daleijn
daleijn

Reputation: 738

Getting the first date of current quarter

I'm trying to get the first and the last date of current quarter, i'm using it:

NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitQuarter | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];

components.quarter = 1;

funStartDate = [[NSCalendar currentCalendar] dateFromComponents: components];
NSLog(@"First day of quater: %@", funStartDate);

[components setQuarter:[components quarter]+1];

funEndDate = [[NSCalendar currentCalendar] dateFromComponents: components];
NSLog(@"Last day of quater: %@", [funEndDate descriptionWithLocale:[NSLocale currentLocale]]);

But in both console print I see today's date. What I'm doing wrong?

Upvotes: 6

Views: 3553

Answers (2)

Adam Smaka
Adam Smaka

Reputation: 6393

Swift 3.1. Quarter component still not working. Workaround:

extension Date {
    public var startOfQuarter: Date {
        let startOfMonth = Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: Calendar.current.startOfDay(for: self)))!

        var components = Calendar.current.dateComponents([.month, .day, .year], from: startOfMonth)

        let newMonth: Int
        switch components.month! {
        case 1,2,3: newMonth = 1
        case 4,5,6: newMonth = 4
        case 7,8,9: newMonth = 7
        case 10,11,12: newMonth = 10
        default: newMonth = 1
        }
        components.month = newMonth
        return Calendar.current.date(from: components)!
    }
}

Usage:

Date().startOfQuarter

Upvotes: 8

kas-kad
kas-kad

Reputation: 3764

UPDATED: I've found that Apple's bug with quarter unit is still there in iOS 7.1, so avoid using this unit in your date components.

Here I got working solution for you:

first day of a quarter:

    NSDate *date = <whatever>;
    NSCalendar *currentCalendar = [NSCalendar currentCalendar];
    NSDate *startOfQuarter;
    [currentCalendar rangeOfUnit: NSQuarterCalendarUnit
                       startDate: &startOfQuarter
                        interval: NULL
                         forDate: date];
    NSLog(@"quarter starts at %@", startOfQuarter);

last day of a quarter:

    NSDateComponents* comps = [currentCalendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay)
                                                 fromDate:date];
    NSUInteger quartalNum = (comps.month - 1) / 3 + 1;
    NSUInteger lastQuartalMonthNum = quartalNum * 3;
    NSUInteger nextQuartalFirstMonth = lastQuartalMonthNum + 1
    [comps setMonth: nextQuartalFirstMonth];
    [comps setDay: 0]; // with 0 day we get last day of previous month

    NSLog(@"quarter ends at %@",  [currentCalendar dateFromComponents: comps]);

Upvotes: 8

Related Questions