iOS 14.0.1下NSDate获取小时值错误问题求助
解决NSDate获取小时值错误的问题
嗨,我来帮你搞定这个小时值不对的问题~
问题根源分析
你现在遇到的问题,核心是误解了NSDate的本质:NSDate本身是一个「绝对时间戳」,不携带任何时区信息,它代表的是GMT标准时间。你手动给原始date加上本地时区的偏移量,得到的correctDate其实是把「本地时间对应的GMT时间」又往后推了8小时(你的时区应该是GMT+8),这时候这个correctDate对应的本地时间就变成了第二天的6:34,所以不管是br_hour还是NSDateFormatter,拿到的都是这个错误时间的小时值。
举个例子:
- 你选择的22:34是本地时间,对应的GMT时间是14:34(也就是日志里的
inital date selected) - 你加了8小时的偏移量后,
correctDate变成了22:34 GMT,这个时间对应的本地时间就是第二天的6:34(22+8=30,减去24就是6) - 这就是为什么小时始终是6,而分钟34是对的——分钟不会因为跨天改变
正确的解决方案
不要手动修改NSDate的时间戳来处理时区,而是用NSCalendar来提取指定时区的日期组件,或者用NSDateFormatter直接格式化原始NSDate。
方法1:用NSCalendar获取小时和分钟
NSDate *date = self.wakeUpView.timePicker.date; // 获取当前日历,并明确设置时区为本地时区 NSCalendar *calendar = [NSCalendar currentCalendar]; calendar.timeZone = [NSTimeZone localTimeZone]; // 提取小时和分钟组件 NSDateComponents *components = [calendar components:NSCalendarUnitHour | NSCalendarUnitMinute fromDate:date]; NSInteger targetHour = components.hour; NSInteger targetMinute = components.minute; NSLog(@"正确的小时:%ld,分钟:%ld", (long)targetHour, (long)targetMinute);
方法2:用NSDateFormatter正确格式化时间
如果你只是需要字符串形式的时间,直接用原始date即可,NSDateFormatter会自动处理时区:
NSDate *date = self.wakeUpView.timePicker.date; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"HH:mm"]; // 可以明确设置时区,默认也是本地时区,保险起见加上 [formatter setTimeZone:[NSTimeZone localTimeZone]]; NSString *dateString = [formatter stringFromDate:date]; NSLog(@"formatted date: %@", dateString); // 这里会输出你选择的22:34
补充说明
关于你用的br_hour分类方法,它内部应该也是基于NSCalendar实现的,但因为你传入的correctDate本身就是错误的时间戳,所以才会返回6。只要用原始的date,配合正确的时区设置,不管是系统API还是自定义分类,都能拿到正确的小时值。
内容的提问来源于stack exchange,提问作者muuka7




