0

FMDatabase を使用して NSDate をデータベースに直接保存したり、データベースから読み取ったりできるかどうかは疑問です。

私の調査によると、FMDatabase はレコードから日付を読み取り、そのタプルがdouble 値であることを期待しています。FMDatabase は、このメソッドでその double 値を日付に変換します。

- (NSDate*) dateForColumn:(NSString*)columnName; {
    int columnIdx = [self columnIndexForName:columnName];

    if (columnIdx == -1) {
        return nil;
    }

    return [NSDate dateWithTimeIntervalSince1970:[self doubleForColumn:columnName]];
}

このアプローチの主な問題は、コード内の FMDatabase が理解できるようにデータベースに手動でデータを入力するのが難しいことです。そのため、GUI で単純に日付を double 値で入力することはできません。1 つのアプローチは、これらの関数のいずれかを使用することです。

date(timestring, modifier, modifier, ...)
time(timestring, modifier, modifier, ...)
datetime(timestring, modifier, modifier, ...)
julianday(timestring, modifier, modifier, ...)
strftime(format, timestring, modifier, modifier, ...)

ただし、ここでもオーバーヘッドは、次のような挿入操作を使用してレコードを入力するたびにクエリを実行することです。

Compute the current date.
SELECT date('now');

Compute the last day of the current month.
SELECT date('now','start of month','+1 month','-1 day');

日付を次の形式でデータベースに保存したいと思います。

TEXT as ISO8601 strings ("YYYY-MM-DD")

そして、データベースに日付形式で保存して、次のことができるようにします。

  1. クエリで日付比較機能を活用します。
  2. この日付形式を読み書きできるように FMDatabase を理解できるようにします。

FMDatabase がこの種の日付形式とやり取りできる直接的な方法はありますか? それとも、これは FMDatabase の制限であり、NSDate の読み書きを sqlite 日付形式に戻すには、FMDatabase クラスを拡張する必要がありますか?

ありがとう

編集: FMDatabase の作成者/モデレーターの 1 人は、それについてこれを言わなければなりませ: http://code.google.com/p/flycode/issues/detail?id=16#c1

4

1 に答える 1

2

YYYY-MM-DD の形式で入力されたデータベースから日付を読み取ります。

FMResultSet クラスを拡張して、次の追加メソッドを含めました。

FMResultSet+Addtion.hファイル:

typedef enum
{
    eText,
    eReal,
    eInteger
}EDateAndTimeDataType;
// Reference: http://www.sqlite.org/datatype3.html

typedef enum
{
    eDateString    // YYYY-MM-DD format
    // Rest is un implemented
}EDateAndTimeFunctionType;
// Refernce: http://www.sqlite.org/lang_datefunc.html

@interface FMResultSet (Additions)

-(NSDate*)dateForColumn:(NSString *)columnName withDataType:(EDateAndTimeDataType)inDateDataType functionType:(EDateAndTimeFunctionType)inFunctionType;
-(NSDate*)dateForColumnIndex:(int)columnIdx withDataType:(EDateAndTimeDataType)inDateDataType functionType:(EDateAndTimeFunctionType)inFunctionType;

@end

FMResultSet+Addition.mファイル:

@implementation FMResultSet (Additions)

-(NSDate*)dateForColumn:(NSString *)columnName withDataType:(EDateAndTimeDataType)inDateDataType functionType:(EDateAndTimeFunctionType)inFunctionType
{
    return [self dateForColumnIndex:[self columnIndexForName:columnName]
                       withDataType:inDateDataType
                       functionType:inFunctionType];
}

-(NSDate*)dateForColumnIndex:(int)columnIdx withDataType:(EDateAndTimeDataType)inDateDataType functionType:(EDateAndTimeFunctionType)inFunctionType
{
    NSAssert (eText==inDateDataType, @"Only Text type is implemented for now");
    NSAssert (eDateString==inFunctionType, @"Only date() function type is implemented for now");

    NSDate *theDate = nil;
    NSString *dateString = [self stringForColumnIndex:columnIdx];
    if (nil!=dateString)
    {
        theDate = [Utility getDateFromString:dateString
                              withDateFormat:@"yyyy-MM-dd"];
        NSLog(@"Date from DB: %@", theDate);
    }
    return theDate;
}

@end

効用:

+(NSDate *)getDateFromString:(NSString *)inString withDateFormat:(NSString*)inDateFormat
{
    NSDate *date =nil;
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
    [dateFormatter setDateFormat:inDateFormat];

    NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
    [dateFormatter setLocale:enUSPOSIXLocale];
    [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
    [enUSPOSIXLocale release];

    date = [dateFormatter dateFromString:inString];
    [dateFormatter release];
    return date;
}

* *編集: これは "select * from table_name" のようなクエリでは機能しますが、日付を比較するクエリでは失敗します。これには解決策が必要です。

于 2011-12-29T18:43:06.310 に答える