从 Unix 时间戳获取人类可读的相对时间和日期?

发布于 2024-10-03 20:59:36 字数 344 浏览 0 评论 0原文

从像 1290529723 这样的 unix 时间戳开始,我(假设 gmt)如何获取以下信息:

  • 今天(如果是,则是什么时间)

  • in过去 7 天(如果是的话,哪一天......星期一, 周二等?)

  • 超过一周(如果是这样,如何以 dd/mm/yy 输出 格式?)

我需要这个消息列表,例如 iPhone 的邮件应用程序,其中显示相对于当前日期和时间的日期/时间,如下所示

15:45
Yesterday
Sunday
Saturday
10/10/10

Starting with a unix timestamp like 1290529723, how would I (assuming gmt) get the information on whether it is:

  • today (if so, what time)

  • in the last seven days (if so, which day ... mon,
    tues etc?)

  • older than a week (if so, how to output in dd/mm/yy
    format?)

I need this for a list of messages like the iPhone's Mail app, where date/times are shown relative to the current date and time, like so:

15:45
Yesterday
Sunday
Saturday
10/10/10

etc

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

爱格式化 2024-10-10 20:59:36

需要进行一些调整才能获得尊重设备区域设置的解决方案。以下方法relativeStringFromDate 返回一个表示日期的字符串,格式如下:

  • 如果日期是今天,则根据区域设置仅返回时间(例如“3:40PM”或“15:40”)
  • 如果日期是昨天,则返回“昨天”(但将被国际化为区域设置的语言)
  • 如果日期是两到六天前,则为星期几的名称(例如“星期一”、“星期二”等,同样根据区域设置的语言)
  • 仅日期部分,如果根据区域设置,日期已超过一周前(例如,美国为“1/20/2012”,欧洲为“20/1/2012”)

    - (NSString *)relativeStringFromDate:(NSDate *)date {
        if ([self dateIsToday:日期])
            返回 [self dateAsStringTime:date];
        else if ([self dateIsYesterday:date])
            返回 [self dateAsStringDate:date];
        else if ([self dateIsTwoToSixDaysAgo:date])
            返回 [self dateAsStringDay:date];
        别的
            返回 [self dateAsStringDate:date];
    }
    
    - (BOOL)日期:(NSDate *)日期 
            isDayWithTimeIntervalSinceNow:(NSTimeInterval)间隔 {
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setDateFormat:@"yyyy-MM-dd"];
    
        NSDate *other_date;
        other_date = [NSDate dateWithTimeIntervalSinceNow:间隔];
    
        NSString *d1, *d2;
        d1 = [df stringFromDate:日期];
        d2 = [df stringFromDate:other_date];
        返回[d1 isEqualToString:d2];    
    }
    
    - (BOOL)dateIsToday:(NSDate *)日期 {
        返回[自身日期:日期isDayWithTimeIntervalSinceNow:0];
    }
    
    - (BOOL)dateIsYesterday:(NSDate *)日期 {
        返回[自身日期:日期 isDayWithTimeIntervalSinceNow:-86400];
    }
    
    - (BOOL)dateIsTwoToSixDaysAgo:(NSDate *)日期 {
        for (int i = 2; i <= 6; i += 1)
            if ([自身日期:日期 isDayWithTimeIntervalSinceNow:i*-86400])
                返回是;
        返回否;    
    }
    
    - (NSString *)dateAsStringDate:(NSDate *)日期 {
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setDateStyle:NSDateFormatterShortStyle];
        [df setDoesRelativeDateFormatting:YES];
        NSString *str = [df stringFromDate:日期];
        返回字符串;
    }
    
    - (NSString *)dateAsStringTime:(NSDate *)日期 {
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setTimeStyle:NSDateFormatterShortStyle];
        NSString *str = [df stringFromDate:日期];
        返回字符串;
    }
    
    - (NSString *)dateAsStringDay:(NSDate *)日期 {
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setDateFormat:@"EEEE"];
        NSString *str_day = [df stringFromDate:日期];
        返回str_day;
    }
    

