Swift:获取不同时区的当前Date用于时间区间比较
嘿,我太懂你这种跨时区判断营业状态的头疼了——时区这块儿真的很容易绕晕人!先给你理清一个核心误区:NSDate本身是一个绝对的时间戳,不带任何时区信息,它代表的是全球统一的某个瞬间。我们要做的,是把这个绝对时间“翻译”成目标时区(比如你说的PST)的本地时间,再和门店的营业区间对比。
步骤1:获取当前绝对时间
先拿到当前的全局统一时间戳,这一步很简单:
NSDate *currentAbsoluteDate = [NSDate date];
这个值在EST、PST或者任何时区都是同一个,我们接下来要做的就是把它转换成目标时区的本地时间维度。
步骤2:配置目标时区的日历工具
首先指定你要转换的目标时区,比如PST用America/Los_Angeles作为时区名:
NSTimeZone *pstTimeZone = [NSTimeZone timeZoneWithName:@"America/Los_Angeles"];
然后初始化一个日历对象,并把它的时区设置为目标时区,这样它就能帮我们准确解析时间:
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; [calendar setTimeZone:pstTimeZone];
步骤3:提取目标时区下的当前时间组件
用上面的日历,把绝对时间解析成目标时区的时、分等关键组件:
NSDateComponents *currentPSTComponents = [calendar components:(NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:currentAbsoluteDate]; NSInteger currentPSTHour = currentPSTComponents.hour; NSInteger currentPSTMinute = currentPSTComponents.minute;
比如你说的EST 23:30,转换成PST就是20:30,这里拿到的currentPSTHour就是20,currentPSTMinute是30。
步骤4:和门店营业区间做对比
为了方便比较,我们可以把时间转换成总分钟数,这样就不用分别判断时和分了:
// 当前PST时间的总分钟数 NSInteger currentPSTTotalMinutes = currentPSTHour * 60 + currentPSTMinute; // 门店关门时间(PST 23:00)的总分钟数 NSInteger storeCloseTotalMinutes = 23 * 60 + 0; // 假设门店开门时间是PST 9:00 NSInteger storeOpenTotalMinutes = 9 * 60 + 0; // 判断营业状态 if (currentPSTTotalMinutes >= storeOpenTotalMinutes && currentPSTTotalMinutes < storeCloseTotalMinutes) { NSLog(@"门店在PST时区当前处于营业状态"); } else { NSLog(@"门店在PST时区当前已打烊"); }
这样就能准确判断出,当你在EST 23:30时,PST的当前时间是20:30,还没到23:00关门时间,门店还在营业。
额外小技巧:构造目标时区的“当日起始时间”
如果你需要判断日期范围(比如门店是否在营业日),可以用日历构造出目标时区当天的0点绝对时间:
// 获取PST时区下的当前年月日组件 NSDateComponents *todayPSTComponents = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:currentAbsoluteDate]; // 设置时分秒为0,得到PST当天0点的绝对时间 [todayPSTComponents setHour:0]; [todayPSTComponents setMinute:0]; [todayPSTComponents setSecond:0]; NSDate *pstTodayStart = [calendar dateFromComponents:todayPSTComponents];
这个时间可以用来和门店的营业日期范围做对比。
总的来说,核心思路就是用绝对时间戳 + 目标时区的日历解析,不要试图让NSDate本身携带时区信息,而是通过日历工具把绝对时间转换成对应时区的本地时间组件来做判断,这样就不会出错啦!
内容的提问来源于stack exchange,提问作者keylin wu

