cocoa - 如何根据给定的 NSDate 生成方便的日期范围?

标签 cocoa nsdate

我正在 Cocoa 中创建一个报告生成器,我需要生成方便的日期范围,例如“今天”、“本周”、“本月”、“今年”等。

有什么好的方法吗?到目前为止,这是我的骨架:

@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];
}

最佳答案

为了完整起见,这是我的最终解决方案(感谢 Kendall Helmstetter 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];
}

关于cocoa - 如何根据给定的 NSDate 生成方便的日期范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1330798/

相关文章:

objective-c - 如何在 NSUserDefaults 中存储多个 NSMutableDictionary

crash - 使用NSUserDefaults导致timeIntervalSince1970崩溃

iphone - iOS获得与用户设置时间无关的绝对时间?

ios - NSDate 作为 Swift 中的函数参数

cocoa - 使用 Cocoa 和 Core Data 自动保存

xcode - 无法在 OSX 10.8 以下设置部署目标(错误 : dyld: Library not loaded -- Reason: Incompatible library version)

objective-c - 文本转语音快捷方式如何读取任何突出显示的文本?

ios - NSDate 不是 Objective-C 对象?

arrays - append NSDate 类型的值不起作用

swift - 以编程方式更改 Mac 光标速度