如您所述和 Brad 的答案,您可以使用 NSDate 的 dateWithTimeIntervalSince1970 从时间戳获取 NSDate。

It takes a bit of fiddling to get a solution that respects the device's locale. The following method relativeStringFromDate returns a string representing the date, formatted as following:

  • just the time if the date is today, according to locale (e.g. '3:40PM' or '15:40')
  • 'Yesterday' if the date is yesterday (but will be internationalized into locale's language)
  • name of the day of the week if date is two to six days ago (e.g. 'Monday', 'Tuesday', etc, again according to locale's language)
  • just the date component if the date is over one week ago, according to locale (e.g. '1/20/2012' in US vs '20/1/2012' in Europe)

    - (NSString *)relativeStringFromDate:(NSDate *)date {
        if ([self dateIsToday:date])
            return [self dateAsStringTime:date];
        else if ([self dateIsYesterday:date])
            return [self dateAsStringDate:date];
        else if ([self dateIsTwoToSixDaysAgo:date])
            return [self dateAsStringDay:date];
        else
            return [self dateAsStringDate:date];
    }
    
    - (BOOL)date:(NSDate *)date 
            isDayWithTimeIntervalSinceNow:(NSTimeInterval)interval {
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setDateFormat:@"yyyy-MM-dd"];
    
        NSDate *other_date;
        other_date = [NSDate dateWithTimeIntervalSinceNow:interval];
    
        NSString *d1, *d2;
        d1 = [df stringFromDate:date];
        d2 = [df stringFromDate:other_date];
        return [d1 isEqualToString:d2];    
    }
    
    - (BOOL)dateIsToday:(NSDate *)date {
        return [self date:date isDayWithTimeIntervalSinceNow:0];
    }
    
    - (BOOL)dateIsYesterday:(NSDate *)date {
        return [self date:date isDayWithTimeIntervalSinceNow:-86400];
    }
    
    - (BOOL)dateIsTwoToSixDaysAgo:(NSDate *)date {
        for (int i = 2; i <= 6; i += 1)
            if ([self date:date isDayWithTimeIntervalSinceNow:i*-86400])
                return YES;
        return NO;    
    }
    
    - (NSString *)dateAsStringDate:(NSDate *)date {
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setDateStyle:NSDateFormatterShortStyle];
        [df setDoesRelativeDateFormatting:YES];
        NSString *str = [df stringFromDate:date];
        return str;
    }
    
    - (NSString *)dateAsStringTime:(NSDate *)date {
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setTimeStyle:NSDateFormatterShortStyle];
        NSString *str = [df stringFromDate:date];
        return str;
    }
    
    - (NSString *)dateAsStringDay:(NSDate *)date {
        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setDateFormat:@"EEEE"];
        NSString *str_day = [df stringFromDate:date];
        return str_day;
    }
    

As mentioned in yours and Brad's answers, you can obtain an NSDate from a timestamp using NSDate's dateWithTimeIntervalSince1970.

暗地喜欢 2024-10-10 20:59:36

我使用这个方法将 unix 时间戳更改为可读的相对字符串。可能在新年的头几天无法正常工作,但希望你宿醉得太厉害而不会注意到。

-(NSString *)relativeTime:(int)datetimestamp
{
    NSDate *aDate = [NSDate dateWithTimeIntervalSince1970:datetimestamp];
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned int unitFlags =  NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayOrdinalCalendarUnit|NSWeekdayCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit;
    NSDateComponents *messageDateComponents = [calendar components:unitFlags fromDate:aDate];
    NSDateComponents *todayDateComponents = [calendar components:unitFlags fromDate:[NSDate date]];

    NSUInteger dayOfYearForMessage = [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:aDate];
    NSUInteger dayOfYearForToday = [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:[NSDate date]];


    NSString *dateString;

    if ([messageDateComponents year] == [todayDateComponents year] && 
        [messageDateComponents month] == [todayDateComponents month] &&
        [messageDateComponents day] == [todayDateComponents day]) 
    {
        dateString = [NSString stringWithFormat:@"%02d:%02d", [messageDateComponents hour], [messageDateComponents minute]];
    } else if ([messageDateComponents year] == [todayDateComponents year] && 
               dayOfYearForMessage == (dayOfYearForToday-1))
    {
        dateString = @"Yesterday";
    } else if ([messageDateComponents year] == [todayDateComponents year] &&
               dayOfYearForMessage > (dayOfYearForToday-6))
    {

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"EEEE"];
        dateString = [dateFormatter stringFromDate:aDate];
        [dateFormatter release];

    } else {

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"yy"];
        dateString = [NSString stringWithFormat:@"%02d/%02d/%@", [messageDateComponents day], [messageDateComponents month], [dateFormatter stringFromDate:aDate]];
        [dateFormatter release];
    }

    return dateString;
}

