通过FMDatabase读取和写入NSDate到sqlite数据库

时间:2011-12-28 07:38:27

标签: cocoa-touch cocoa sqlite nsdate fmdb

我怀疑是否可以使用FMDatabase直接存储或从数据库中读取NSDate。

根据我的研究,FMDatabase从记录中读取日期,期望元组为双值。 FMDatabase在此方法中将该double值转换为date:

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

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

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

这种方法的主要问题是,手动输入数据库中的数据的人很难在代码中通过FMDatabase理解。所以有人不能简单地在GUI中输入双倍值的日期。一种方法是使用these functions

之一
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');

我希望将日期存储在following format中的数据库中:

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

并将其作为日期格式存储在数据库中,以便我可以:

  1. 在查询中利用日期比较工具。
  2. 使FMDatabase易于阅读和编写此日期格式。
  3. FMDatabase是否可以直接与这种日期格式进行交互?或者这是FMDatabase的限制,我将不得不扩展FMDatabase类来处理NSDate的读写回写为sqlite日期格式?

    由于

    修改:FMDatabase的作者/版主之一必须说thishttp://code.google.com/p/flycode/issues/detail?id=16#c1

1 个答案:

答案 0 :(得分: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”之类的查询,但在查询日期时查询失败。需要解决方案。