存储绝对NSDate,而不是相对于时区

Sko*_*ota 6 objective-c nsdate nstimezone nscalendar ios

我正在创建一个iOS应用程序来跟踪出勤率.每个出勤条目存储在具有状态属性(例如,存在,不存在)的对象中,并且NSDate被称为属性的属性date表示该出勤记录被拍摄的日期.当我选择特定日期(使用UIDatePickerView或类似)时,我希望该日期的所有出勤记录(对象)都显示在表格视图中.

虽然原则上听起来很简单,但我遇到了与时区有关的问题.我知道NSDates的存储与时区无关(即它们相对于UTC/GMT +0000存储).这意味着,如果我在悉尼并参加,例如,2012年11月4日星期日,因为日期存储为独立的时区,如果我将我的iPhone/iPad带到不同的时区(如旧金山)所有出席记录会在一天之前转移,在这种情况下会转移到2012年11月3日星期六,因为那是当地时间(实际上是第二天,悉尼当地时间)出席的时刻.

我不希望这种情况发生 - 我希望日期是绝对的.换句话说,如果出席会议是在2012年11月4日星期日举行,那么无论在世界的哪个地方(以及无论哪个时区),我都需要留在那个日期.正如您所看到的,这与日历应用程序形成鲜明对比,在日历应用程序中,预约的时间根据时区而变化是可取的.

任何关于更好地解决这个问题的方法的建议都将受到赞赏.请记住,我选择显示的日期使用a 以时区独立格式UIDatePickerView返回当前NSDate,所以我还需要一种方法来进行简单的比较(最好是NSPredicate因为考勤对象存储在Core Data中)获取该特定日期的所有出勤对象.

Abi*_*ern 6

您是否尝试将时间转换为NSDateComponents?然后,无论时区如何,都可以从中重新创建NSDate.

编辑添加

// This is just so I can create a date from a string.
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];


// Create a date as recorded in a timezone that isn't mine.
NSDate *localDate = [formatter dateFromString:@"2012-10-30 10:30:00 +0200"];
NSLog(@"Initial Date: %@", localDate);
// this logs 2012-10-30 08:30:00 +0000
// Which is what you would expect, as the original time was 2 hours ahead

NSDateComponents *components = [[NSDateComponents alloc] init];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
components = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit fromDate:localDate];

NSLog(@"Components: %@", components);


// Create a date from these time components in some other time zone
[gregorian setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"EST"]];
NSDate *newDate = [gregorian dateFromComponents:components];

NSLog(@"New Date: %@", newDate);
// This logs 2012-10-30 12:30:00 +0000
// Which is the local EST of 8:30 am expressed in UTC
Run Code Online (Sandbox Code Playgroud)

这演示了我如何在+2时区上午8:30进行转换看起来与-4时区相同.