UITableView部分中的NSDates不反映UIDatePicker中的日期

时间:2014-09-17 12:28:19

标签: ios uitableview core-data nsdate nsfetchedresultscontroller

我有一个UITableViewController的简单应用程序,用户填写并在另一个视图中选择UIDatePicker的日期来填充。 cells的{​​{1}}填充了UITableView中的字词,UITextField UITableView标题代表section中的所选日期。

当用户保存在UIDatePicker时,它会保存到Add Entry View Controller,Core Data负责更新NSFetchedResultsController

在我的应用程序的早期版本(版本2.0)中,我遇到了一个错误,即美国时区总是会在UITableView所选日期之前的一天显示该部分标题。对其他国家来说没问题。 NSDate使用UTC时区存储。

我通过将UIDatePicker设置为不使用版本2.1.1的任何时区来实现修复。我认为修复它,但进一步测试让我发现其他错误。

我现在正试图解决这个问题。

我有以下部分标题的UIDatePicker属性:

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 EntitydatesOfEvent。我将其转换为字符串,因此可以使用NSDate标题以我想要的格式轻松显示。

问题

如果我从我的应用程序的新安装开始,这非常有效,在section中,我已将Add Entry View Controller设置为使用GMT时区。

但是,如果我从版本2.1.1更新,我的所有EXISTING *条目的日期都会在UIDatePicker的{​​{1}}标题中向后移动一个。我的意思是:

如果我在9月17日有一个条目,在2.1.1版本中有一个第15个条目和第10个条目(仅仅是一个日期示例),当我更新到我正在工作的这个新版本时所有章节标题都可以追溯到9月16日,9月14日和9月。如果我点击该条目,section将显示它应该是的日期(而不是UITableView标题中显示的日期)。因此,如果我点击第一个条目,UIDatePicker会向我显示第17个,但section标题会显示第16个。

这与时区无关。

我不确定我需要做些什么来确保更新的用户具有相同的日期,新用户也不会遇到问题。为什么一切都要追溯到一个日期?

更新后运行应用程序时,NSLogs输出显示: [交易] self.dates.dateOfEvent = 2014-09-16 23:00:00 +0000的NSDate [交易] NSDate转换为字符串= 2014年9月16日

我不明白为什么UIDatePicker在23:00时排名第16,字符串显示为第16位。我不明白为什么日期会追溯到一个日期。

*现有:我清楚地标记了这一点,因为更新版本中的新条目工作正常,但现有条目是其日期在章节标题中移回的条目。

请注意,对于版本2.1.1,我没有代码在section标题的dateOfEvent属性中使用GMT。这是我在开发过程中引入的一些东西,这是由于时区的一些奇怪行为造成的。

更新:显示日期的存储方式

在Add Entry的保存方法中,在2.1.1版中,我这样做:

Transient

所以,我已经为日历和NSDateComponents添加了localTimeZone,但是我在2.1.1的发布版本中注释了代码。

在2.0版中,我有:

section

我将NSDateComponents的时区设置为UTC。

在2.2版本(我正在处理的版本)中,我设置了这个:

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];

我将此设置为GMT时区。

对此有任何帮助真的很感激。

1 个答案:

答案 0 :(得分:1)

NSDate包含UTC的时间点(大致是格林威治标准时间,没有夏令时)。它没有时区信息。如果我们同时看看我们的手表,我们可能会看到不同的时间,因为我们在不同的位置。但是如果我们的应用程序同时调用[NSDate日期],我们会看到相同的结果。

您应始终将NSDate保存为未修改的,并使用NSTimeZone和NSDateFormatter方法向用户显示时间。如果NSLog(@"%@",[NSDate date]))显示对您来说意外的事情,这是绝对正常的,因为它以UTC显示时间。通过NSDateFormatter向用户显示的文本应该不同。

我说你需要退出你正在做的事情,并找出你现在存储的确切日期。您是否存储了正确的NSDate,或者您是否以某种方式调整了时区?如果你的新代码同时存储不同的NSDates,那么显然有些东西是行不通的。