NSDate () o Date () muestra el momento incorrecto

Cuando bash registrar la fecha actual:

print(NSDate()) 

o

 print(Date()) 

(en Swift 3)

O cualquier objeto de fecha, muestra el momento incorrecto. Por ejemplo, ahora son alrededor de las 16:12, pero lo que se muestra arriba

 2016-10-08 20:11:40 +0000 

¿Mi fecha está en el huso horario equivocado? ¿Cómo arreglo mi fecha para tener la zona horaria correcta?

¿Por qué es eso y cómo solucionarlo? ¿Cómo puedo mostrar fácilmente una fecha arbitraria en mi zona horaria local, ya sea en las declaraciones de impresión o en el depurador?

(Tenga en cuenta que esta pregunta es un “timbre” para que pueda proporcionar una extensión simple de fecha / NSDate Swift 3 / Swift 2 que le permite mostrar fácilmente cualquier objeto de fecha en su zona horaria local.

NSDate (o Date en Swift 3) no tiene un huso horario. Registra un instante en el tiempo en todo el mundo.

Internamente, los objetos de fecha registran el número de segundos desde la “fecha de época”, o la Medianoche del 1 de enero de 2001 en Greenwich Mean Time , también conocido como UTC.

Normalmente pensamos en las fechas en nuestra zona horaria local.

Si registra una fecha usando

 print(NSDate()) 

El sistema muestra la fecha actual, pero lo expresa en UTC / Greenwich Mean Time. Entonces, el único lugar donde la hora se verá correcta es en esa zona horaria.

Obtiene el mismo problema en el depurador si emite el comando depurador

 e NSDate() 

Esto es un dolor Personalmente, me gustaría que iOS / Mac OS muestren fechas usando la zona horaria actual del usuario, pero no es así.

EDIT # 2:

Una mejora en mi uso anterior de cadenas localizadas que hace que sea un poco más fácil de usar es crear una extensión para la clase Date :

 extension Date { func localString(dateStyle: DateFormatter.Style = .medium, timeStyle: DateFormatter.Style = .medium) -> String { return DateFormatter.localizedString(from: self, dateStyle: dateStyle, timeStyle: timeStyle) } } 

De esta forma, puede usar una expresión como Date().localString() , o si solo desea imprimir la hora, puede usar Date().localString(dateStyle:.none)

EDITAR:

Acabo de descubrir que NSDateFormatter ( DateFormatter en Swift 3) tiene un método de clase localizedString. Eso hace lo que hace mi extensión a continuación, pero más simple y limpiamente. Aquí está la statement:

 class func localizedString(from date: Date, dateStyle dstyle: DateFormatter.Style, timeStyle tstyle: DateFormatter.Style) -> String 

Entonces simplemente usarías

 let now = Date() print (DateFormatter.localizedString( from: now, dateStyle: .short, timeStyle: .short)) 

Puedes prácticamente ignorar todo lo de abajo.


Creé una categoría de la clase NSDate (Date in swift 3) que tiene un método localDateString que muestra una fecha en la zona horaria local del usuario.

Aquí está la categoría en la forma Swift 3: (filename Date_displayString.swift)

 extension Date { @nonobjc static var localFormatter: DateFormatter = { let dateStringFormatter = DateFormatter() dateStringFormatter.dateStyle = .medium dateStringFormatter.timeStyle = .medium return dateStringFormatter }() func localDateString() -> String { return Date.localFormatter.string(from: self) } } 

Y en forma de Swift 2:

 extension NSDate { @nonobjc static var localFormatter: NSDateFormatter = { let dateStringFormatter = NSDateFormatter() dateStringFormatter.dateStyle = .MediumStyle dateStringFormatter.timeStyle = .MediumStyle return dateStringFormatter }() public func localDateString() -> String { return NSDate.localFormatter.stringFromDate(self) } } 

(Si prefiere un formato de fecha diferente, es bastante fácil modificar el formato utilizado por los formateadores de fecha. También es sencillo mostrar la fecha y la hora en cualquier zona horaria que necesite).

Sugeriría poner la versión Swift 2 / Swift 3 apropiada de este archivo en todos sus proyectos.

Puedes usar

Swift 2:

 print(NSDate().localDateString()) 

Swift 3:

 print(Date().localDateString())