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/yyyyyyyy-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);
}

YYYYMMDDここで、アプリがデータベースを開くときに、上記のルーチンを呼び出すSQLite 関数 を定義します。

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 に答える