简体   繁体   English

如何在Objective-C中格式化日期,类似于jquery.timeago库?

[英]How can I format a date in Objective-C similar to the jquery.timeago library?

I have a feed of items displayed in table cells, part of which is a date / timestamp in the past. 我有一个表格单元格中显示的项目,其中一部分是过去的日期/时间戳。

In Objective-C, how can I accomplish formatting them in the same manner as the jquery.timeago plugin on the web? 在Objective-C中,如何以与网络上的jquery.timeago插件相同的方式完成格式化?

That is, taking in a date and outputting things like: 也就是说,接受日期并输出如下内容:

  • 'just now' '现在'
  • '2 minutes ago' '2分钟前'
  • '24 days ago' '24天前'
  • 'a month ago' '一个月前'

I see there is an NSDate extension class here with methods such as dateWithDaysBeforeNow, dateWithMinutesBeforeNow, etc, but if there is a library out there that has already done this I will use it. 我看到这里有一个NSDate扩展类,其中包含dateWithDaysBeforeNow,dateWithMinutesBeforeNow等方法,但如果有一个已经完成此操作的库,我将使用它。

EDIT: Further to this, if someone composes a method (takes a date, returns a string) that accomplishes this, either with this linked extensions library or another method, I will award them the answer. 编辑:除此之外,如果某人编写了一个方法(接受一个日期,返回一个字符串)来实现这一点,无论是使用这个链接的扩展库还是其他方法,我都会给他们答案。

EDIT 2 Bounty goes to whoever can write the fuzzy date algorithm in Objective-C. EDIT 2 Bounty适用于任何可以在Objective-C中编写模糊日期算法的人。

Create Static Class Method: 创建静态类方法:

+ (NSString *)stringForTimeIntervalSinceCreated:(NSDate *)dateTime serverTime:(NSDate *)serverDateTime{
    NSInteger MinInterval;
    NSInteger HourInterval;
    NSInteger DayInterval;
    NSInteger DayModules;   

    NSInteger interval = abs((NSInteger)[dateTime timeIntervalSinceDate:serverDateTime]);
    if(interval >= 86400)    
    {
        DayInterval  = interval/86400;
        DayModules = interval%86400;
        if(DayModules!=0)
        {
            if(DayModules>=3600){
                //HourInterval=DayModules/3600;
                return [NSString stringWithFormat:@"%i days", DayInterval];
            }
            else {
                if(DayModules>=60){
                    //MinInterval=DayModules/60;
                    return [NSString stringWithFormat:@"%i days", DayInterval];
                }
                else {
                    return [NSString stringWithFormat:@"%i days", DayInterval];
                }
            }
        }
        else 
        {
        return [NSString stringWithFormat:@"%i days", DayInterval];
        }

    }

    else{

        if(interval>=3600)
        {

            HourInterval= interval/3600;
            return [NSString stringWithFormat:@"%i hours", HourInterval];

        }

        else if(interval>=60){

            MinInterval = interval/60;

            return [NSString stringWithFormat:@"%i minutes", MinInterval];
        }
        else{
            return [NSString stringWithFormat:@"%i Sec", interval];
        }

    }

}

OK, I couldn't sleep last night -- guess I'll bite. 好吧,我昨晚无法入睡 - 猜我会咬人。 Here's a line-for-line port of jQuery's timeAgo, with the original JavaScript source in comments for reference. 这是jQuery的timeAgo的line-for-line端口,其中包含原始JavaScript源代码以供参考。 Uses standard ObjC/AppKit mechanisms for user defaults and localization. 使用标准的ObjC / AppKit机制进行用户默认和本地化。 Web-related stuff, like updating an existing DOM element is obviously omitted. 显然忽略了与Web相关的东西,比如更新现有的DOM元素。 Also omits the mechanism where you can put a function in the settings, because that's sort of JavaScript specific. 还省略了可以在设置中放置函数的机制,因为这是一种特定于JavaScript的。 Without further ado: 无需再费周折:

Header file: 头文件:

//
//  NSDate+JQTimeAgoAdditions.h
//  JQTimeAgo
//

#import <Foundation/Foundation.h>

@interface NSDate (JQTimeAgoAdditions)

- (NSString*)timeAgo;

@end