I made this method to change the unix time stamp into a nice readable, relative string. Probably doesn't work properly in the first few days of a new year, but hopefully you should be too hungover to notice.

-(NSString *)relativeTime:(int)datetimestamp
{
    NSDate *aDate = [NSDate dateWithTimeIntervalSince1970:datetimestamp];
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned int unitFlags =  NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayOrdinalCalendarUnit|NSWeekdayCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit;
    NSDateComponents *messageDateComponents = [calendar components:unitFlags fromDate:aDate];
    NSDateComponents *todayDateComponents = [calendar components:unitFlags fromDate:[NSDate date]];

    NSUInteger dayOfYearForMessage = [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:aDate];
    NSUInteger dayOfYearForToday = [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:[NSDate date]];


    NSString *dateString;

    if ([messageDateComponents year] == [todayDateComponents year] && 
        [messageDateComponents month] == [todayDateComponents month] &&
        [messageDateComponents day] == [todayDateComponents day]) 
    {
        dateString = [NSString stringWithFormat:@"%02d:%02d", [messageDateComponents hour], [messageDateComponents minute]];
    } else if ([messageDateComponents year] == [todayDateComponents year] && 
               dayOfYearForMessage == (dayOfYearForToday-1))
    {
        dateString = @"Yesterday";
    } else if ([messageDateComponents year] == [todayDateComponents year] &&
               dayOfYearForMessage > (dayOfYearForToday-6))
    {

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"EEEE"];
        dateString = [dateFormatter stringFromDate:aDate];
        [dateFormatter release];

    } else {

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"yy"];
        dateString = [NSString stringWithFormat:@"%02d/%02d/%@", [messageDateComponents day], [messageDateComponents month], [dateFormatter stringFromDate:aDate]];
        [dateFormatter release];
    }

    return dateString;
}
━╋う一瞬間旳綻放 2024-10-10 20:59:36

我个人喜欢 github 上的 https://github.com/kevinlawler/NSDate-TimeAgo 库。它只有两个文件,使用起来非常简单。如果您愿意的话,它还具有本地化功能!

I personally like the https://github.com/kevinlawler/NSDate-TimeAgo library on github. It only has two files and it's very simple to use. It also has localization if you want!

未央 2024-10-10 20:59:36

NSDateFormatter 类有你需要的。它确实通过 doesRelativeDateFormatting 方法执行“今天”、“明天”等操作。

希望这可以帮助那些来到这里并且不想使用外部类或创建自己的类的人。

The NSDateFormatter class has what you need. It does do "today", "tomorrow" etc. via the doesRelativeDateFormatting method.

Hope that helps someone else who lands on here and doesn't want to use an external class or creates his own.

不喜欢何必死缠烂打 2024-10-10 20:59:36

有一个库:TTTTimeIntervalFormatter 在 mattt 的 FormatterKit< /代码>:)

There is a library for that: TTTTimeIntervalFormatter in mattt's FormatterKit :)

千鲤 2024-10-10 20:59:36

将其转换为 NSDate:

+ (id)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds

然后与其他日期进行比较:

* – compare:
* – earlierDate:
* – isEqual: (NSObject protocol)
* – laterDate:

Convert it to an NSDate with:

+ (id)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds

Then compare to other dates with:

* – compare:
* – earlierDate:
* – isEqual: (NSObject protocol)
* – laterDate:
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文