如何使用Objective C在SQLite中获取date时间列

如何在SQLite中使用Objective C获取date时间列?

我有一个包含4个字段的表: pkdatetimevalue1value2pk (主键), value1value2是整数,所以我使用:

  int value1 = sqlite3_column_int(statement, 2); int value1 = sqlite3_column_int(statement, 3); 

但是我应该怎么用datetime

在SQLite中,本身没有date/时间列types,所以最终表示date为Juliandate值(实数列)或string(文本列)。 date在string中的表示方式也很特别,yyyy-MM-dd HH:mm:ss(only)。

这些是我为编写Objective-C的SQLitedate而编写的一些方法。 这些方法在NSDate的一个类中实现。

请务必查看SQLite提供的用于处理Juliandate的function。 我发现这些非常有用( http://www.sqlite.org/lang_datefunc.html )。 代码示例中包含了派生NSDate的JulianDay的函数。

看起来这个主题也包括在这里。 在iPhone应用程序中坚持date到SQLite3

 + (NSDate *) dateWithSQLiteRepresentation: (NSString *) myString; { NSAssert3(myString, @"%s: %d; %s; Invalid argument. myString == nil", __FILE__, __LINE__, __PRETTY_FUNCTION__); return [[self sqlLiteDateFormatter] dateFromString: myString]; } + (NSDate *) dateWithSQLiteRepresentation: (NSString *) myString timeZone: (NSString *) myTimeZone; { NSString * dateWithTimezone = nil; NSDate * result = nil; NSAssert3(myString, @"%s: %d; %s; Invalid argument. myString == nil", __FILE__, __LINE__, __PRETTY_FUNCTION__); NSAssert3(myTimeZone, @"%s: %d; %s; Invalid argument. myTimeZone == nil", __FILE__, __LINE__, __PRETTY_FUNCTION__); dateWithTimezone = [[NSString alloc] initWithFormat: @"%@ %@", myString, myTimeZone]; result = [[self sqlLiteDateFormatterWithTimezone] dateFromString: dateWithTimezone]; [dateWithTimezone release]; return result; } + (NSString *) sqlLiteDateFormat; { return @"yyyy-MM-dd HH:mm:ss"; } + (NSString *) sqlLiteDateFormatWithTimeZone; { static NSString * result = nil; if (!result) { result = [[NSString alloc] initWithFormat: @"%@ zzz", [self sqlLiteDateFormat]]; } return result; } + (NSDateFormatter *) sqlLiteDateFormatter; { static NSDateFormatter * _result = nil; if (!_result) { _result = [[NSDateFormatter alloc] init]; [_result setDateFormat: [self sqlLiteDateFormat]]; } return _result; } + (NSDateFormatter *) sqlLiteDateFormatterWithTimezone; { static NSDateFormatter * _result = nil; if (!_result) { _result = [[NSDateFormatter alloc] init]; [_result setDateFormat: [self sqlLiteDateFormatWithTimeZone]]; } return _result; } - (NSString *) sqlLiteDateRepresentation; { NSString * result = nil; result = [[NSDate sqlLiteDateFormatter] stringFromDate: self]; return result; } - (NSTimeInterval) unixTime; { NSTimeInterval result = [self timeIntervalSince1970]; return result; } #define SECONDS_PER_DAY 86400 #define JULIAN_DAY_OF_ZERO_UNIX_TIME 2440587.5 - (NSTimeInterval) julianDay; { return [self unixTime]/SECONDS_PER_DAY + JULIAN_DAY_OF_ZERO_UNIX_TIME; } + (NSDate *) dateWithJulianDay: (NSTimeInterval) myTimeInterval { NSDate *result = [self dateWithTimeIntervalSince1970: (myTimeInterval - JULIAN_DAY_OF_ZERO_UNIX_TIME) * SECONDS_PER_DAY]; return result; } 

如果可以定义数据库,那么也可以使用REAL(SQLite数据types)作为date时间的types,然后使用sqlite3_column_double()加载它。 这将返回doubletypes的variables。

然后你可以使用[NSDate dateWithTimeIntervalSince1970:double_value]来获得一个NSDate对象。

请注意,上面的类别解决scheme存在一个问题,因为它受到用户设备上的区域设置的限制。 例如,2010年4月5日午夜,sqlLiteDateRepresentation将返回大部分人的机器的2010/04/05 00:00:00,但是我遇到了一个场景,用户的语言环境设置导致相同的function产生“2010/04/05上午12:00:00“,当我的查询使用时不返回任何行。 这似乎从NSDateFormatter的文档:“通常,鼓励您使用格式样式(请参阅timeStyle,dateStyle和NSDateFormatterStyle),而不是使用自定义格式string,因为给定样式的格式反映了用户的偏好。样式也反映了语言环境设置。“ 虽然我没有看到使用timeStyle / dateStyle获取与yyyy / MM / dd HH:mm:ss相同的格式,SQLite似乎需要一个好方法。 我担心你最好的select可能是一个自定义的解决scheme,你确保时间确实是写在24H格式,不允许区域设置导致错误。

如果您只想从SQLite datetime字段获取NSDate,其中dateTime是从数据库返回的字段:

 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; NSDate *date = [dateFormatter dateFromString:dateTime]; 

现在工作!

 NSString *dateValueS = [[NSString alloc] initWithUTF8String:(char*) sqlite3_column_text(statement,2)];