salio precio plus playa nuevo esta cuesta cuanto cuando costara costaba carmen cancun aifon 256gb iphone objective-c cocoa datetime time

playa - precio del iphone 7 plus en cancun



iPhone: convierte la cadena de fecha en una marca de tiempo relativa (11)

Aquí hay métodos de Cocoa para ayudarlo a obtener información relevante (no estoy seguro si todos están disponibles en 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]);

El objeto NSDateComponents parece contener la diferencia en unidades relevantes (como se especifica). Si especifica todas las unidades, puede usar este método:

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]); }

Si quiere calcular usted mismo, puede echar un vistazo a:

NSDate timeIntervalSinceDate

Y luego use segundos en el algoritmo.

Descargo de responsabilidad : si esta interfaz se está desaprovechando (no la he marcado), la forma preferida de Apple de hacer esto a través de NSDateFormatters , como se sugiere en los comentarios a continuación, también se ve bastante ordenada: mantendré mi respuesta por razones históricas, aún puede ser útil para que algunos observen la lógica utilizada.

Tengo una marca de tiempo como una cadena como:

Jue, 21 de mayo de 09 19:10:09 -0700

y me gustaría convertirlo en una marca de tiempo relativa como ''hace 20 minutos'' o ''3 días atrás''.

¿Cuál es la mejor manera de hacer esto usando Objective-C para iPhone?


En aras de la integridad, basado en la respuesta de @Gilean, aquí está el código completo para una categoría simple en NSDate que imita a los ingeniosos ayudantes de fecha de los rieles. Para una actualización sobre las categorías, estos son los métodos de instancia que llamaría a los objetos NSDate. Entonces, si tengo un NSDate que representa ayer, [myDate distanceOfTimeInWordsToNow] => "1 día".

Espero que sea útil!

@interface NSDate (NSDate_Relativity) -(NSString *)distanceOfTimeInWordsSinceDate:(NSDate *)aDate; -(NSString *)distanceOfTimeInWordsToNow; @end @implementation NSDate (NSDate_Relativity) -(NSString *)distanceOfTimeInWordsToNow { return [self distanceOfTimeInWordsSinceDate:[NSDate date]]; } -(NSString *)distanceOfTimeInWordsSinceDate:(NSDate *)aDate { double interval = [self timeIntervalSinceDate:aDate]; NSString *timeUnit; int timeValue; if (interval < 0) { interval = interval * -1; } if (interval< 60) { return @"seconds"; } else if (interval< 3600) { // minutes timeValue = round(interval / 60); if (timeValue == 1) { timeUnit = @"minute"; } else { timeUnit = @"minutes"; } } else if (interval< 86400) { timeValue = round(interval / 60 / 60); if (timeValue == 1) { timeUnit = @"hour"; } else { timeUnit = @"hours"; } } else if (interval< 2629743) { int days = round(interval / 60 / 60 / 24); if (days < 7) { timeValue = days; if (timeValue == 1) { timeUnit = @"day"; } else { timeUnit = @"days"; } } else if (days < 30) { int weeks = days / 7; timeValue = weeks; if (timeValue == 1) { timeUnit = @"week"; } else { timeUnit = @"weeks"; } } else if (days < 365) { int months = days / 30; timeValue = months; if (timeValue == 1) { timeUnit = @"month"; } else { timeUnit = @"months"; } } else if (days < 30000) { // this is roughly 82 years. After that, we''ll say ''forever'' int years = days / 365; timeValue = years; if (timeValue == 1) { timeUnit = @"year"; } else { timeUnit = @"years"; } } else { return @"forever ago"; } } return [NSString stringWithFormat:@"%d %@", timeValue, timeUnit]; } @end


Mi solución:

- (NSString *) dateToName:(NSDate*)dt withSec:(BOOL)sec { NSLocale *locale = [NSLocale currentLocale]; NSTimeInterval tI = [[NSDate date] timeIntervalSinceDate:dt]; if (tI < 60) { if (sec == NO) { return NSLocalizedString(@"Just Now", @""); } return [NSString stringWithFormat: NSLocalizedString(@"%d seconds ago", @""),(int)tI]; } if (tI < 3600) { return [NSString stringWithFormat: NSLocalizedString(@"%d minutes ago", @""),(int)(tI/60)]; } if (tI < 86400) { return [NSString stringWithFormat: NSLocalizedString(@"%d hours ago", @""),(int)tI/3600]; } NSDateFormatter *relativeDateFormatter = [[NSDateFormatter alloc] init]; [relativeDateFormatter setTimeStyle:NSDateFormatterNoStyle]; [relativeDateFormatter setDateStyle:NSDateFormatterMediumStyle]; [relativeDateFormatter setDoesRelativeDateFormatting:YES]; [relativeDateFormatter setLocale:locale]; NSString * relativeFormattedString = [relativeDateFormatter stringForObjectValue:dt]; return relativeFormattedString; }


No estoy seguro de por qué esto no está en el toque de cacao, una buena manera estándar de hacer esto sería genial.

Configure algunos tipos para mantener los datos, lo hará más fácil si alguna vez lo localizó un poco más. (obviamente ampliar si necesita más períodos de tiempo)

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; }

NOTA: Estoy usando un cálculo basado en una hora, ya que es en lo que están mis datos. NSTimeInterval está basado en segundos. También tuve que convertir entre los dos.


Todavía no puedo editar, pero tomé el código de Gilean e hice algunos ajustes y lo convertí en una categoría de NSDateFormatter.

Acepta una cadena de formato para que funcione con cadenas arbitrarias y agregué si las cláusulas para que los eventos singulares sean gramaticalmente correctos.

Aclamaciones,

Carl 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


Tomé el código de Carl Coryell-Martin e hice una categoría de NSDate más simple que no tiene advertencias sobre el formato de cadena de las singulares, y también ordena la semana anterior singular:

@interface NSDate (Extras) - (NSString *)differenceString; @end @implementation NSDate (Extras) - (NSString *)differenceString{ NSDate* date = self; NSDate *now = [NSDate date]; double time = [date timeIntervalSinceDate:now]; time *= -1; if (time < 60) { int diff = round(time); if (diff == 1) return @"1 second ago"; return [NSString stringWithFormat:@"%d seconds ago", diff]; } else if (time < 3600) { int diff = round(time / 60); if (diff == 1) return @"1 minute ago"; return [NSString stringWithFormat:@"%d minutes ago", diff]; } else if (time < 86400) { int diff = round(time / 60 / 60); if (diff == 1) return @"1 hour ago"; return [NSString stringWithFormat:@"%d hours ago", diff]; } else if (time < 604800) { int diff = round(time / 60 / 60 / 24); if (diff == 1) return @"yesterday"; if (diff == 7) return @"a week ago"; return[NSString stringWithFormat:@"%d days ago", diff]; } else { int diff = round(time / 60 / 60 / 24 / 7); if (diff == 1) return @"a week ago"; return [NSString stringWithFormat:@"%d weeks ago", diff]; } } @end


Use la clase NSDate:

timeIntervalSinceDate

devuelve el intervalo en segundos.

Ejercicio rápido para implementar esto en Object-C:

