如何以[[今天10:01:20],[08-jan-17 11:20:51]等格式获取日期和时间?

时间:2017-01-07 15:11:19

标签: ios nsdate datetime-format

我正在处理聊天应用程序,我想以特定格式发送日期/时间,例如今天,昨天和日期。如何按照这种格式显示?

  - (NSString *)relativeDateStringForDate:(NSDate *)date
   {
      NSCalendarUnit units = NSCalendarUnitDay | NSCalendarUnitWeekOfYear | 
                       NSCalendarUnitMonth | NSCalendarUnitYear;

    NSDateComponents *components = [[NSCalendar currentCalendar] components:units
                                                               fromDate:date
                                                                  toDate:[NSDate date]
                                                                options:0];
  if (components.year > 0) {
     return [NSString stringWithFormat:@"%ld years ago", (long)components.year];
   } else if (components.month > 0) {
    return [NSString stringWithFormat:@"%ld months ago", (long)components.month];
   } else if (components.weekOfYear > 0) {
    return [NSString stringWithFormat:@"%ld weeks ago", (long)components.weekOfYear];
   } else if (components.day > 0) {
    if (components.day > 1) {
         return [NSString stringWithFormat:@"%ld days ago", (long)components.day];
    } else {
        return @"Yesterday";
    }
   } else
     {
         return @"Today";
     }
   }

我使用上面的函数来获取日期,但我希望在组合字符串中使用日期时间。那么如何将日期/时间与上述方法相结合?是否可以向此方法发送日期时间字符串?

2 个答案:

答案 0 :(得分:2)

要以[08-jan-17 11:20:51]格式获取日期,您可以使用以下代码

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// Convert to new Date Format
[dateFormatter setDateFormat:@"dd-MMM-yy HH:mm:ss"];
NSDate *date = [NSDate date];
NSString *newDate = [dateFormatter stringFromDate:date]
NSLog(@"[%@]",newDate); // this will give you the date in format [08-jan-17 11:20:51]

要以格式[10:01:20]获取时间,您可以使用以下代码

// Convert to new Time Format
[dateFormatter setDateFormat:@"HH:mm:ss"];
NSDate *date = [NSDate date];
NSString *newTime = [dateFormatter stringFromDate:date];
NSLog(@"%@",newTime); // this will give you the time in format 10:01:20

所以你可以像这样使用你的代码 -

- (NSString *)relativeDateStringForDate:(NSDate *)date
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    // Convert to new Date Format
    [dateFormatter setDateFormat:@"dd-MMM-yy HH:mm:ss"];
    NSString *newDate = [dateFormatter stringFromDate:date];
    NSLog(@"[%@]",newDate);


    // Convert to new Time Format
    [dateFormatter setDateFormat:@"HH:mm:ss"];
    NSString *newTime = [dateFormatter stringFromDate:date];
    NSLog(@"%@",newTime);


    NSCalendarUnit units = NSCalendarUnitDay | NSCalendarUnitWeekOfYear |
    NSCalendarUnitMonth | NSCalendarUnitYear;

    NSDateComponents *components = [[NSCalendar currentCalendar] components:units
                                                                   fromDate:date
                                                                     toDate:[NSDate date]
                                                                    options:0];
    if (components.year > 0) {
        return [NSString stringWithFormat:@"[%ld years ago], [%@]", (long)components.year, newDate];
    } else if (components.month > 0) {
        return [NSString stringWithFormat:@"[%ld months ago], [%@]", (long)components.month, newDate];
    } else if (components.weekOfYear > 0) {
        return [NSString stringWithFormat:@"[%ld weeks ago], [%@]", (long)components.weekOfYear, newDate];
    } else if (components.day > 0) {
        if (components.day > 1) {
            return [NSString stringWithFormat:@"[%ld days ago], [%@]", (long)components.day, newDate];
        } else {
            return [NSString stringWithFormat:@"[Yesterday %@]",newTime];
        }
    } else
    {
        return [NSString stringWithFormat:@"[Today %@]", newTime];
    }
}

答案 1 :(得分:2)

