【问题标题】:Issues converting DATETIME using SQLITE3 and Objective C使用 SQLITE3 和 Objective C 转换 DATETIME 的问题
【发布时间】:2013-01-13 16:28:09
【问题描述】:

我有一个 sqlite3 数据库,它的 DATETIME 列包含如下格式的值:
2013-01-09 04:00:00

我想弄清楚如何确定时间是上午还是下午?

以下是我使用 Objective-C 从我的 Sqlite3 DB 读取和转换 DATETIME 对象的方法:

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
char *DateTimeColumn = (char *)sqlite3_column_text(statement, 13);
NSDate *myDate =[dateFormat dateFromString:[NSString stringWithUTF8String:DateTimeColumn]];

这非常有效,只是它无法确定这是凌晨 4:00 还是下午 4:00。

我看到一个帖子建议在格式化程序字符串的末尾添加一个a,如下所示:
"yyyy-MM-dd hh:mm:ss a"
...找出上午/下午 - 但这会导致崩溃。 (当然,我还在 DATETIME 列的实际值中添加了 AMPM,如下所示:
2013-01-09 04:00:00 AM
但它仍然崩溃了。

不确定我是否做错了什么 - 或者这是否无法完成。

是使数据库本身中的条目全部在 24 小时内的唯一解决方案。格式(意思是:下午 4:00 应该输入为 16:00) - 然后使用IF 语句从 > 12 的值中减去 12 以确定时间的上午或下午?
我原以为会有一些自动化功能……有什么想法吗?

==================================

编辑/更新:
将字符串转换为 NSDate 后,我突然得到一个“(null)”。这是当前版本的代码:

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
char *DateTimeColumn = (char *)sqlite3_column_text(statement, 13);
NSString *DateTimeString = [NSString stringWithUTF8String:DateTimeColumn];
NSLog(@"DateTimeString = %@", DateTimeString);
   // This NSLog gives me a good string: "DateTimeString = 2013-01-09 16:00:00"
// But when I create an NSDate object from this string:
NSDate *myDate =[dateFormat dateFromString:DateTimeString];
// ... and log it out: 
NSLog(@"the REAL DATETIME object = %@", [myDate description]);
// the console shows: "the REAL DATETIME object = (null)"
// and when I add this NSDate object to my Array of NSDates, I crash:
[tempNSDateObjectsArray addObject:myDate];

Console shows: 
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',     
reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:

【问题讨论】:

  • 嗯,什么崩溃了?这应该不会崩溃,最多返回nil。大概您的代码中还有其他错误。
  • 是的,我只是 NSLogging 一些东西——出于某种原因,我突然得到了一个 NULL 对象。创建我的 NSDate 对象后,我将它添加到一个数组中,我得到了这个:*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil' 我将在顶部编辑问题以获取更多详细信息...

标签: iphone datetime sqlite nsdate


【解决方案1】:

HH,而不是hh,用于 24 小时日期格式:

[dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

将“2013-01-09 16:00:00”与 hh 解析为小时格式失败,因此返回 nil

请注意,NSDateFormatter 根据本地时区解释日期字符串,除非您设置了明确的时区。您可能希望将时区信息添加到字符串中,或​​使用不同的格式(例如 UNIX 时间,自 1.1.1970 以来的秒数)来存储日期。


添加: SQLite datetime() 函数返回一个字符串“YYYY-MM-DD HH:MM:SS”,它是UTC/GMT 的日期和时间。要将此类字符串转换为 NSDate,请使用 NSDateFormatter 并将时区设置为 GMT:

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
[dateFormat setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

NSString *dateTimeString = @"2013-01-09 16:00:00";
NSLog(@"DateTimeString = %@", dateTimeString);

NSDate *myDate =[dateFormat dateFromString:dateTimeString];
NSLog(@"myDate:          %@", myDate);

输出:

dateTimeString = 2013-01-09 16:00:00
myDate:        = 2013-01-09 16:00:00 +0000

向用户显示日期,请将NSDate 转换为NSString,使用stringFromDate,但不要设置时区(以便使用本地时区):

NSDateFormatter *dateFormat2 = [[NSDateFormatter alloc] init];
[dateFormat2 setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

NSString *localDateString = [dateFormat2 stringFromDate:myDate];
NSLog(@"localDateString: %@", localDateString);

输出:

localDateString: 2013-01-09 17:00:00

时间现在显示为17:00:00,因为我的本地时区是“GMT+01”。

【讨论】:

  • 你是对的 - 这解决了我的崩溃问题 :-) 但现在我的时间很奇怪 - 它似乎增加了 6 小时。我所有的时间。显然,我们在这里处理时区。那么你如何解决那个? :-)
  • @sirab333:另请注意,NSDate 的 NSLog() 始终显示 GMT 日期,而不是您的时区。
  • 好的,很高兴知道。等等,你是说如果我取出同一个 NSDate 对象并 NSLog 将其取出并同时显示在标签中 - 我会得到不同的输出?
  • @sirab333。没有。NSDate 是一个没有任何时区信息的时间点。打印[myDate description]仅对调试有用,因为它始终以 GMT 显示日期。要向用户显示日期,您必须使用 -[NSDateFormatter stringFromDate:]´ 将日期转换为字符串。
  • 明白了。有关如何获取 NSDate 并将其格式转换为各种时区的任何示例?
【解决方案2】:

24 小时格式是唯一在 SQLite 日期字段中有效的格式。

请注意,数据库中的字符串并不打算直接显示给用户;为用户的时区和格式偏好修改它们是应用程序的工作。

【讨论】:

    猜你喜欢
    • 2011-09-26
    • 2017-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多