【问题标题】:iOS - Friendly NSDate formatiOS - 友好的 NSDate 格式
【发布时间】:2012-04-21 23:38:08
【问题描述】:

我需要在我的应用程序中向用户显示帖子的日期,现在我以这种格式执行此操作:“5 月 25 日,星期五”。我将如何格式化 NSDate 以读取“2 小时前”之类的内容?使其更加用户友好。

【问题讨论】:

标签: ios date nsdate nsdateformatter date-format


【解决方案1】:

看看 FormaterKit https://github.com/mattt/FormatterKit

由同样创建了 AFNetworking 的 mattt 创建。

【讨论】:

  • 这应该会得到 ore upvotes,它是由伟大的开发人员创建的一个很棒的工具包,而且它非常易于使用。
【解决方案2】:

NSDateFormatter 不能那样做;你需要建立自己的规则。我猜是这样的:

- (NSString *)formattedDate:(NSDate *)date
{
     NSTimeInterval timeSinceDate = [[NSDate date] timeIntervalSinceDate:date];

     // print up to 24 hours as a relative offset
     if(timeSinceDate < 24.0 * 60.0 * 60.0)
     {
         NSUInteger hoursSinceDate = (NSUInteger)(timeSinceDate / (60.0 * 60.0));

         switch(hoursSinceDate)
         {
              default: return [NSString stringWithFormat:@"%d hours ago", hoursSinceDate];
              case 1: return @"1 hour ago";
              case 0:
                  NSUInteger minutesSinceDate = (NSUInteger)(timeSinceDate / 60.0);
                  /* etc, etc */
              break;
         }
     }
     else
     {
          /* normal NSDateFormatter stuff here */
     }
}

也就是说,从日期开始最多 24 小时打印“x 分钟前”或“x 小时前”,通常是一天。