extern NSString* const kJQTimeAgoAllowFutureKey;
extern NSString* const kJQTimeAgoStringsPrefixAgoKey;
extern NSString* const kJQTimeAgoStringsPrefixFromNowKey;
extern NSString* const kJQTimeAgoStringsSuffixAgoKey;
extern NSString* const kJQTimeAgoStringsSuffixFromNowKey;
extern NSString* const kJQTimeAgoStringsSecondsKey;
extern NSString* const kJQTimeAgoStringsMinuteKey;
extern NSString* const kJQTimeAgoStringsMinutesKey;
extern NSString* const kJQTimeAgoStringsHourKey;
extern NSString* const kJQTimeAgoStringsHoursKey;
extern NSString* const kJQTimeAgoStringsDayKey;
extern NSString* const kJQTimeAgoStringsDaysKey;
extern NSString* const kJQTimeAgoStringsMonthKey;
extern NSString* const kJQTimeAgoStringsMonthsKey;
extern NSString* const kJQTimeAgoStringsYearKey;
extern NSString* const kJQTimeAgoStringsYearsKey;
extern NSString* const kJQTimeAgoStringsNumbersKey;

And the implementation file: 和实施文件:

//
//  NSDate+JQTimeAgoAdditions.m
//  JQTimeAgo
//

#import "NSDate+JQTimeAgoAdditions.h"

@implementation NSDate (JQTimeAgoAdditions)

