2009-08-25 36 views
5

我創建可可的報告生成器,我需要製作方便的日期範圍,如「今天」,「本週」,「這個月」,「今年」,等等。如何根據給定的NSDate生成方便的日期範圍?

是否有好辦法做到這一點?這裏是我的骨架迄今:

@interface DateRange : NSObject 
{ 
    NSDate startDate; 
    NSDate endDate; 
} 

@property (nonatomic, retain) NSDate * startDate; 
@property (nonatomic, retain) NSDate * endDate; 

+ (DateRange *)rangeForDayContainingDate:(NSDate *)date; 
+ (DateRange *)rangeForWeekContainingDate:(NSDate *)date; 
+ (DateRange *)rangeForMonthContainingDate:(NSDate *)date; 
+ (DateRange *)rangeForYearContainingDate:(NSDate *)date; 

@end 

一些示例用例將如下所示:

DateRange * thisWeek = [DateRange rangeForWeekContainingDate:[NSDate date]]; 
DateRange * thisYear = [DateRange rangeForYearContainingDate:[NSDate date]]; 

從本質上講,我想返回DateRange對象包含一週的開始和結束日期,月或目標日期周圍的一年。例如(在僞代碼):

NSDate * today = [August 25, 2009]; 
DateRange * thisWeek = [DateRange rangeForWeekContainingDate:today]; 
assert(thisWeek.startDate == [August 23, 3009]); 
assert(thisWeek.endDate == [August 29, 3009]); 

更新:

我能得到這個工作,感謝answer provided by Kendall Helmstetter Geln。這裏是一個星期的範圍完整的方法:

+ (DateRange *)rangeForWeekContainingDate:(NSDate *)date 
{ 
    DateRange * range = [[self alloc] init]; 

    // start of the week 
    NSDate * firstDay; 
    [[self calendar] rangeOfUnit:NSWeekCalendarUnit 
         startDate:&firstDay 
         interval:0 
         forDate:date]; 
    [range setStartDate:firstDay]; 

    // end of the week 
    NSDateComponents * oneWeek = [[NSDateComponents alloc] init]; 
    [oneWeek setWeek:1]; 
    [range setEndDate:[[self calendar] dateByAddingComponents:oneWeek 
                 toDate:firstDay 
                 options:0]]; 
    [oneWeek release]; 

    return [range autorelease]; 
} 
+2

有一件事你可能想在您的解決方案改變是有'[[自我ALLOC ] init]'而不是'[[DateRange alloc ...',這樣子類也會自己分配,而不是總是使用DateRange,它可能是它們的超類。 – jbrennan 2009-08-25 21:53:09

+1

@ jbrennan:好點。我改變了它。 – 2009-08-25 23:56:56

回答

2

好,因爲一個時間間隔爲秒,只是做數學題,找出多少秒一天:

60秒*60分鐘* 24小時= 1天。

然後在您的rangeForDayContainingDate方法中,您可以提取日期組件,獲取當前日期,基於時間和分鐘設置爲0:00的日期創建新日期,並創建結束日期,將時間間隔添加爲計算的以上。

+0

+1看起來很有希望。日期組件可能正是我所需要的。 – 2009-08-25 21:06:31

+0

謝謝,先生!你的回答指出我的方向是正確的。作爲對原始問題的修改,我已發佈了單週範圍的完整解決方案。 – 2009-08-25 21:46:30

+0

不客氣,請隨時將自己的答案標記爲實際的解決方案,而不是我粗略的方向......我不會被冒犯。 – 2009-08-26 18:13:44

8

爲了完整起見,這裏是我的最終解決方案(與感謝肯德爾黑爾姆施泰特Geln和jbrennan):

+ (NSCalendar *)calendar 
{ 
    NSCalendar * gregorian = [[NSCalendar alloc] 
           initWithCalendarIdentifier:NSGregorianCalendar]; 
    return [gregorian autorelease]; 
} 

//////////////////////////////////////////////////////////////// 

+ (NSDateComponents *)singleComponentOfUnit:(NSCalendarUnit)unit 
{ 
    NSDateComponents * component = [[NSDateComponents alloc] init]; 

    switch (unit) 
    { 
     case NSDayCalendarUnit: [component setDay:1]; break; 
     case NSWeekCalendarUnit: [component setWeek:1]; break; 
     case NSMonthCalendarUnit: [component setMonth:1]; break; 
     case NSYearCalendarUnit: [component setYear:1]; break; 
    } 

    return [component autorelease]; 
} 

//////////////////////////////////////////////////////////////// 

+ (WM_DateRange *)rangeForUnit:(NSCalendarUnit)unit 
       surroundingDate:(NSDate *)date 
{ 
    WM_DateRange * range = [[self alloc] init]; 

    // start of the period 
    NSDate * firstDay; 
    [[self calendar] rangeOfUnit:unit 
         startDate:&firstDay 
         interval:0 
         forDate:date]; 
    [range setStartDate:firstDay]; 

    // end of the period 
    [range setEndDate:[[self calendar] 
     dateByAddingComponents:[self singleComponentOfUnit:unit] 
         toDate:firstDay 
         options:0]]; 

    return [range autorelease]; 
} 

//////////////////////////////////////////////////////////////// 

+ (WM_DateRange *)rangeForDayContainingDate:(NSDate *)date 
{ return [self rangeForUnit:NSDayCalendarUnit surroundingDate:date]; } 

+ (WM_DateRange *)rangeForWeekContainingDate:(NSDate *)date 
{ return [self rangeForUnit:NSWeekCalendarUnit surroundingDate:date]; } 

+ (WM_DateRange *)rangeForMonthContainingDate:(NSDate *)date 
{ return [self rangeForUnit:NSMonthCalendarUnit surroundingDate:date]; } 

+ (WM_DateRange *)rangeForYearContainingDate:(NSDate *)date 
{ return [self rangeForUnit:NSYearCalendarUnit surroundingDate:date]; } 

//////////////////////////////////////////////////////////////// 

- (void)dealloc 
{ 
    [endDate release]; 
    [startDate release]; 
    [super dealloc]; 
} 
+0

這對我正在開發的一個項目幫助很大 - 感謝您發佈您的最終答案! – Jim 2011-09-21 22:09:32