Objective-C configurando NSDate en UTC actual

80

¿Existe una manera fácil de iniciar NSDatecon la fecha / hora UTC actual?

Brodie
fuente
1
¿ [NSDate date]Funcionaría? No estoy seguro de si es UTC.
zneak
2
No existe un NSDateconjunto de UTC, no tiene una zona horaria asociada.
Nick Forge
3
@MurraySagal Estás equivocado: NSDaterepresenta un instante en el tiempo (el nombre NSDatees algo inapropiado). Cuando se describe una hora como "el primer instante del 1 de enero de 2001", necesita una zona horaria para determinar de qué instante exacto está hablando, pero una vez que NSDatese crea, no hay una zona horaria asociada.
Nick Forge
1
@NickForge Una NSDate se crea como "el primer instante del 1 de enero de 2001, GMT", una hora específica en una zona horaria específica, y ese hecho es inmutable y de importancia crítica para explicar por qué las fechas funcionan como lo hacen. Si estamos en diferentes zonas horarias y lo registramos en el mismo momento, NSLog(@"since1970= %f", [[NSDate date] timeIntervalSince1970]);el resultado es el mismo. ¿Por qué? Porque es relativo a un momento específico en una zona horaria específica (GMT), sin importar dónde se encuentre el usuario. El hecho de que sea relativo a GMT no desaparece una vez creado. Sin este ancla, las fechas serían arbitrarias.
Murray Sagal
2
@MurraySagal Ambos tienen razón de diferentes maneras, pero Nick tiene más razón al decir "No existe un NSDateconjunto en UTC", porque no puede establecer la zona horaria de un NSDate, y se equivoca al decir eso. "tiene una zona horaria". Es cierto que se define en relación con una zona horaria específica, pero decir que "tiene" una zona horaria implica que la zona horaria es una propiedad de NSDate, y eso no es cierto.
devios1

Respuestas:

148

[NSDate date];

Es posible que desee crear una categoría que haga algo como esto:

-(NSString *)getUTCFormateDate:(NSDate *)localDate
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
    [dateFormatter setTimeZone:timeZone];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSString *dateString = [dateFormatter stringFromDate:localDate];
    [dateFormatter release];
    return dateString;
}
jessecurry
fuente
2
NSTimeZone * timeZone = [NSTimeZone timeZoneWithName: @ "UTC"]; [dateFormatter setTimeZone: timeZone]; eso lo clavó gracias
Brodie
1
si esto se está moviendo a producción, es posible que desee crear un dateFormatter estático que se inicialice de forma diferida. La creación de un formato de fecha es en realidad algo costosa.
jessecurry
3
Lo necesito como objeto de fecha, no como cadena, ¿qué puedo hacer en este caso?
Maystro
1
Las fechas existen independientemente de las zonas horarias, la zona horaria solo se utiliza para producir productos para el consumo humano.
jessecurry
@jessecurry No es del todo cierto. De la referencia de la clase NSDate: "Este método devuelve un valor de tiempo relativo a una fecha de referencia absoluta: el primer instante del 1 de enero de 2001, GMT". Tenga en cuenta la referencia clara y específica a GMT.
Murray Sagal
13

NSDate es una referencia a un intervalo desde una fecha de referencia absoluta, el 1 de enero de 2001 a las 00:00 GMT. Entonces, el método de clase [NSDate date] devolverá una representación de ese intervalo. Para presentar esos datos en un formato textual en UTC, simplemente use NSDateFormatter con el NSTimeZone (UTC) apropiado para renderizar según sea necesario.

rcw3
fuente
3
Creo que [NSDate ahora] debería ser [NSDate date] en esta respuesta.
lechuga plegable
2

Los objetos NSDate encapsulan un solo punto en el tiempo, independientemente de cualquier sistema de calendario o zona horaria en particular. Los objetos de fecha son inmutables y representan un intervalo de tiempo invariante en relación con una fecha de referencia absoluta (00:00:00 UTC del 1 de enero de 2001).

Versión rápida:

extension NSDate {
    func getUTCFormateDate() -> String {
        let dateFormatter = NSDateFormatter()
        let timeZone = NSTimeZone(name: "UTC")
        dateFormatter.timeZone = timeZone
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return dateFormatter.stringFromDate(self)
    }
}
Tikhonov Alexander
fuente