1

我有一个 NSArray,其中包含以下名称和日期对。注意:日期始终在我的自定义数组的索引 1 中

MyCustomArray: 
(
"Toms Bday"
"2012-01-10"
)
(
"Jesscia Bday"
"2012-01-27"
)
(
"Jills Bday"
"2012-03-03"
)
(
"Joes Bday"
"2012-04-15"
)

我的数组中有数百个名称日期对。因此,对于给定的 StartDate = "2012-01-01" 和 endDate = "2012-01-31" 我只想获得以下记录。我怎么做?

(
    "Toms Bday"
    "2012-01-10"
    )
    (
    "Jesscia Bday"
    "2012-01-27"
    )

我查看了这篇文章为什么不能使用 < 或 > 比较 NSDate?但仍然无法弄清楚。

4

4 回答 4

3

考虑到您的日期格式非常简单,您可以将它们作为字符串进行比较,结果应该是正确的:

NSString *start = @"2012-01-01";
NSString *end = @"2012-01-31";

NSString *date = @"2012-01-10";

if ([start compare:date] == NSOrderedAscending &&
    [end compare:date] == NSOrderedDescending) {
    // Note: might be descending for start and ascending for end, i'm not 100% sure, try both

    // valid date
}
于 2012-12-28T14:56:49.863 回答
1

如果您可以自己决定数据结构(即,它们不是外部要求),那么也许您想考虑将内部数组(可以说是数据集的记录)转换为字典。

将字典用于记录的优势在于 Cocoa 框架提供了存储、过滤和通常连接数据所需的一切。

因此,请允许我提出如下设置:

// For the purposes of this piece of code, a hard coded array of dictionaries: 
NSArray *fullArray = @[
    @{@"desc": @"Toms Bday",    @"bday": [NSDate dateWithString:@"2012-01-10 00:00:00 +00:00"]},
    @{@"desc": @"Jesscia Bday", @"bday": [NSDate dateWithString:@"2012-01-27 00:00:00 +00:00"]}
// etc...
];


// The interval of NSDates that you want to filter
NSDate *intervalBeginning = [NSDate dateWithString:@"2012-01-15 00:00:00 +00:00"];
NSDate *intervalEnd       = [NSDate dateWithString:@"2012-01-31 23:59:59 +00:00"];

// Find the relevant record(s):
NSArray *filteredArray = [fullArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"bday >= %@  and bday <= %@", intervalBeginning, intervalEnd]];

完毕!

于 2012-12-28T15:20:05.867 回答
1

假设entriesNSArrayNSArrays 的NSStrings。

NSDateFormatter * formatter = [NSDateFormatter new];
[formatter setDateFormat:@"yyyy-MM-dd"];

NSString * start = @"2012-01-01";
NSDate * startDate = [formatter dateFromString:start];

NSString * end = @"2012-01-31";
NSDate * endDate = [formatter dateFromString:end];

NSIndexSet * indexes = [entries indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    NSString * dateString = obj[1]; // retrieve the date string
    NSDate * date = [formatter dateFromString:dateString];

    return !([date compare:startDate] == NSOrderedAscending ||
             [date compare:endDate] == NSOrderedDescending);
}];

NSArray * results = [entries objectsAtIndexes:indexes];

我在这里所做的是过滤通过块定义的测试(在开始日期和结束日期之间)的索引,然后创建一个仅包含这些索引的数组。

在此之前,您显然需要使用NSDateFormatter.

我个人更喜欢块而不是谓词,因为我认为它们更容易阅读。

于 2012-12-28T15:26:38.620 回答
0

感谢大家帮助我。这是我的 Kal-Calendar 项目中现在正在运行的代码。我希望这可以帮助任何可能对未来感兴趣的人。虽然回答这篇文章的其他人有更好的通用答案

- (void)loadHolidaysFrom:(NSDate *)fromDate to:(NSDate *)toDate delegate:(id<KalDataSourceCallbacks>)delegate
{
    NSLog(@"Fetching B-Days between %@ and %@...", fromDate, toDate);

    NSDateFormatter *fmt = [[[NSDateFormatter alloc] init] autorelease];
    [fmt setDateFormat:@"yyyy-MM-dd"];


    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"birthdays.plist"];

    //READ IN
    NSMutableArray *arryData = [[NSMutableArray alloc] initWithObjects:nil];
    NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:stringsPlistPath];



    for (id key in dictionary) 
    {
        [arryData addObject:[dictionary objectForKey:key]];
    }


    for (int i=0; i<[arryData count]; i++)
    {

        NSMutableArray *bdayArray = [[NSMutableArray alloc] initWithArray:[arryData objectAtIndex:i]];

        NSString *nameStr = [bdayArray objectAtIndex:0];
        NSString *bdayStr = [bdayArray objectAtIndex:1];

        NSLog(@"nameStr:%@ ... bdayStr:%@ ...", nameStr,bdayStr);


        NSDate *BirthdayDate = [fmt dateFromString:bdayStr];

        if ([fromDate compare:BirthdayDate] == NSOrderedAscending &&
            [toDate compare:BirthdayDate] == NSOrderedDescending) 
        {
            // valid date
            //do something interesting here ... and it does!
        }

    }
于 2012-12-28T15:42:15.380 回答