我正在创建一个包含时间表功能的应用,允许用户指定特定日期的时段(例如,时段1从9:00到10:00;时段2从10:00到11:00,等等)。由于应用程序由Core Data支持,因此将句点存储为具有两个NSDate
属性的核心数据管理对象似乎是明智的:startTime
和endTime
。
假设句点不能跨越多天,NSDate
个对象中的日期无关紧要 - 我只对时间感兴趣。虽然一种方法是简单地使用NSDateComponents
来提取时间(并忽略日期),如果我正在对NSDate
个对象进行比较,或者根据这些对象进行排序,那么如果日期不同那么会影响比较或排序。我认为解决此问题的一种方法是手动将startTime
和endTime
属性设置为具有相同(任意)选择的日期。这是围绕这个问题的最好方法吗?
此外,时间(即NSDate
个对象)需要与时区无关。如果用户从说澳大利亚旅行到美国,那么我不希望所有时间现在都显示他们在半夜上课!补偿时区变化与此应用程序无关,因此无论时区如何,我都希望时间保持静止。我也很感激这方面的建议。
提前感谢您的任何帮助!
答案 0 :(得分:2)
如果您不需要“日期”,我建议您根本不使用NSDate,否则您将遇到各种问题。正如评论中所述,NSDate不是时区感知,这意味着您将进行大量不必要的转换,以确保您的应用程序适用于所有时区。
我也可以使用这种方法来保存午夜以来的秒数,或者从午夜开始有两个小时和分钟的字段。这基本上是当地时间,总是如此。
要从UIDatePicker获取此信息,您必须将NSDate转换为NSDateComponents
- (IBAction)datePickerChanged:(UIDatePicker *)sender {
NSDate *date = sender.date;
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
calendar.timeZone = sender.timeZone;
NSDateComponents *components = [calendar components:NSHourCalendarUnit|NSMinuteCalendarUnit fromDate:date];
NSInteger hours = components.hour;
NSInteger minutes = components.minute;
NSLog(@"%02ld:%02ld", (long)hours, (long)minutes);
NSInteger secondsSinceMidnight = hours * (60*60) + minutes * 60;
// save to core data
}
如果你想在datePicker中显示你的时间,你必须采取相反的方式,你必须从保存的组件创建一个NSDate(由于时区原因恰好是今天)。 e.g:
// get from core data
NSInteger secondsSinceMidnight = 8 * (60*60) + 30 * 60;
NSInteger minutes = (secondsSinceMidnight / 60) % 60;
NSInteger hours = (secondsSinceMidnight / 3600);
NSLog(@"%02ld:%02ld", (long)hours, (long)minutes);
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
calendar.timeZone = datePicker.timeZone;
// use today as day, to avoid timezone issues
NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]];
components.hour = hours;
components.minute = minutes;
datePicker.date = [calendar dateFromComponents:components];