你的问题已经收到了负分(-4在写作的时间)的人显然觉得你没有表现出努力,以便预期。然而,你的问题隐藏了一个难题,苹果最近更加努力,这使得它很有趣。
你的采样时间为:
NSString *currentTime = @"Sat, 17 Oct 2015 9:58 am CDT"
这似乎是 “早晨”。然而,这与以下情况完全相同:
Sat, 17 Oct 2015 2:58 pm GMT
这似乎是“下午”。这两个时间是:
Sat, 17 Oct 2015 14:58 UTC
为什么这是一个问题?
一个NSDate
是一个时间点没有任何关联的时区。类NSDateFormatter
以及NSDate
本身的关联方法将解析日期时间字符串并生成字符串表示的绝对UTC时间点。在字符串中的任何时间段,例如在CDT
的例子中,被允许用于在确定绝对时间点,但没有在NSDate
值,其导致直接表示。
当使用NSCalendar
类来分解日期的某些部分时,它与缺省为系统时区的时区相关。
这一切都加起来是,如果您的应用程序正在运行,比方说,在英国的计算机上和您按照意见建议:
- 解析时间(使用
NSDateFormatter
)
- 跳出小时&分钟以得到一个
NSDateComponents
值(使用NSCalendar
);和
- 小时&分钟比较你的边界,然后你的采样时间将被报告为“午”
不好:-(
你需要的是解析日期时间(让一个标准的UTC时间点)和时区,然后你可以传递时区NSCalendar
,其余是容易的。
苹果使得它更难
之前OS X 10.9 &的iOS 7的NSDateFormatter
类返回NSCalendarDate
日期值,该类型是的NSDate
一个子类,并且还存储在NSTimeZone
值。因此,解析您的示例将返回时间点“星期六,2015年10月17日14:58 UTC”和时区“UTC-5”。有了这些信息,NSCalendar
可用于突破小时&分钟,并正确确定时间是“早上”。
NSCalendarDate
现在已被弃用,虽然仍有可能使用它,但随时都可能发生变化。 Apple似乎还没有提供另一种“解析日期和时区”方法。
解析这两个日期和时区偏移
从简单的观察,如果你解析“周六,2015年10月17日上午9时58 CDT”忽略了时区,把它当作UTC结果一个绝对时间点相差5小时,即CDT的时区偏移量,如果将字符串解析为时区,则得到时间偏移量,您有一种获取时区的方法 - 解析字符串两次,忽略时区,并确定差异。
这可能不是最好的算法,但它的工作......(你可以在此处插入关于过早优化的警告!)
所以这里去(最小的意见,看看这些方法起来的文件,错误检查等 - 当作仅仅是概要):
- (BOOL) dateAndZoneFromString:(NSString *)timeString // the date-time string
dateFormat:(NSString *)dateFormat // the format of the date-time, should contain a time zone format at the end
parsedDate:(NSDate **)date // NSDate representing the absolute time point
parsedZone:(NSTimeZone **)zone // NSTimeZone representing the time zone of the original string
error:(NSError **)error
{
NSDateFormatter *df = [NSDateFormatter new];
// parse timeString taking time zone into account
df.dateFormat = dateFormat;
NSDate *absDate = [df dateFromString:timeString];
// parse timeString ignoring the time zone by removing the format specifier from dateFormat
df.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
df.dateFormat = [dateFormat stringByReplacingOccurrencesOfString:@" *[zZvV]+$" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, dateFormat.length)];
NSDate *zonelessDate;
NSRange range = NSMakeRange(0, timeString.length);
if ([df getObjectValue:&zonelessDate forString:timeString range:&range error:error])
{
// parse successful, calculate the difference and construct an NSTimeZone value
NSTimeInterval offset = [zonelessDate timeIntervalSinceDate:absDate];
NSTimeZone *timezone = [NSTimeZone timeZoneForSecondsFromGMT:offset];
*date = absDate;
*zone = timezone;
return YES;
}
else
return NO;
}
如果传递@"Sat, 17 Oct 2015 9:58 am CDT"
和格式@"E, d MMM y h:m a z"
此方法将返回的时间点“周六,二零一五年十月十七日14:58 UTC”为NSDate
和作为NSTimeZone
的时区“UTC-5”。
如果传递@"Sat, 17 Oct 2015 2:58 pm GMT"
那么它将返回相同绝对时间点和“UTC + 0”的时区。
对于这一点,你可以使用这些值与NSCalendar
,NSDateComponents
,和简单的比较来确定早上/下午/晚上。
HTH
解析字符串日期,提取小时组件,然后核对上午/下午/晚上边界是小时值?你有没有尝试过自己呢? – luk2302
要添加到@ luk2302评论中的重要一点是您需要将字符串解析为日期**和时区**。标准日期时间解析将允许时区,但不会报告它,只是返回绝对时间点 - 这是无用的,以确定早上/下午/晚上,因为每个绝对时间点都是他们! – CRD
一旦你解析日期为@ luk2302建议你可以使用下面的帖子中的代码来完成你正在寻找的东西:http://stackoverflow.com/questions/6945553/find-if-current-time-is-between -a-range/6945653#6945653您需要根据自己的喜好调整时间。 – Joe