1

就在它完美运行之前的片刻,突然不知道发生了什么并且没有改变任何东西,但它不再工作了尝试了这么多,但无法弄清楚我错过了什么任何帮助对我来说就像天堂一样下面是我的代码

这就是我的日期在我的 sqlite 数据库 01/20/1978 中的样子

       01/20/2013

       02/28/1979


       MM/dd/yyyy


 NSLog(@"Fetching holidays from the database between %@ and %@...", fromDate, toDate);
// fromdate and todate both are nsdate this is what they prints 
// Fetching holidays from the database between 2013-06-29 18:30:00 +0000 and 2013-08-03 18:29:59 +0000...   
    NSDateFormatter *fmt = [[[NSDateFormatter alloc] init] autorelease];



    NSString *query4 = [[NSString alloc] initWithFormat:@"select Birthdates,Names,Profilepic,Email,Phonenumber from PersonNamesAndBirthDates where Birthdates between ? and ?"];


    sqlite3_stmt *stmt4;
    int x4 = sqlite3_prepare_v2(database1,[query4 UTF8String],-1, &stmt4, nil);
    if (x4 == SQLITE_OK)
        [fmt setDateFormat:@"MM/dd/yyyy"];

        sqlite3_bind_text(stmt4, 1, [[fmt stringFromDate:fromDate] UTF8String], -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt4, 2, [[fmt stringFromDate:toDate] UTF8String], -1, SQLITE_STATIC);
    //**IT WAS GOING IN WHILE BUT NOW ITS NOT GOING IN SO IT JUST JUMP FROM HERE**
    while(sqlite3_step(stmt4) == SQLITE_ROW)
    {
        NSString *name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt4, 0)];
        NSString *proPic = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt4, 1)];
        NSString *email = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt4, 2)];
        NSString *pNumber = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt4, 3)];
        NSString *bDate = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt4, 4)];


        [holidays addObject:[Holiday holidayNamed:name email:email profilePic:proPic phoneNumber:pNumber date:[fmt dateFromString:bDate]]];


        NSLog(@"%@",holidays);

    }
    sqlite3_finalize(stmt4);
    NSLog(@"%@",holidays);

    sqlite3_close(database1);
    [delegate loadedDataSource:self];

}

4

2 回答 2

4

格式化程序与您在数据库中使用的内容相匹配,但问题是该格式不会按时间顺序对日期进行排序。SQLite 没有正确的日期数据类型,而是将日期存储为字符串(或数字,但不是真正的“日期”数据类型)。更糟糕的是,由于您当前的字符串值的格式为MM/dd/yyyy,因此它将按字母顺序对它们进行排序,即按月、日、年,而不是按时间顺序。

解决方案是:

  • 浏览您的数据库并将当前存储为 格式的字符串的日期值替换为 格式的MM/dd/yyyy字符串值yyyy-MM-dd

  • 同样,在上面的代码示例中,替换:

    [fmt setDateFormat:@"MM/dd/yyyy"];
    

    [fmt setDateFormat:@"yyyy-MM-dd"];
    

您还可以使用日期和时间函数中列举的一种格式。但是选择一种格式,这样当您按字母顺序排序时,它也可以有效地按时间顺序排序。


虽然您确实应该修复数据库中的数据,但您可以定义一个自定义 SQLite 函数,该函数可以MM/dd/yyyy即时转换yyyy-MM-dd。所以,在你之前@implementation,声明这个新函数:

void convertFromMMDDYYYY(sqlite3_context *context, int argc, sqlite3_value **argv);

然后,在@end你的之后@implementation,实现这个功能:

/*
 convert from MM/dd/yyyy
 to           yyyy-MM-dd
 */
void convertFromMMDDYYYY(sqlite3_context *context, int argc, sqlite3_value **argv)
{
    assert(argc == 1);

    if (sqlite3_value_type(argv[0]) != SQLITE_TEXT) {
        sqlite3_result_null(context);
        return;
    }

    NSString *originalDateString = [NSString stringWithUTF8String:(const char *)sqlite3_value_text(argv[0])];

    static NSDateFormatter *mmddyyyyFormat = nil;
    static NSDateFormatter *yyyymmddFormat = nil;

    // date formatters are a little computationally intensive to create, so let's only do it once

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        mmddyyyyFormat = [[NSDateFormatter alloc] init];
        mmddyyyyFormat.dateFormat = @"MM/dd/yyyy";

        yyyymmddFormat = [[NSDateFormatter alloc] init];
        yyyymmddFormat.dateFormat = @"yyyy-MM-dd";
    });

    NSDate *date = [mmddyyyyFormat dateFromString:originalDateString];
    if (date == nil)
    {
        sqlite3_result_null(context);
        return;
    }

    NSString *resultingDateString = [yyyymmddFormat stringFromDate:date];
    char *buf = sqlite3_malloc(sizeof(char) * [resultingDateString length] + 1);
    strcpy(buf, [resultingDateString UTF8String]);

    sqlite3_result_text(context, buf, -1, sqlite3_free);
}

现在,当您的应用程序打开数据库时,定义一个 SQLite 函数 ,YYYYMMDD它将调用上述例程:

if (sqlite3_create_function_v2(database1, "YYYYMMDD", 1, SQLITE_ANY, NULL, &convertFromMMDDYYYY, NULL, NULL, NULL) != SQLITE_OK)
    NSLog(@"%s: sqlite3_create_function_v2 error: %s", __FUNCTION__, sqlite3_errmsg(database1));

然后你可以改变你的 SQL 来利用这个新的 SQLite 函数:

NSString *query4 = @"select Birthdates,Names,Profilepic,Email,Phonenumber from PersonNamesAndBirthDates where YYYYMMDD(Birthdates) between ? and ?";

而且,当然,由于这是在寻找格式,因此您应该使用该格式来为您在此特定 SQL 语句中yyyy-MM-dd为子句绑定的值:WHERE

sqlite3_stmt *stmt4;
int x4 = sqlite3_prepare_v2(database1,[query4 UTF8String],-1, &stmt4, nil);
if (x4 == SQLITE_OK) {
    [fmt setDateFormat:@"yyyy-MM-dd"];

    // ...
}

同样,最好修复数据,但您可以使用这种自定义函数方法。这是一种非常低效的方法,但应该可以。

于 2013-07-18T13:25:09.980 回答
0

You must use one of the supported date/time formats for comparisons to work correctly.

于 2013-07-18T12:50:17.233 回答