如何从NSDate对象检索午夜过后的小时数?

我需要从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而不是2210确实是UIDatePicker可见的值,但由于@"H" ,我原本期望NSDateFormatter将其转换为22

这有什么不对? 我的转换假设不正确吗? 这是UIDatePicker的错误吗? 如何解决问题,因此我基本上可以访问UIDatePicker中设置的午夜过后的小时数,与用户的12或24小时时钟偏好无关? 无论如何,这是要走的路吗?

为清楚起见,最终目标是检索午夜过后的分钟数(因此小时数* 60 +分钟,价值总是在0和1440之间)。

您可以使用NSCalendar执行此NSCalendar

首先,得到你的约会对象:

 NSDate *date = [timePicker date]; 

接下来,将其转换为其日期组件 :

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

戴夫的答案是正确的,但它不如下面的例子那样高效。 在我的仪器配置文件测试中,我的解决方案速度超过了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; }