You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动