Вы можете получить информацию о городе / штате в формате значений, разделенных табуляцией, из GeoNames.org . Данные являются бесплатными, всеобъемлющими и хорошо структурированными. Для данных в США возьмите файл US.txt
на странице бесплатных данных почтового индекса . Файл readme.txt
на этой странице описывает формат.
-(NSString *)dateDiff:(NSString *)origDate {
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setFormatterBehavior:NSDateFormatterBehavior10_4];
[df setDateFormat:@"EEE, dd MMM yy HH:mm:ss VVVV"];
NSDate *convertedDate = [df dateFromString:origDate];
[df release];
NSDate *todayDate = [NSDate date];
double ti = [convertedDate timeIntervalSinceDate:todayDate];
ti = ti * -1;
if(ti < 1) {
return @"never";
} else if (ti < 60) {
return @"less than a minute ago";
} else if (ti < 3600) {
int diff = round(ti / 60);
return [NSString stringWithFormat:@"%d minutes ago", diff];
} else if (ti < 86400) {
int diff = round(ti / 60 / 60);
return[NSString stringWithFormat:@"%d hours ago", diff];
} else if (ti < 2629743) {
int diff = round(ti / 60 / 60 / 24);
return[NSString stringWithFormat:@"%d days ago", diff];
} else {
return @"never";
}
}
Вот методы из Какао, которые помогут вам получить релевантную информацию (не уверен, все ли они доступны в coca-touch).
NSDate * today = [NSDate date];
NSLog(@"today: %@", today);
NSString * str = @"Thu, 21 May 09 19:10:09 -0700";
NSDate * past = [NSDate dateWithNaturalLanguageString:str
locale:[[NSUserDefaults
standardUserDefaults] dictionaryRepresentation]];
NSLog(@"str: %@", str);
NSLog(@"past: %@", past);
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
unsigned int unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |
NSDayCalendarUnit |
NSHourCalendarUnit | NSMinuteCalendarUnit |
NSSecondCalendarUnit;
NSDateComponents *components = [gregorian components:unitFlags
fromDate:past
toDate:today
options:0];
NSLog(@"months: %d", [components month]);
NSLog(@"days: %d", [components day]);
NSLog(@"hours: %d", [components hour]);
NSLog(@"seconds: %d", [components second]);
Кажется, что объект NSDateComponents содержит разницу в соответствующих единицах (как указано). Если вы укажете все единицы, вы можете использовать этот метод:
void dump(NSDateComponents * t)
{
if ([t year]) NSLog(@"%d years ago", [t year]);
else if ([t month]) NSLog(@"%d months ago", [t month]);
else if ([t day]) NSLog(@"%d days ago", [t day]);
else if ([t minute]) NSLog(@"%d minutes ago", [t minute]);
else if ([t second]) NSLog(@"%d seconds ago", [t second]);
}
Если вы хотите вычислить самостоятельно, вы можете взглянуть на:
NSDate timeIntervalSinceDate
А затем использовать секунды в алгоритме.
Отказ от ответственности : Если этот интерфейс устаревает (я не проверял), предпочтительный способ Apple сделать это через NSDateFormatters
, как предлагается в комментариях ниже, также выглядит довольно аккуратно - я сохраню свой ответ по историческим причинам, это может все же будет полезно для некоторых взглянуть на используемую логику.
Не уверен, почему этого нет в cocoa-touch, я хороший стандартный способ сделать это было бы здорово.
Настройте некоторые типы для хранения данных, это упростит, если вам когда-либо требовалось немного его локализовать. (очевидно, расширьте, если вам нужно больше периодов времени)
typedef struct DayHours {
int Days;
double Hours;
} DayHours;
+ (DayHours) getHourBasedTimeInterval:(double) hourBased withHoursPerDay:(double) hpd
{
int NumberOfDays = (int)(fabs(hourBased) / hpd);
float hoursegment = fabs(hourBased) - (NumberOfDays * hpd);
DayHours dh;
dh.Days = NumberOfDays;
dh.Hours = hoursegment;
return dh;
}
ПРИМЕЧАНИЕ: Я использую расчет на основе часов, так как это то, в чем мои данные. NSTimeInterval основан на секундах. Мне также пришлось конвертировать между ними.
Используйте класс NSDate:
timeIntervalSinceDate
возвращает интервал в секундах.
Быстрое упражнение для реализации этого в objective-c:
Затем реализуйте этот псевдокод:
if (x < 60) // x seconds ago
else if( x/60 < 60) // floor(x/60) minutes ago
else if (x/(60*60) < 24) // floor(x/(60*60) hours ago
else if (x/(24*60*60) < 7) // floor(x(24*60*60) days ago
и так далее ...
, тогда вам нужно решить, равен ли месяц 30,31 или 28 дней. Будьте проще - выберите 30.
Может быть и лучший способ, но сейчас 2 часа ночи, и это первое, что пришло в голову ...
Я пока не могу редактировать, но я взял Gilean и сделал пару настроек и сделал его категорией NSDateFormatter.
Он принимает строку формата, поэтому он будет работать с произвольными строками, и я добавил, что предложения if, содержащие единичные события, должны быть грамматически правильными.
Ура,
Карл CM
@interface NSDateFormatter (Extras)
+ (NSString *)dateDifferenceStringFromString:(NSString *)dateString
withFormat:(NSString *)dateFormat;
@end
@implementation NSDateFormatter (Extras)
+ (NSString *)dateDifferenceStringFromString:(NSString *)dateString
withFormat:(NSString *)dateFormat
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat:dateFormat];
NSDate *date = [dateFormatter dateFromString:dateString];
[dateFormatter release];
NSDate *now = [NSDate date];
double time = [date timeIntervalSinceDate:now];
time *= -1;
if(time < 1) {
return dateString;
} else if (time < 60) {
return @"less than a minute ago";
} else if (time < 3600) {
int diff = round(time / 60);
if (diff == 1)
return [NSString stringWithFormat:@"1 minute ago", diff];
return [NSString stringWithFormat:@"%d minutes ago", diff];
} else if (time < 86400) {
int diff = round(time / 60 / 60);
if (diff == 1)
return [NSString stringWithFormat:@"1 hour ago", diff];
return [NSString stringWithFormat:@"%d hours ago", diff];
} else if (time < 604800) {
int diff = round(time / 60 / 60 / 24);
if (diff == 1)
return [NSString stringWithFormat:@"yesterday", diff];
if (diff == 7)
return [NSString stringWithFormat:@"last week", diff];
return[NSString stringWithFormat:@"%d days ago", diff];
} else {
int diff = round(time / 60 / 60 / 24 / 7);
if (diff == 1)
return [NSString stringWithFormat:@"last week", diff];
return [NSString stringWithFormat:@"%d weeks ago", diff];
}
}
@end