ios - reloj - Obtenga la hora UTC y la hora local del objeto NSDate
reloj analogico hora actual (9)
En este momento (con los últimos cambios en Swift), NSDate.date()
ya no está disponible.
En su lugar, solo necesita inicializar NSDate
para obtener la fecha y hora actuales.
Para probarlo, en un parque infantil:
var d = NSDate()
d
y obtendrá:
Oct 22, 2014, 12:20 PM"
En object-c, el siguiente código da como resultado la información de fecha y hora UTC usando la API de date
.
NSDate *currentUTCDate = [NSDate date]
En Swift sin embargo,
let date = NSDate.date()
resultados en fecha y hora local.
Tengo dos preguntas:
- ¿Cómo puedo obtener la hora UTC y la hora local (la
date
correcta da la hora local) en los objetosNSDate
? - ¿Cómo puedo obtener precisión por segundos del objeto
NSDate
?
EDIT 1: Gracias por todas las entradas, pero no estoy buscando objetos NSDateFormatter
o valores de cadena. Simplemente estoy buscando objetos NSDate (sin embargo los cocinamos pero ese es el requisito).
Ver punto 1.
Encontré una forma más fácil de obtener UTC en Swift4. Pon este código en el patio
let date = Date()
*//"Mar 15, 2018 at 4:01 PM"*
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
let newDate = dateFormatter.string(from: date)
*//"2018-03-15 21:05:04 +0000"*
La documentación dice que el método de date
devuelve una nueva fecha establecida a la fecha y hora actual independientemente del idioma utilizado.
El problema probablemente se encuentra en algún lugar donde presentas la fecha utilizando NSDateFormatter
. NSDate
es solo un punto en una línea de tiempo. No hay zonas horarias cuando se habla de NSDate
. Hice una prueba.
Rápido
print(NSDate())
Salida: 2014-07-23 17:56:45 +0000
C objetivo
NSLog(@"%@", [NSDate date]);
Salida: 2014-07-23 17:58:15 +0000
Resultado - No hay diferencia.
Mi Xcode Versión 6.1.1 (6A2008a)
En el patio de recreo, prueba así:
// I''m in East Timezone 8
let x = NSDate() //Output:"Dec 29, 2014, 11:37 AM"
let y = NSDate.init() //Output:"Dec 29, 2014, 11:37 AM"
println(x) //Output:"2014-12-29 03:37:24 +0000"
// seconds since 2001
x.hash //Output:441,517,044
x.hashValue //Output:441,517,044
x.timeIntervalSinceReferenceDate //Output:441,517,044.875367
// seconds since 1970
x.timeIntervalSince1970 //Output:1,419,824,244.87537
una fecha es independiente de cualquier zona horaria, así que use un Dateformatter y adjunte una zona horaria para mostrar:
rápido:
let date = NSDate()
let dateFormatter = NSDateFormatter()
let timeZone = NSTimeZone(name: "UTC")
dateFormatter.timeZone = timeZone
println(dateFormatter.stringFromDate(date))
objC:
NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeZone:timeZone];
NSLog(@"%@", [dateFormatter stringFromDate:date]);
NSDate
es un punto específico en el tiempo sin una zona horaria . Piense en ello como el número de segundos que han pasado desde una fecha de referencia. ¿Cuántos segundos han pasado en una zona horaria en comparación con otra desde una fecha de referencia en particular? La respuesta es la misma.
Dependiendo de cómo emita esa fecha (incluso mirando al depurador), puede obtener una respuesta en una zona horaria diferente.
Si se ejecutaron en el mismo momento, los valores de estos son los mismos. Ambos son el número de segundos desde la fecha de referencia, que pueden tener formato en la salida a UTC o hora local. Dentro de la variable de fecha, ambos son UTC.
C objetivo:
NSDate *UTCDate = [NSDate date]
Rápido:
let UTCDate = NSDate.date()
Para explicar esto, podemos usar un NSDateFormatter en un patio de recreo:
import UIKit
let date = NSDate.date()
// "Jul 23, 2014, 11:01 AM" <-- looks local without seconds. But:
var formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
let defaultTimeZoneStr = formatter.stringFromDate(date)
// "2014-07-23 11:01:35 -0700" <-- same date, local, but with seconds
formatter.timeZone = NSTimeZone(abbreviation: "UTC")
let utcTimeZoneStr = formatter.stringFromDate(date)
// "2014-07-23 18:01:41 +0000" <-- same date, now in UTC
La fecha de salida varía, pero la fecha es constante. Esto es exactamente lo que estás diciendo. No hay tal cosa como un NSDate local.
En cuanto a cómo obtener microsegundos, puedes usar esto (ponlo en la parte inferior del mismo campo de juego):
let seconds = date.timeIntervalSince1970
let microseconds = Int(seconds * 1000) % 1000 // chops off seconds
Para comparar dos fechas, puede usar date.compare(otherDate)
.
Swift 3
Puede obtener la fecha según su zona horaria actual de UTC
extension Date {
func currentTimeZoneDate() -> String {
let dtf = DateFormatter()
dtf.timeZone = TimeZone.current
dtf.dateFormat = "yyyy-MM-dd HH:mm:ss"
return dtf.string(from: self)
}
}
Llama así:
Date().currentTimeZoneDate()
Xcode 9 • Swift 4 o Swift 3 :
let date = Date() // default is UTC.
Este código da fecha en UTC. Si necesita la hora local, debe llamar a la siguiente extensión con la zona Timezone.current
como Timezone.current
extension Date {
var currentUTCTimeZoneDate: String {
let formatter = DateFormatter()
formatter.timeZone = TimeZone(identifier: "UTC")
formatter.amSymbol = "AM"
formatter.pmSymbol = "PM"
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
return formatter.string(from: self)
}
}
Para la hora UTC, Date().currentUTCTimeZoneDate
como: Date().currentUTCTimeZoneDate
Xcode 9 • Swift 4 (también funciona Swift 3.x)
extension Formatter {
// create static date formatters for your date representations
static let preciseLocalTime: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "HH:mm:ss.SSS"
return formatter
}()
static let preciseGMTTime: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "HH:mm:ss.SSS"
return formatter
}()
}
extension Date {
// you can create a read-only computed property to return just the nanoseconds from your date time
var nanosecond: Int { return Calendar.current.component(.nanosecond, from: self) }
// the same for your local time
var preciseLocalTime: String {
return Formatter.preciseLocalTime.string(for: self) ?? ""
}
// or GMT time
var preciseGMTTime: String {
return Formatter.preciseGMTTime.string(for: self) ?? ""
}
}
Prueba de juegos
Date().preciseLocalTime // "09:13:17.385" GMT-3
Date().preciseGMTTime // "12:13:17.386" GMT
Date().nanosecond // 386268973
Esto podría ayudarte a formatear también tus fechas: