Ios UITableView节中的NSDate不反映UIDatePicker中的日期

Ios UITableView节中的NSDate不反映UIDatePicker中的日期,ios,uitableview,core-data,nsdate,nsfetchedresultscontroller,Ios,Uitableview,Core Data,Nsdate,Nsfetchedresultscontroller,我有一个带有UITableViewController的简单应用程序,该应用程序由用户在另一个视图中填写并从UIDatePicker中选择日期来填充。UITableView的单元格由UITextField中的单词填充,UITableView部分标题表示从UIDatePicker中选择的日期 当用户保存在添加条目视图控制器中时,将保存到核心数据中,NSFetchedResultsController负责更新UITableView 在我的应用程序的早期版本(2.0版)中,我遇到了一个错误,美国时区总

我有一个带有
UITableViewController
的简单应用程序,该应用程序由用户在另一个视图中填写并从
UIDatePicker
中选择日期来填充。
UITableView
单元格
UITextField
中的单词填充,
UITableView
部分标题表示从
UIDatePicker
中选择的日期

当用户保存在
添加条目视图控制器中时,
将保存到
核心数据中,
NSFetchedResultsController
负责更新
UITableView

在我的应用程序的早期版本(2.0版)中,我遇到了一个错误,美国时区总是在
UIDatePicker
中选定日期的前一天显示部分标题。对其他国家来说也不错。NSDate与UTC时区一起存储

我通过将
UIDatePicker
设置为2.1.1版不使用任何时区,实现了一个修复。我原以为已经解决了,但进一步的测试让我发现了其他的bug

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

我有一个
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];

}
我的模型是:
交易实体
日期实体
有关系,
日期事件
NSDate
。我正在将其转换为字符串,以便以所需格式轻松显示为
部分
标题

问题

如果我从新安装的应用程序开始,这将非常有效,并且在
添加入口视图控制器
中,我已将
UIDatePicker
设置为使用GMT时区

但是,如果我从版本2.1.1更新,所有现有*条目的日期都会在
UITableView
标题的
部分中向后移动一个。我的意思是:

如果在版本2.1.1中,我有一个条目是9月17日,一个条目是15日,一个条目是10日(只是日期的一个示例),当我更新到我正在编写的这个新版本时,所有章节标题都会在一个日期前追溯到9月16日、14日和9日。如果单击条目,则
ui日期选择器
将显示它应该是的日期(而不是
部分
标题中显示的日期)。因此,如果我单击第一个条目,
UIDatePicker
会显示第17个条目,而
部分
标题会显示第16个条目

这与时区无关

我真的不知道我需要做什么来确保更新的用户有相同的日期,而新用户也没有问题。为什么每件事都要倒退一天

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

我不明白为什么
dateOfEvent
在23:00是16,而字符串显示为16。我不明白为什么日期会向后移动一个日期

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

请记住,在2.1.1版中,我没有在
部分的
标题的
Transient
属性中使用GMT的代码。这正是我在开发过程中介绍的,因为时区的一些奇怪行为

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

在2.1.1版的Add条目的保存方法中,我执行以下操作:

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];
因此,我为calendar和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];
我正在将NSDATE组件的时区设置为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时区


在此方面的任何帮助都将不胜感激

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

应始终存储未修改的NSDate,并使用NSTimeZone和NSDateFormatter方法向用户显示时间。如果NSLog(@“%@,[NSDate date])显示您意想不到的内容,这是绝对正常的,因为它以UTC显示时间。通过NSDateFormatter显示给用户的文本应该不同


我想说的是,你需要从你正在做的事情中退一步,找出你为现有日期存储了什么。您是否存储了正确的NSDate,还是存储了经过时区调整的NSDate?如果您的新代码同时存储不同的NSDATE,那么显然有些东西无法工作

非常感谢@gnasher729的回复,你的解释真的很有道理。我已经更新了我的问题,以反映存储日期的代码。在2.0版中,我将其存储为UTC。在2.1.1中,我根本没有设置时区(我遇到了一些奇怪的问题,我认为没有设置时区是可行的……但这是导致这个问题的原因),在2.2版(我目前正在处理的版本)中,我将其设置为GMT。问题是从2.1.1到2.2(2.0到2.1.1是可以的)。。由于没有设置时区,我把事情搞砸了。所以看起来,显示给用户的日期就是搞砸的。。将其设置为时区,这与升级时的UIDatePicker有所不同。而且,这很重要