我需要从iPhone项目中的UIDatePicker控件中检索午夜过后的小时数。 datePickerMode
设置为UIDatePickerModeTime
,因此用户只能设置时间,不能设置日期。当用户完成并关闭UIDatePicker所在的视图时,可能会检索以下日期(作为示例):
NSDate *returnTime = timePicker.date;
NSLog(@"returnTime: %@", returnTime); // returns for example @"1970-01-01 10:13:00 PM +0000"
如上所述,我正在寻找午夜过后的小时数。在上面的示例中,该值应为22
。我想通过创建一个NSDateFormatter对象并以24小时时钟格式提取一天中的小时来实现这一点,因此使用setDateFormat:@"H"
(大写H而不是'h'):
NSDateFormatter *formatHour = [[NSDateFormatter alloc] init];
[formatHour setDateFormat:@"H"];
NSInteger intHoursPastMidnight = [[formatHour stringFromDate:returnTime] integerValue];
然而,这并不总是按预期工作。当用户在系统范围的首选项中禁用24小时制(即用户使用AM / PM)时,intHoursPastMidnight
将包含10
而不是22
。 10
确实是UIDatePicker
中可见的值,但由于NSDateFormatter
,我原本希望将22
转换为@"H"
。
这里有什么问题?我的转换假设不正确吗?这是UIDatePicker的错误吗?如何解决问题,因此我基本上可以访问UIDatePicker中设置的午夜过后小时数,与用户的12或24小时时钟偏好无关?这还是要走的路吗?
明确的最终目标是检索午夜过后的分钟数(所以小时数* 60 +分钟,价值总是在0和1440之间)。
答案 0 :(得分:22)
您可以使用NSCalendar
。
首先,得到你的约会对象:
NSDate *date = [timePicker date];
接下来,将其转换为date components:
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSIntegerMax fromDate:date];
现在我们重置日期组件的小时和分钟,以便它现在指向午夜:
[components setHour:0];
[components setMinute:0];
[components setSecond:0];
接下来,我们将其转回日期:
NSDate *midnight = [[NSCalendar currentCalendar] dateFromComponents:components];
最后,我们要求午夜和日期之间的小时数:
NSDateComponents *diff = [[NSCalendar currentCalendar] components:NSHourCalendarUnit fromDate:midnight toDate:date options:0];
NSInteger numberOfHoursPastMidnight = [diff hour];
答案 1 :(得分:3)
戴夫的回答是正确的,但它不如下面的例子那样高效。在我的仪器配置文件测试中,我的解决方案速度超过了3倍 - 他的方法在我的测试应用程序中的所有调用所花费的总时间为844毫秒,我的268毫秒。
请记住,我的测试应用程序会迭代一组对象,以计算每个对象的午夜后的分钟数,然后将其用作排序的基础。因此,如果您的代码没有做类似的事情,那么他更易读,更标准的答案可能是更好的选择。
int const MINUTES_IN_HOUR = 60;
int const DAY_IN_MINUTES = 1440;
#define DATE_COMPONENTS (NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekdayCalendarUnit | NSWeekdayOrdinalCalendarUnit)
#define CURRENT_CALENDAR [NSCalendar currentCalendar]
- (NSUInteger)minutesSinceMidnight
{
NSDateComponents *startComponents = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self.startTime];
NSUInteger fromMidnight = [startComponents hour] * MINUTES_IN_HOUR + [startComponents minute];
return fromMidnight;
}