【讨论】:

    【解决方案3】:

    我想要 Facebook 为他们的移动应用程序提供的日期格式,所以我创建了这个 NSDate 类别 - 希望它对某人有用(这种东西真的应该在标准库中!):)

    https://github.com/nikilster/NSDate-Time-Ago

    【讨论】:

    • 我浏览了您的图书馆,它非常有用。但是在您的图书馆中,诸如“刚刚”、“6 分钟前”、“7 小时前”之类的内容运行良好。但我也想要“3 天前”、“4 周前”、“2 年前”之类的东西。如何做到这一点?
    • 这是为了模仿 Facebook 的日期格式风格而创建的。它意味着人类可读且易于理解(他们对如何最好地表示日期进行了很多思考,我认为当您使用它时很清楚这是一种很好的格式。像 4 周前这样的事情不会当您查看过去的时间间隔时,为您提供足够的具体信息。如果您想获得类似的信息,只需修改 if 语句输出的字符串。
    • 但这是我公司的要求,而且我认为如果我写“1 w”(一周前),而不是显示“10 月 3 日凌晨 12 点 42 分”,它可能会占用大量空间
    【解决方案4】:

    还有 SEHumanizedTimeDiff 支持/即将支持多种语言,如果这对您来说是个问题:

    https://github.com/sarperdag/SEHumanizedTimeDiff

    【讨论】:

    • 这是一个不错的小库,仅本地化就值得一票;因为这是其他提议的解决方案所没有的。
    • 同意@CarlosP。外观也已经贡献了很多语言。
    【解决方案5】:

    有大约一百万种方法可以做到这一点,但这里有一个快速的方法:

    NSString* hoursAgo = [NSString stringWithFormat:@"%.0lf hours ago", fabs([date timeIntervalSinceNow] / 3600.0)]
    

    当然,这并不能检查 date 是否真的来自过去,除了几个小时之外什么都不做。但是,你可能明白了。

    timeIntervalSinceNow 返回自给定日期以来经过的秒数,正数表示未来的日期,负数表示过去的日期。所以,我们得到经过了多少秒,将其除以 3600 秒,计算出经过的小时数,然后将其绝对值放入字符串“n hours ago”。

    【讨论】:

      【解决方案6】:

      这是一个很好的答案,从 epoch(1970 年 1 月 1 日)开始需要几秒钟,并返回一个格式不错的字符串,例如“3 分钟前”。只需像这样用您的日期对象调用它:

      [timeAgoFromUnixTime:[myDateObject timeIntervalSince1970]];
      
      + (NSString *)timeAgoFromUnixTime:(double)seconds
      {
          double difference = [[NSDate date] timeIntervalSince1970] - seconds;
          NSMutableArray *periods = [NSMutableArray arrayWithObjects:@"second", @"minute", @"hour", @"day", @"week", @"month", @"year", @"decade", nil];
          NSArray *lengths = [NSArray arrayWithObjects:@60, @60, @24, @7, @4.35, @12, @10, nil];
          int j = 0;
          for(j=0; difference >= [[lengths objectAtIndex:j] doubleValue]; j++)
          {
              difference /= [[lengths objectAtIndex:j] doubleValue];
          }
          difference = roundl(difference);
          if(difference != 1)
          {
              [periods insertObject:[[periods objectAtIndex:j] stringByAppendingString:@"s"] atIndex:j];
          }
          return [NSString stringWithFormat:@"%li %@%@", (long)difference, [periods objectAtIndex:j], @" ago"];
      }
      

      【讨论】:

        【解决方案7】:

        在提出此问题后的较新版本的 iOS 中,NSDateFormatter 已添加此功能。它现在可以使用doesRelativeDateFormatting 属性来完成。

        【讨论】:

        • 无法让它工作。检查文档,不确定我做错了什么。如果我格式化为常规日期,我会得到一个字符串。但是,如果我调用 setDoesRelativeDateFormatting 我什么也得不到。想法?代码示例?
        • 您可以在一些使用 Google 的教程中找到它,但我认为您应该将您的问题作为新的 SO 问题发布,以便我们可以看到您的代码!没有它就很难给出建议。
        【解决方案8】:
        +(NSString*)HourCalculation:(NSString*)PostDate
        
        {
            NSLog(@"postdate=%@",PostDate);
            // PostDate=@"2014-04-02 01:31:04";
            NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
            [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
            [dateFormat setTimeZone:gmt];
            NSDate *ExpDate = [dateFormat dateFromString:PostDate];
            NSLog(@"expdate=%@",ExpDate);
            NSLog(@"expdate=%@",[NSDate date ]);
            NSCalendar *calendar = [NSCalendar currentCalendar];
        
            NSDateComponents *components = [calendar components:(NSDayCalendarUnit|NSWeekCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit|NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:ExpDate toDate:[NSDate date] options:0];
        
        //    NSLog(@"year=%d",components.year);
        //    
        //    NSLog(@"month=%d",components.month);
        //    
        //    NSLog(@"week=%d",components.week);
        //    
        //    NSLog(@"day=%d",components.day);
        //    
        //    NSLog(@"hour=%d",components.hour);
        //    
        //    NSLog(@"min=%d",components.minute);
        //    
        //    NSLog(@"sce=%d",components.second);
        //    
        
            NSString *time;
        
            if(components.year!=0)   
            {
                if(components.year==1) 
                {
                    time=[NSString stringWithFormat:@"%ld year",(long)components.year];  
                }
                else{
                    time=[NSString stringWithFormat:@"%ld years",(long)components.year]; 
                }    
            }
            else if(components.month!=0) 
            {
                if(components.month==1)   
                {
                    time=[NSString stringWithFormat:@"%ld month",(long)components.month]; 
                }
                else{
                    time=[NSString stringWithFormat:@"%ld months",(long)components.month]; 
                }
              //  NSLog(@"%@",time);
            }
            else if(components.week!=0)
            {
                if(components.week==1)
                {
                    time=[NSString stringWithFormat:@"%ld week",(long)components.week];
                }
                else{
                    time=[NSString stringWithFormat:@"%ld weeks",(long)components.week];
                }
               // NSLog(@"%@",time);
            }
            else if(components.day!=0)
            {
                if(components.day==1)   
                {
                    time=[NSString stringWithFormat:@"%ld day",(long)components.day];
                }
                else{
                    time=[NSString stringWithFormat:@"%ld days",(long)components.day]; 
                } 
            }
            else if(components.hour!=0) 
            {
                if(components.hour==1)  
                {
                    time=[NSString stringWithFormat:@"%ld hour",(long)components.hour];  
                }
                else{
                    time=[NSString stringWithFormat:@"%ld hours",(long)components.hour];
                }
            }
            else if(components.minute!=0)  
            {
                if(components.minute==1)  
                {
                    time=[NSString stringWithFormat:@"%ld min",(long)components.minute];
                }
        
                else{
                    time=[NSString stringWithFormat:@"%ld mins",(long)components.minute]; 
                }
              //  NSLog(@"time=%@",time);
            }
            else if(components.second>=0){
        
               // NSLog(@"postdate=%@",PostDate);
        
               // NSLog(@"expdate=%@",[NSDate date ]);
        
                if(components.second==0)   
                {
                    time=[NSString stringWithFormat:@"1 sec"];
                }
                else{
                    time=[NSString stringWithFormat:@"%ld secs",(long)components.second];
                }
            }
            return [NSString stringWithFormat:@"%@ ago",time];
        
        }
        

        此代码将显示您的时间 ------------ 秒 喜欢 2 秒前 ------------min like 2 分钟前 ------------ 几小时前 2 小时前 ------------天像 2 天前 ------------一周像 2 周前 ------------月份像 2 个月前 最后.... 像 2 年前一样 :) 试试这个

        【讨论】:

          【解决方案9】:

          添加到解决方案试试这个更简化的方法

              NSDateComponents *today = [[NSCalendar currentCalendar] components:NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate:passed toDate:[NSDate date] options:0];
              NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:date];
          
              if (interval < 60) timestampString = [NSString stringWithFormat:@"%d seconds ago" ,today.second];
              else if (interval < 60 * 60) timestampString = [NSString stringWithFormat:@"%d minutes ago" ,today.minute];
              else if (interval < 60 * 60 * 24) timestampString = [NSString stringWithFormat:@"%d hours ago" ,today.hour];
              else timestampString = [NSString stringWithFormat:@"%d days ago" ,today.day];
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-06-14
            • 1970-01-01
            • 2011-07-04
            • 2016-10-05
            • 1970-01-01
            • 1970-01-01
            • 2011-09-17
            相关资源
            最近更新 更多