Чтение и запись NSDate в базу данных sqlite через FMDatabase - PullRequest
0 голосов
/ 28 декабря 2011

У меня есть сомнения, может ли NSDate быть напрямую сохранен или прочитан из базы данных с использованием FMDatabase или нет.

Согласно моему исследованию, FMDatabase считывает дату из записи, ожидая, что кортеж будет двойным значением.FMDatabase преобразует это двойное значение к дате в этом методе:

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

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

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

Основная проблема с этим подходом состоит в том, что человеку, который вручную вводит данные в базу данных, будет трудно, чтобы его могли понятьFMDatabase в коде.Поэтому кто-то не может просто ввести дату в двойном значении в графическом интерфейсе.Один из подходов состоит в том, чтобы использовать одну из этих функций

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, и мне придется расширить класс FMDatabase для обработки чтения и записи NSDate в формате даты sqlite?

Спасибо

Редактировать: Один из авторов / модераторов FMDatabase должен сказать это об этом: http://code.google.com/p/flycode/issues/detail?id=16#c1

1 Ответ

2 голосов
/ 29 декабря 2011

Чтение даты из базы данных, которая вводится в формате ГГГГ-ММ-ДД.

Я расширил класс 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;
}

** Редактировать : Хотя это работает для запросов типа «выбрать * из таблицы», оно не выполняется в запросах, сравнивающих даты.Нужны решения для этого.

...