有几点意见:

  1. 您需要NSCalendarUnitWeekOfMonth,而不是NSCalendarUnitWeekOfYear

  2. 为了区分“今天”和“昨天”,您不能只获取两个NSDate对象之间的日期组件。您应首先获取两个日期的日期组件(但不是时间组件),然后获取这两组日期组件之间的差异。

    实际上,如果是早上9点,你正在查看昨晚11点的消息,它会计算day < 1,因此会说“今天晚上11点”(这是错误的)而不是“昨天晚上11点“。

  3. 如果您要包含“x个月前”的字符串,我建议您不要自行构建它。 Apple有一个类为你做这个(NSDateComponentsFormatter)并且它是本地化的。

  4. 所以,把它们拉到一起,就会得到类似的东西:

    - (NSString *)relativeDateStringForDate:(NSDate *)date {
        // get the number of days differences
    
        NSCalendarUnit units =  NSCalendarUnitDay | NSCalendarUnitWeekOfMonth | NSCalendarUnitMonth | NSCalendarUnitYear;
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSDateComponents *dateComponents = [calendar components:units fromDate:date];
        NSDateComponents *nowComponents2 = [calendar components:units fromDate:[NSDate date]];
        NSDateComponents *components = [calendar components:units fromDateComponents:dateComponents toDateComponents:nowComponents2 options:0];
    
        if (components.year > 0 || components.month > 0 || components.weekOfMonth > 0 || components.day > 1) {
            NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
            formatter.allowedUnits = units;
            formatter.maximumUnitCount = 2;    // set this to whatever you want, but 1 or 2 is often best
            formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull;
            return [NSString stringWithFormat:@"%@ %@", [formatter stringFromDateComponents:components], NSLocalizedString(@"ago", @"x days _ago_")];
        } else {
            // build time string
    
            NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
            formatter.timeStyle = NSDateFormatterShortStyle;
            NSString *timeString = [formatter stringFromDate:date];
    
            if (components.day == 1) {
                return [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"Yesterday", @"day before today"), timeString];
            } else {
                return [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"Today", @"well, er, today"), timeString];
            }
        }
    }
    

    现在,请注意我排除了日期是在昨天之前的时间。如果以大于天的任何单位测量日期字符串,则时间没有意义(例如,该字符串中的时间毫无意义:“3个月前,上午11点20分”)。如果要包含时间,则必须包含日期(然后将这些相对“前”字符串呈现为无效)。所以你可能只是摆脱这个“前”部分:

    - (NSString *)relativeDateStringForDate:(NSDate *)date {
        // get the number of days differences
    
        NSCalendarUnit units =  NSCalendarUnitDay | NSCalendarUnitWeekOfMonth | NSCalendarUnitMonth | NSCalendarUnitYear;
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSDateComponents *dateComponents = [calendar components:units fromDate:date];
        NSDateComponents *nowComponents2 = [calendar components:units fromDate:[NSDate date]];
        NSDateComponents *components = [calendar components: NSCalendarUnitDay fromDateComponents:dateComponents toDateComponents:nowComponents2 options:0];
    
        if (components.day > 1) {
            // build date/time string
    
            NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
            formatter.timeStyle = NSDateFormatterShortStyle;
            formatter.dateStyle = NSDateFormatterShortStyle;
            return [formatter stringFromDate:date];
        } else {
            // build time string
    
            NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
            formatter.timeStyle = NSDateFormatterShortStyle;
            NSString *timeString = [formatter stringFromDate:date];
    
            if (components.day == 1) {
                return [NSString stringWithFormat:@"%@, %@", NSLocalizedString(@"Yesterday", @"day before today"), timeString];
            } else {
                return [NSString stringWithFormat:@"%@, %@", NSLocalizedString(@"Today", @"well, er, today"), timeString];
            }
        }
    }
    

    这解决了“3个月前,上午11点20分”这个奇怪的问题,但话说再说一遍,它不再是一个相对的日期/时间字符串。

    另一种选择是完全放弃绝对时间,只显示一个相对字符串:

    - (NSString *)relativeDateStringForDate:(NSDate *)date {
        NSCalendarUnit units = NSCalendarUnitSecond | NSCalendarUnitMinute | NSCalendarUnitHour | NSCalendarUnitDay | NSCalendarUnitWeekOfMonth | NSCalendarUnitMonth | NSCalendarUnitYear;
        NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
        formatter.allowedUnits = units;
        formatter.maximumUnitCount = 2;
        formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull;
        return [NSString stringWithFormat:@"%@ %@", [formatter stringFromDate:date toDate:[NSDate date]], NSLocalizedString(@"ago", @"x days _ago_")];
    }
    

    上述样本的细节不如基本概念重要,即:

    • 在确定“今天”与“昨天”时,请小心使用日期组件;
    • 在尝试创建时间字符串或日期/时间字符串时使用日期格式化程序;和
    • 在尝试构建表示已经过的时间(或天数)的字符串时,使用日期组件格式化程序。