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

时间:2011-11-10 23:33:37

标签: ios objective-c date 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中可见的值,但由于NSDateFormatter,我原本希望将22转换为@"H"

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

明确的最终目标是检索午夜过后的分钟数(所以小时数* 60 +分钟,价值总是在0和1440之间)。

2 个答案:

答案 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;
}