  1. Obtenga tiempo "ahora" NSDate
  2. Obtenga el NSDate con el que desea comparar
  3. Obtenga el intervalo en segundos usando timeIntervalSinceDate

Luego implementa este pseudo código:

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

y así...

entonces debe decidir si un mes es 30,31 o 28 días. Mantenlo simple: elige 30.

Puede haber una manera mejor, pero son las 2 de la mañana y esto es lo primero que se me viene a la mente ...


Vi que había varias funciones atrás en fragmentos de código en y quería una que realmente diera el sentido más claro de la época (ya que se produjo alguna acción). Para mí, esto significa estilo "hace tiempo" para intervalos de tiempo cortos (5 min., Hace 2 horas) y fechas específicas para períodos de tiempo más largos (15 de abril de 2011 en lugar de hace 2 años). Básicamente, pensé que Facebook hizo un muy buen trabajo en esto y quería seguir su ejemplo (ya que estoy seguro de que reflexionaron mucho sobre esto y es muy fácil y claro de entender desde la perspectiva del consumidor).

Después de un largo tiempo de búsqueda de Google, me sorprendí bastante al ver que nadie había implementado esto por lo que pude ver. Decidí que lo quería lo suficiente como para pasar el tiempo escribiendo y pensé que lo compartiría.

Espero que lo disfrutes :)

Obtenga el código aquí: github.com/nikilster/NSDate-Time-Ago


Ya hay muchas respuestas que responden a la misma solución, pero no tiene sentido tener opciones. Esto es lo que se me ocurrió.

- (NSString *)stringForTimeIntervalSinceCreated:(NSDate *)dateTime { NSDictionary *timeScale = @{@"second":@1, @"minute":@60, @"hour":@3600, @"day":@86400, @"week":@605800, @"month":@2629743, @"year":@31556926}; NSString *scale; int timeAgo = 0-(int)[dateTime timeIntervalSinceNow]; if (timeAgo < 60) { scale = @"second"; } else if (timeAgo < 3600) { scale = @"minute"; } else if (timeAgo < 86400) { scale = @"hour"; } else if (timeAgo < 605800) { scale = @"day"; } else if (timeAgo < 2629743) { scale = @"week"; } else if (timeAgo < 31556926) { scale = @"month"; } else { scale = @"year"; } timeAgo = timeAgo/[[timeScale objectForKey:scale] integerValue]; NSString *s = @""; if (timeAgo > 1) { s = @"s"; } return [NSString stringWithFormat:@"%d %@%@ ago", timeAgo, scale, s]; }


En Swift

Uso:

let time = NSDate(timeIntervalSince1970: timestamp).timeIntervalSinceNow let relativeTimeString = NSDate.relativeTimeInString(time) println(relativeTimeString)

Extensión:

extension NSDate { class func relativeTimeInString(value: NSTimeInterval) -> String { func getTimeData(value: NSTimeInterval) -> (count: Int, suffix: String) { let count = Int(floor(value)) let suffix = count != 1 ? "s" : "" return (count: count, suffix: suffix) } let value = -value switch value { case 0...15: return "just now" case 0..<60: let timeData = getTimeData(value) return "/(timeData.count) second/(timeData.suffix) ago" case 0..<3600: let timeData = getTimeData(value/60) return "/(timeData.count) minute/(timeData.suffix) ago" case 0..<86400: let timeData = getTimeData(value/3600) return "/(timeData.count) hour/(timeData.suffix) ago" case 0..<604800: let timeData = getTimeData(value/86400) return "/(timeData.count) day/(timeData.suffix) ago" default: let timeData = getTimeData(value/604800) return "/(timeData.count) week/(timeData.suffix) ago" } } }


-(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"; } }