我在Objective-C工作。我在字符串中有这三个值,它们决定了当天的部分
NSString *morning = @"7:01";
NSString *afternoon = @"12:01"
NSString *night = @"19:01"
我的原始日期是这个,也是字符串
NSString *currentTime = @"Sat, 17 Oct 2015 9:58 am CDT"
我需要确定当前日期是早上,下午还是晚上,根据当前日期为String。有人有解决方案吗?
答案 0 :(得分:2)
你的问题得分为负(在撰写本文时为-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
,其余的是容易。
Apple让它变得更难
OS X 10.9& iOS 7 NSDateFormatter
类返回了NSCalendarDate
日期值,该类型是NSDate
的子类,并且还存储了NSTimeZone
值。因此,解析您的样本返回时间点"星期六,2015年10月17日14:58 UTC"和时区" UTC-5"。有了这些信息NSCalendar
可以用来打破时间和时间。 min并且正确地确定时间是"早晨"。
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"
传递给此方法,则会返回时间点"星期六,2015年10月17日14:58 UTC"作为NSDate
和时区" UTC-5"作为NSTimeZone
。
如果您通过@"Sat, 17 Oct 2015 2:58 pm GMT"
,则会返回相同的绝对时间点和" UTC + 0"的时区。
在这一点上,您可以将这些值与NSCalendar
,NSDateComponents
和简单比较结合使用,以确定上午/下午/晚上。
HTH
答案 1 :(得分:1)
-(void)ShowTimeMessage
{
// For calculating the current date
NSDate *date = [NSDate date];
// Make Date Formatter
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"hh a EEEE"];
// hh for hour mm for minutes and a will show you AM or PM
NSString *str = [dateFormatter stringFromDate:date];
// NSLog(@"%@", str);
// Sperate str by space i.e. you will get time and AM/PM at index 0 and 1 respectively
NSArray *array = [str componentsSeparatedByString:@" "];
// Now you can check it by 12. If < 12 means Its morning > 12 means its evening or night
NSString *message;
NSString *timeInHour;
NSString *am_pm;
NSString *DayOfWeek;
if (array.count>2)
{
// am pm case
timeInHour = array[0];
am_pm = array[1];
DayOfWeek = array[2];
}
else if (array.count>1)
{
// 24 hours case
timeInHour = array[0];
DayOfWeek = array[1];
}
if (am_pm)
{
if ([timeInHour integerValue]>=4 && [timeInHour integerValue]<=9 && [am_pm isEqualToString:@"AM"])
{
message = [NSString stringWithFormat:@"Morning"];
}
else if (([timeInHour integerValue]>=10 && [timeInHour integerValue]!=12 && [am_pm isEqualToString:@"AM"]) || (([timeInHour integerValue]<4 || [timeInHour integerValue]==12) && [am_pm isEqualToString:@"PM"]))
{
message = [NSString stringWithFormat:@"Afternoon"];
}
else if ([timeInHour integerValue]>=4 && [timeInHour integerValue]<=9 && [am_pm isEqualToString:@"PM"])
{
message = [NSString stringWithFormat:@"Evening"];
}
else if (([timeInHour integerValue]>=10 && [timeInHour integerValue]!=12 && [am_pm isEqualToString:@"PM"]) || (([timeInHour integerValue]<4 || [timeInHour integerValue]==12) && [am_pm isEqualToString:@"AM"]))
{
message = [NSString stringWithFormat:@"Night"];
}
}
else
{
if ([timeInHour integerValue]>=4 && [timeInHour integerValue]<10)
{
message = [NSString stringWithFormat:@"Morning"];
}
else if ([timeInHour integerValue]>=10 && [timeInHour integerValue]<16)
{
message = [NSString stringWithFormat:@"Afternoon"];
}
else if ([timeInHour integerValue]>=16 && [timeInHour integerValue]<22)
{
message = [NSString stringWithFormat:@"Evening"];
}
else
{
message = [NSString stringWithFormat:@"Night"];
}
}
if (DayOfWeek)
{
_timeLbl.text=[NSString stringWithFormat:@"%@ %@",DayOfWeek,message];
}
}