- (NSString*)timeAgo
{
    NSTimeInterval distanceMillis = -1000.0 * [self timeIntervalSinceNow];
//        inWords: function(distanceMillis) {
//            var $l = this.settings.strings;
    NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
//            var prefix = $l.prefixAgo;
    NSString* prefix = [defs stringForKey: kJQTimeAgoStringsPrefixAgoKey];
//            var suffix = $l.suffixAgo;
    NSString* suffix = [defs stringForKey: kJQTimeAgoStringsSuffixAgoKey];
//            if (this.settings.allowFuture) {
    if ([defs boolForKey: kJQTimeAgoAllowFutureKey])
    {
//                if (distanceMillis < 0) {
        if (distanceMillis < 0.0) 
        {
//                    prefix = $l.prefixFromNow;
            prefix = [defs stringForKey: kJQTimeAgoStringsPrefixFromNowKey];
//                    suffix = $l.suffixFromNow;
            suffix = [defs stringForKey: kJQTimeAgoStringsSuffixFromNowKey];
//                }
        }
//                distanceMillis = Math.abs(distanceMillis);
        distanceMillis = fabs(distanceMillis);            
//            }
    }
//            
//            var seconds = distanceMillis / 1000;
    const double seconds = distanceMillis / 1000.0;
//            var minutes = seconds / 60;
    const double minutes = seconds / 60.0;
//            var hours = minutes / 60;
    const double hours = minutes / 60.0;
//            var days = hours / 24;
    const double days = hours / 24.0;
//            var years = days / 365;
    const double years = days / 365.0;
//            
//            function substitute(stringOrFunction, number) { ... }
    // Use stringWithFormat, etc.
//            
//            var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
    NSString* words = nil;
    if (seconds < 45)
        words = [[defs stringForKey: kJQTimeAgoStringsSecondsKey] stringByReplacingOccurrencesOfString: @"%d" withString: [NSString stringWithFormat: @"%d", (int)round(seconds)]];
//            seconds < 90 && substitute($l.minute, 1) ||
    else if (seconds < 90)
        words = [[defs stringForKey: kJQTimeAgoStringsMinuteKey] stringByReplacingOccurrencesOfString: @"%d" withString: [NSString stringWithFormat: @"%d", (int)1]];

//            minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
    else if (minutes < 45)
        words = [[defs stringForKey: kJQTimeAgoStringsMinutesKey] stringByReplacingOccurrencesOfString: @"%d" withString: [NSString stringWithFormat: @"%d", (int)round(minutes)]];

//            minutes < 90 && substitute($l.hour, 1) ||
    else if (minutes < 90)
        words = [[defs stringForKey: kJQTimeAgoStringsHourKey] stringByReplacingOccurrencesOfString: @"%d" withString: [NSString stringWithFormat: @"%d", (int)1]];

//            hours < 24 && substitute($l.hours, Math.round(hours)) ||
    else if (hours < 24)
        words = [[defs stringForKey: kJQTimeAgoStringsHoursKey] stringByReplacingOccurrencesOfString: @"%d" withString: [NSString stringWithFormat: @"%d", (int)round(hours)]];

//            hours < 48 && substitute($l.day, 1) ||
    else if (hours < 48)
        words = [[defs stringForKey: kJQTimeAgoStringsDayKey] stringByReplacingOccurrencesOfString: @"%d" withString: [NSString stringWithFormat: @"%d", (int)1]];
//            days < 30 && substitute($l.days, Math.floor(days)) ||
    else if (days < 30)
        words = [[defs stringForKey: kJQTimeAgoStringsDaysKey] stringByReplacingOccurrencesOfString: @"%d" withString: [NSString stringWithFormat: @"%d", (int)floor(days)]];

//            days < 60 && substitute($l.month, 1) ||
    else if (days < 60)
        words = [[defs stringForKey: kJQTimeAgoStringsMonthKey] stringByReplacingOccurrencesOfString: @"%d" withString: [NSString stringWithFormat: @"%d", (int)1]];

//            days < 365 && substitute($l.months, Math.floor(days / 30)) ||
    else if (days < 365)
        words = [[defs stringForKey: kJQTimeAgoStringsMonthsKey] stringByReplacingOccurrencesOfString: @"%d" withString: [NSString stringWithFormat: @"%d", (int)floor(days/30.0)]];

//            years < 2 && substitute($l.year, 1) ||
    else if (years < 2)
        words = [[defs stringForKey: kJQTimeAgoStringsYearKey] stringByReplacingOccurrencesOfString: @"%d" withString: [NSString stringWithFormat: @"%d", (int)1]];
//            substitute($l.years, Math.floor(years));
    else
        words = [[defs stringForKey: kJQTimeAgoStringsYearsKey] stringByReplacingOccurrencesOfString: @"%d" withString: [NSString stringWithFormat: @"%d", (int)floor(years)]];
//            
//            return $.trim([prefix, words, suffix].join(" "));
    NSString* retVal = [[NSString stringWithFormat: @"%@ %@ %@", 
                         (prefix ? prefix : @""),
                         (words ? words : @""),
                         (suffix ? suffix : @"")] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
    return retVal;
//        },
}

// Load settings
+ (void)load
{    
    // Frameworks are guaranteed to be loaded by now so we can use NSDictionary, etc...
    // See here for details: http://www.mikeash.com/pyblog/friday-qa-2009-05-22-objective-c-class-loading-and-initialization.html
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        @autoreleasepool 
        {
            NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [NSNumber numberWithBool: NO], kJQTimeAgoAllowFutureKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsPrefixAgoKey, nil, [NSBundle mainBundle], @" ", @"kJQTimeAgoStringsPrefixAgoKey"), kJQTimeAgoStringsPrefixAgoKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsPrefixFromNowKey, nil, [NSBundle mainBundle], @" ", @"kJQTimeAgoStringsPrefixFromNowKey"), kJQTimeAgoStringsPrefixFromNowKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsSuffixAgoKey, nil, [NSBundle mainBundle], @"ago", @"kJQTimeAgoStringsSuffixAgoKey"), kJQTimeAgoStringsSuffixAgoKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsSuffixFromNowKey, nil, [NSBundle mainBundle], @"from now", @"kJQTimeAgoStringsSuffixFromNowKey"), kJQTimeAgoStringsSuffixFromNowKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsSecondsKey, nil, [NSBundle mainBundle], @"less than a minute", @"kJQTimeAgoStringsSecondsKey"), kJQTimeAgoStringsSecondsKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsMinuteKey, nil, [NSBundle mainBundle], @"about a minute", @"kJQTimeAgoStringsMinuteKey"), kJQTimeAgoStringsMinuteKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsMinutesKey, nil, [NSBundle mainBundle], @"%d minutes", @"kJQTimeAgoStringsMinutesKey"), kJQTimeAgoStringsMinutesKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsHourKey, nil, [NSBundle mainBundle], @"about an hour", @"kJQTimeAgoStringsHourKey"), kJQTimeAgoStringsHourKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsHoursKey, nil, [NSBundle mainBundle], @"about %d hours", @"kJQTimeAgoStringsHoursKey"), kJQTimeAgoStringsHoursKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsDayKey, nil, [NSBundle mainBundle], @"about a day", @"kJQTimeAgoStringsDayKey"), kJQTimeAgoStringsDayKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsDaysKey, nil, [NSBundle mainBundle], @"%d days", @"kJQTimeAgoStringsDaysKey"), kJQTimeAgoStringsDaysKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsMonthKey, nil, [NSBundle mainBundle], @"about a month", @"kJQTimeAgoStringsMonthKey"), kJQTimeAgoStringsMonthKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsMonthsKey, nil, [NSBundle mainBundle], @"%d months", @"kJQTimeAgoStringsMonthsKey"), kJQTimeAgoStringsMonthsKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsYearKey, nil, [NSBundle mainBundle], @"about a year", @"kJQTimeAgoStringsYearKey"), kJQTimeAgoStringsYearKey,
                                      NSLocalizedStringWithDefaultValue(kJQTimeAgoStringsYearsKey, nil, [NSBundle mainBundle], @"%d years", @"kJQTimeAgoStringsYearsKey"), kJQTimeAgoStringsYearsKey,
                                      nil];


            [[NSUserDefaults standardUserDefaults] registerDefaults: settings];
        }
    });
}

