【发布时间】:2014-09-17 12:28:18
【问题描述】:
我有一个带有UITableViewController 的简单应用程序,它由用户填写a 并在不同的视图中从UIDatePicker 中选择一个日期。 UITableView 的 cells 填充有来自 UITextField 的词,而 UITableView section 标题表示来自 UIDatePicker 的选定日期。
当用户保存在Add Entry View Controller, 中时,它会保存到Core Data 并且NSFetchedResultsController 负责更新UITableView。
在我的应用程序的早期版本(2.0 版)中,我遇到了一个错误,即美国时区总是将部分标题显示为UIDatePicker 中所选日期的前一天。对其他国家来说很好。 NSDate 与 UTC 时区一起存储。
我通过将UIDatePicker 设置为不使用版本 2.1.1 的任何时区来实施修复。我认为已经修复了它,但进一步的测试使我发现了其他错误。
我现在正在尝试解决这个问题。
我有一个Transient 属性,用于部分标题如下:
-(NSString *)sectionDateFormatter
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"d MMMM yyyy"];
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
NSDate *thisDate = self.dates.dateOfEvent;
NSString *stringDate = [dateFormatter stringFromDate:self.dates.dateOfEvent];
NSLog(@"[Transaction] The NSDate of self.dates.dateOfEvent = %@", thisDate);
NSLog(@"[Transaction] The NSDate converted into a string = %@", stringDate);
return [dateFormatter stringFromDate:self.dates.dateOfEvent];
}
我的模型是:Transaction Entity 与 Dates Entity 有关系,datesOfEvent 是 NSDate。我将其转换为字符串,以便以我想要的格式轻松显示为section 标题。
问题
如果我从新安装我的应用程序开始,这会非常有效,并且在 Add Entry View Controller 中,我已将 UIDatePicker 设置为也使用 GMT 时区。
但是,如果我从版本 2.1.1 更新,我的所有 EXISTING* 条目的日期都会在 UITableView 的 section 标题中后移一位。我的意思是:
如果我在 2.1.1 版中有 1 个 9 月 17 日的条目、15 日的一个条目和 10 日的一个条目(只是日期的一个例子),当我更新到我正在开发的这个新版本时,所有章节标题都可以追溯到 9 月 16 日、9 月 14 日和 9 月 9 日。如果我单击该条目,UIDatePicker 将显示它应该是的日期(而不是 section 标题中显示的日期)。因此,如果我单击第一个条目,UIDatePicker 会显示第 17 个,但 section 标题会显示第 16 个。
这与时区无关。
我不确定我需要做些什么来确保更新的用户有相同的日期,并且新用户也没有问题。为什么一切都往前追溯?
当我在更新后运行应用程序时,NSLogs 输出显示: [交易] self.dates.dateOfEvent 的 NSDate = 2014-09-16 23:00:00 +0000 [Transaction] NSDate 转成字符串 = 16 September 2014
我不明白为什么dateOfEvent 在 23:00 是第 16 位,而字符串显示的是第 16 位。我不明白为什么日期会向后移动。
*EXISTING:我已经清楚地标记了这一点,因为更新版本中的新条目可以正常工作,但现有条目是它们的日期在章节标题中移回的条目。
请记住,在 2.1.1 版中,我没有在 Transient 属性中为 section 标题使用 GMT 的代码。由于时区的一些奇怪行为,这只是我现在在开发过程中介绍的内容。
更新:显示日期的存储方式
在添加条目的保存方法中,在 2.1.1 版本中,我这样做:
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
//cal.timeZone = [NSTimeZone localTimeZone];
NSDateComponents *components = [cal components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
fromDate:self.datePicker.date];
//[components setTimeZone:[NSTimeZone localTimeZone]];
NSDate *selectedDate = [cal dateFromComponents:components];
// Call the date category and check whether the value exists; if it does return, etc.
Date *date = (Date *)[Date occasionWithDate:selectedDate inManagedObjectContext:context];
所以,我已经为日历和 NSDateComponents 输入了 localTimeZone,但是我在发布的 2.1.1 版本中注释掉了代码。
在 2.0 版中,我有:
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [cal components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
fromDate:self.datePicker.date];
[components setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
NSDate *selectedDate = [cal dateFromComponents:components];
// Call the date category and check whether the value exists; if it does return, etc.
Date *date = (Date *)[Date occasionWithDate:selectedDate inManagedObjectContext:context];
我将 NSDateComponents 的时区设置为 UTC。
在 2.2 版(我正在开发的版本)中,我正在设置:
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [cal components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
fromDate:self.datePicker.date];
self.datePicker.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
components.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
NSDate *selectedDate = [cal dateFromComponents:components];
// Call the date category and check whether the value exists; if it does return, etc.
Date *date = (Date *)[Date occasionWithDate:selectedDate inManagedObjectContext:context];
我将其设置为 GMT 时区。
对此的任何帮助将不胜感激。
【问题讨论】:
标签: ios uitableview core-data nsdate nsfetchedresultscontroller