lunes, 6 de diciembre de 2010

Manejo de fechas en Objective-C

El lenguaje Objective-C tiene una carencia importante según yo lo veo, que es que hay cosas que deberían ser simples y llevan una cantidad importante de trabajo.

Un ejemplo es concatenar dos strings. En cualquier otro lenguaje, sería algo como:
result = s1 + s2;
En Objective-C, hacer lo mismo lleva mucho más código:
result = [NSString stringWithFormat:@"%@%@", s1, s2];
En particular, una de las cosas que me parecen de las más complicadas en Objective-C (desde el punto de la sintaxis), es el manejo de fechas.

Por ejemplo, para crear una fecha, el código es el siguiente:
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setYear:2010];
[comps setMonth:12];
[comps setDay:6];

NSDate *date = [[NSCalendar currentCalendar] dateFromComponents:comps];

[comps release];
También si quiero obtener el día, mes y año de una fecha dada, es complicado:
NSDate *tmpDate = [NSDate date]; // today
NSDateComponents *comp = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:tmpDate];

int day = [comp day];
int month = [comp month];
int year = [comp year];
Claro que estas complicaciones tienen algunas ventajas. Por ejemplo, puedo tener una fecha y consultar el año en distintos calendarios (gregoriano, budista, hebreo, etc.), pero de todas formas, debería haber alguna forma más fácil de trabajar con fechas.

Por suerte, en Objective-C uno puede agregar métodos a clases ya existentes, por lo que es posible agregar algunos métodos a la clase NSDate para facilitar el trabajo. Por ejemplo:
@implementation NSDate (DateHelper)

+ (NSDate *) dateWithYear:(int)year month:(int)month day:(int)day {
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setYear:year];
[comps setMonth:month];
[comps setDay:day];

NSDate *tmpDate = [[NSCalendar currentCalendar] dateFromComponents:comps];

[comps release];

return tmpDate;
}

- (int) getDay {
NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSDayCalendarUnit fromDate:self];
return [comp day];
}

- (int) getMonth {
NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSMonthCalendarUnit fromDate:self];
return [comp month];
}

- (int) getYear {
NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSYearCalendarUnit fromDate:self];
return [comp year];
}

@end
Ahora entonces para crear una nueva fecha, podemos hacer simplemente:
NSDate *date = [NSDate dateWithYear:2010 month:12 day:6];
y para obtener el año de dicha fecha
int year = [date getYear];

3 comentarios:

  1. Que tal Marcos!!
    fíjate que tengo 2 problemas el primero

    1- obtengo dos fechas atravez de un DatePicker, en el siguente formato YYYY/MM/dd HH:mm. la cual es inicial y final de el horario de trabajo ya que hay varios turnos. Mi pregunta es como puedo obtener el resultado de horas que trabajo basados en la inicial y final el total debe de ir con el mismo formato YYYY/MM/dd HH:mm

    2- Como puedo guardo los datos de un Text Field en una variable NSDate yo lo hago de esta forma la cual es erronea NSDate *fecha = [ NSDate date:[self.obtenerFecha.text]];

    ojala me puedas ayudar de antemano Gracias!!!!
    Saludos

    ResponderEliminar
    Respuestas
    1. Jorge:

      1) Si tenés dos fechas de un DatePicker, deberías tenerlas como NSDate. La diferencia se puede obtener con:
      NSTimeInterval diff = [date2 timeIntervalSinceDate:date1];

      2) Usando la clase NSDateFormatter, con el método dateFromString:. Ver https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/Reference/Reference.html

      Eliminar
    2. Gracias Marco!! con tu ayuda resulto ser muy fácil.

      Eliminar