@end

NSString* const kJQTimeAgoAllowFutureKey = @"kJQTimeAgoAllowFutureKey";
NSString* const kJQTimeAgoStringsPrefixAgoKey = @"kJQTimeAgoStringsPrefixAgoKey";
NSString* const kJQTimeAgoStringsPrefixFromNowKey = @"kJQTimeAgoStringsPrefixFromNowKey";
NSString* const kJQTimeAgoStringsSuffixAgoKey = @"kJQTimeAgoStringsSuffixAgoKey";
NSString* const kJQTimeAgoStringsSuffixFromNowKey = @"kJQTimeAgoStringsSuffixFromNowKey";
NSString* const kJQTimeAgoStringsSecondsKey = @"kJQTimeAgoStringsSecondsKey";
NSString* const kJQTimeAgoStringsMinuteKey = @"kJQTimeAgoStringsMinuteKey";
NSString* const kJQTimeAgoStringsMinutesKey = @"kJQTimeAgoStringsMinutesKey";
NSString* const kJQTimeAgoStringsHourKey = @"kJQTimeAgoStringsHourKey";
NSString* const kJQTimeAgoStringsHoursKey = @"kJQTimeAgoStringsHoursKey";
NSString* const kJQTimeAgoStringsDayKey = @"kJQTimeAgoStringsDayKey";
NSString* const kJQTimeAgoStringsDaysKey = @"kJQTimeAgoStringsDaysKey";
NSString* const kJQTimeAgoStringsMonthKey = @"kJQTimeAgoStringsMonthKey";
NSString* const kJQTimeAgoStringsMonthsKey = @"kJQTimeAgoStringsMonthsKey";
NSString* const kJQTimeAgoStringsYearKey = @"kJQTimeAgoStringsYearKey";
NSString* const kJQTimeAgoStringsYearsKey = @"kJQTimeAgoStringsYearsKey";
NSString* const kJQTimeAgoStringsNumbersKey = @"kJQTimeAgoStringsNumbersKey";

I wrote an NSDate category that returns time deltas in a human readable format (eg, "4 weeks, 2 days"). 我写了一个NSDate类别,以人类可读的格式返回时间增量(例如,“4周,2天”)。 You can download it here and tweak it to your needs: https://github.com/chriscdn/RHTools (look for NSDate+timesince). 您可以在此处下载并根据您的需要进行调整: https//github.com/chriscdn/RHTools (查找NSDate + timesince)。

I know this is old but this is what I did which is fairly simple... 我知道这是旧的,但这是我做的,这很简单......

NSDate *placeDate = [object createdAt];
NSTimeInterval timeSince = [placeDate timeIntervalSinceNow];
NSLog(@"%f", timeSince);

