2012-04-06 10 views
0

Ich suche nach einem einfachen, aber effizienten Objective-C-Algorithmus, der ab einem bestimmten Vierteljahr (3 Monate) eine bestimmte Anzahl von Quartalen addiert oder subtrahiert.Datumsberechnungen nach Quartal

Zum Beispiel, Hinzufügen von 10 Quartalen zu Q1 von 2012, bekomme ich das Jahr: 2012 + Floor (10/4) = 2012 + 2 = 2014, dann das Viertel: 1 + Mod (10, 4) = 1 + 2 = Q3. Subtrahiert 2 Quartale von Q3 2011, möchte ich mit Q1 von 2011 enden.

Was wäre der eleganteste Code, um dies zu erreichen?

+0

Sind Sie beginnen mit einem bestimmten Datum, oder wie Ihre Daten gespeichert? Wenn es sich um ein bestimmtes Datum handelt, möchten Sie den Beginn des Quartals, den Sie berechnen, oder einfach drei Monatszeiträume zu dem Datum hinzufügen, mit dem Sie beginnen? – lnafziger

+0

Das Datum wird als zwei int (eins für das Quartal, 1..4) und eins für das Jahr (2000..2012) gespeichert. So habe ich angefangen, aber mein Algorithmus ist noch nicht fertig: 'const int periodsInYear = 4; // 4 Quartale in einem Jahr' 'int yearsToAdd = floor (periodsToAdd/periodsInYear); // nehme nur den ganzzahligen Teil des Ergebnisses, d. h. 10 Viertel/4 = 2,5, floor = 2 ' 'int periodsInYearToAdd = fmod (periodsToAdd, periodsInYear); // ie 10 viertel, 10 mod 4 = 2' – AlexR

Antwort

1
- (void)addQuarters:(NSInteger)quarters toYear:(NSInteger *)currentYear andQuarter:(NSInteger *)currentQuarter { 
    if (*currentYear < 0 || 
     *currentQuarter < 1 || 
     *currentQuarter > 4) { 
     return; 
    } 

    *currentYear += quarters/4; 
    *currentQuarter += quarters % 4; 

    if (*currentQuarter > 4) { 
     *currentQuarter -= 4; 
     *currentYear += 1; 
    } else if (*currentQuarter < 1) { 
     *currentQuarter += 4; 
     *currentYear -= 1; 
    } 
} 

// Example of use: 
NSInteger year = 2012; 
NSInteger quarter = 2; 

[self addQuarters:-7 toYear:&year andQuarter:&quarter]; 
NSLog(@"Quarter %i of %i", quarter, year); 
// Output: Quarter 3 of 2010 
+0

Beachten Sie, dass floor nicht benötigt wird, da in C (und Objective-C) Integer-Division immer den Rest abschneidet (rundet). – lnafziger

3

-Code von hier geändert:

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/DatesAndTimes/Articles/dtCalendricalCalculations.html#//apple_ref/doc/uid/TP40007836-SW1

NSDate *today = [[NSDate alloc] init]; 
NSCalendar *gregorian = [[NSCalendar alloc] 
      initWithCalendarIdentifier:NSGregorianCalendar]; 
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init]; 

[offsetComponents setMonth:3]; // one quarter 

NSDate *oneQuarterFromToday = [gregorian dateByAddingComponents:offsetComponents 
      toDate:today options:0]; 
+0

Könnte es sinnvoller sein, '[NSCalendar currentCalendar] 'anstelle des generischen' NSGregorianCalendar' zu verwenden, da Kalender eine Zeitzone haben und genau wie weit entfernt drei Monate davon entfernt sein können ob in deiner Region die Sommerzeit berücksichtigt wird? Ich bin wahrscheinlich zu empfindlich. – Tommy

+0

Dies wird nicht funktionieren, weil heute zwischen den Quartalen sein kann. Sie können nicht einfach 3 Monate zu einem beliebigen Monat im Jahr hinzufügen und erwarten, dass es ein Viertel ist. – Andy

Verwandte Themen