cocoa-touch - 通过FMDatabase读写NSDate到sqlite数据库

标签 cocoa-touch cocoa sqlite nsdate fmdb

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

根据我的研究,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 中输入双值日期。一种方法是使用 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 易于读取和写入此日期格式。

FMDatabase 有没有直接的方法可以与这种日期格式交互?或者这是 FMDatabase 的限制,我必须扩展 FMDatabase 类来处理 NSDate 的读和写回 sqlite 日期格式?

谢谢

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

最佳答案

从数据库中读取日期,以 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”之类的查询,但在比较日期的查询中却失败了。需要解决这个问题。

关于cocoa-touch - 通过FMDatabase读写NSDate到sqlite数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8653171/

相关文章:

objective-c - 什么在子类化 UIViewController 时调用 viewDidLoad?

objective-c - Cocoa 中未调用我的委托(delegate)操作

objective-c - 如何检查 Cocoa 源代码中所有 objective-c 函数的可用性

objective-c - OSX 查找 "Dialog/Pop-up"的名称是什么?

SQLite - 在表 1 上插入触发器以有条件更新表 2

sqlite - 如何在SQLite的日期和时间之间过滤数据

ios - ImageWithRenderingMode AlwaysOriginal 不适用于 UITabBar

objective-c - 当我调整窗口大小时 NSTableView 自动重新加载 如何禁用它

ios - 用于本地化的字符串比较

sqlite - 如何最好地将应用程序从 sqlite(使用 fmdb)迁移到 CoreData?