if (timeSince > -60) {
cell.date.text = [NSString stringWithFormat:@"%f seconds ago", -timeSince];
}
else if (timeSince <= -60 && timeSince > -3600){
    cell.date.text = [NSString stringWithFormat:@"%.0f minutes ago", -timeSince/60];
}
else if (timeSince <= -3600 && timeSince > -86400){
    cell.date.text = [NSString stringWithFormat:@"%.0f hours ago", -timeSince/60/60];
}
else if (timeSince <= -86400 && timeSince > -604800){
    cell.date.text = [NSString stringWithFormat:@"%.0f days ago", -timeSince/24/60/60];
}
else if (timeSince <= -604800 && timeSince > -2592000){
    cell.date.text = [NSString stringWithFormat:@"%.0f weeks ago", -timeSince/7/24/60/60];
}
else if (timeSince <= -2592000 && timeSince > -31536000){
    cell.date.text = [NSString stringWithFormat:@"%.0f months ago", -timeSince/30/24/60/60];
}
else {
    cell.date.text = [NSString stringWithFormat:@"%.1f years ago", -timeSince/365/24/60/60];
}

You can try with NSDateFormater and write it your self. 您可以尝试使用NSDateFormater并自行编写。

If value is under one minute then write just now, otherwise minutes, hours, days, etc. 如果价值低于一分钟,则立即写入,否则分钟,小时,天等。

You can use NSDate-TimeAgo . 您可以使用NSDate-TimeAgo It can be installed in your project using CocoaPods. 它可以使用CocoaPods安装在您的项目中。

  1. Add the files to your project - manually or via Cocoapods (pod 'NSDate+TimeAgo') 将文件添加到项目中 - 手动或通过Cocoapods(pod'NSDate + TimeAgo')
  2. Import the header using #import "NSDate+TimeAgo.h" 使用#import "NSDate+TimeAgo.h"导入标题
  3. Use the library method timeAgo. 使用库方法timeAgo。

https://stackoverflow.com/a/8268903/1915957 https://stackoverflow.com/a/8268903/1915957

↑ convert swift code. ↑转换swift代码。

class func stringForTimeIntervalSinceCreated(dateTime :NSDate, serverTime serverDateTime:NSDate) -> String {
    var MinInterval  :Int = 0
    var HourInterval :Int = 0
    var DayInterval  :Int = 0
    var DayModules   :Int = 0

    let interval = abs(Int(dateTime.timeIntervalSinceDate(serverDateTime)))
    if (interval >= 86400) {
        DayInterval = interval/86400
        DayModules = interval%86400
        if (DayModules != 0) {
            if (DayModules>=3600) {
                //HourInterval=DayModules/3600;
                return String(DayInterval) + " days"
            } else {
                if (DayModules >= 60) {
                    //MinInterval=DayModules/60;
                    return String(DayInterval) + " days"
                } else {
                    return String(DayInterval) + " days"
                }
            }
        } else {
            return String(DayInterval) + " days"
        }
    } else {
        if (interval >= 3600) {
            HourInterval = interval/3600
            return String(HourInterval) + " hours"
        } else if (interval >= 60) {
            MinInterval = interval/60
            return String(MinInterval) + " minutes"
        } else {
            return String(interval) + " Sec"
        }
    }
}
+ (NSString *)changeTime:(NSString *)serverDateTime{
    NSInteger MinInterval;
    NSInteger HourInterval;
    NSInteger DayInterval;
    //NSInteger DayModules;
    NSTimeInterval _interval=[serverDateTime doubleValue];
    NSDate *Serverdate = [NSDate dateWithTimeIntervalSince1970:_interval];
    NSInteger interval = (long)((NSInteger)[[NSDate date] timeIntervalSinceDate:Serverdate]);
    if(interval >= 86400)
    {
        DayInterval  = interval/86400;// no. of days
        if (DayInterval > 14){
            return [NSString stringWithFormat:@"w+"];
        }
        if (DayInterval >= 7 && DayInterval <= 14){
            int diff =  (int)DayInterval / 7;
            return [NSString stringWithFormat:@"%iw",diff];
        }
        return [NSString stringWithFormat:@"%id",(int)DayInterval];
    }
    else{

        if(interval>=3600)
        {

            HourInterval= interval/3600;
            return [NSString stringWithFormat:@"%lih", (long)HourInterval];

        }
        else if(interval>=60){

            MinInterval = interval/60;

            return [NSString stringWithFormat:@"%lim", (long)MinInterval];
        }
        else{
            return [NSString stringWithFormat:@"%lis", (long)interval];
        }
        return @"now";
    }

}

if you have a problem with date and time. 如果你有日期和时间的问题。 you should think to this library 你应该想到这个图书馆

https://github.com/MatthewYork/DateTools https://github.com/MatthewYork/DateTools

It always help! 它总是有帮助的!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM