2015-10-17 105 views
-2

我在Objective-C的工作识别上午,下午或晚上。我在字符串这三个值,他们决定当天(对象 - )从日期字符串

NSString *morning = @"7:01"; 
NSString *afternoon = @"12:01" 
NSString *night = @"19:01" 

的一部分,我原来的日期是这样的,也是在字符串

NSString *currentTime = @"Sat, 17 Oct 2015 9:58 am CDT" 

我需要确定如果当前日期是上午,按照当前日期的下午或晚上作为字符串。任何人都有解决方案?

+5

解析字符串日期,提取小时组件,然后核对上午/下午/晚上边界是小时值?你有没有尝试过自己呢? – luk2302

+2

要添加到@ luk2302评论中的重要一点是您需要将字符串解析为日期**和时区**。标准日期时间解析将允许时区,但不会报告它,只是返回绝对时间点 - 这是无用的,以确定早上/下午/晚上,因为每个绝对时间点都是他们! – CRD

+0

一旦你解析日期为@ luk2302建议你可以使用下面的帖子中的代码来完成你正在寻找的东西:http://stackoverflow.com/questions/6945553/find-if-current-time-is-between -a-range/6945653#6945653您需要根据自己的喜好调整时间。 – Joe

回答

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类来分解日期的某些部分时,它与缺省为系统时区的时区相关。

这一切都加起来是,如果您的应用程序正在运行,比方说,在英国的计算机上和您按照意见建议:

  1. 解析时间(使用NSDateFormatter
  2. 跳出小时&分钟以得到一个NSDateComponents值(使用NSCalendar);和
  3. 小时&分钟比较你的边界,然后你的采样时间将被报告为“午”

不好:-(

你需要的是解析日期时间(让一个标准的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

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]; 
    } 

} 
+2

尽管此代码可能会回答这个问题,但提供关于此代码为何和/或如何回答此问题的其他上下文可提高其长期价值。 –

相关问题