通过 FMDatabase 读写 NSDate 到 sqlite 数据库

Posted

技术标签:

【中文标题】通过 FMDatabase 读写 NSDate 到 sqlite 数据库【英文标题】:Read and Write NSDate to sqlite database through FMDatabase 【发布时间】:2011-12-28 07:38:26 【问题描述】:

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

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

- (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")

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

    在查询中利用日期比较工具。 使 FMDatabase 易于读取和写入此日期格式。

FMDatabase 有什么直接的方式可以与这种日期格式进行交互吗?或者这是 FMDatabase 的限制,我将不得不扩展 FMDatabase 类来处理 NSDate 到 sqlite 日期格式的读写?

谢谢

编辑:其中一位FMDatabase的作者/版主不得不说this:http://code.google.com/p/flycode/issues/detail?id=16#c1

【问题讨论】:

【参考方案1】:

从数据库中读取日期,格式为 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;

**Edit:虽然这适用于“select * from table_name”之类的查询,但在比较日期的查询中会失败。需要解决方案。

【讨论】:

以上是关于通过 FMDatabase 读写 NSDate 到 sqlite 数据库的主要内容,如果未能解决你的问题,请参考以下文章

我如何将 FMDatabase 存储到 iCloud

FMDatabase + swift + 带有未定义参数数量的请求

可能的 FMDatabase/FMResultSet 错误

Fmdatabase 选择日期

通过 NSDate 对元素进行排序并添加到 UITableView

未处理异常:DatabaseException(Error Domain=FMDatabase Code=26 "file is not a database"。更新到 Flutt