Dans Objective-c, le code suivant génère les informations de date et heure UTC à l'aide de l'API date
.
NSDate *currentUTCDate = [NSDate date]
Dans Swift cependant,
let date = NSDate.date()
résultats en date et heure locales.
J'ai deux questions:
date
donne l'heure locale) dans les objets NSDate
.NSDate
?.EDIT 1: Merci pour toutes les entrées mais je ne cherche pas les objets NSDateFormatter
ni les valeurs de chaîne. Je cherche simplement des objets NSDate (peu importe la façon dont nous les cuisinons, mais c'est la condition).
Voir le point 1.
La documentation indique que la méthode date
renvoie une nouvelle date à la date et à l'heure actuelles, quelle que soit la langue utilisée.
Le problème se situe probablement quelque part où vous présentez la date en utilisant NSDateFormatter
. NSDate
est juste un point sur une ligne de temps. Il n'y a pas de fuseau horaire quand on parle de NSDate
. J'ai fait un test.
print(NSDate())
Sortie: 2014-07-23 17:56:45 +0000
NSLog(@"%@", [NSDate date]);
Sortie: 2014-07-23 17:58:15 +0000
Résultat - Aucune différence.
NSDate
est un moment spécifique sans fuseau horaire. Considérez-le comme le nombre de secondes écoulées depuis une date de référence. Combien de secondes se sont écoulées dans un fuseau horaire par rapport à un autre depuis une date de référence donnée? La réponse est la même.
En fonction de votre sortie cette date (y compris en regardant le débogueur), vous pouvez obtenir une réponse dans un fuseau horaire différent.
S'ils ont fonctionné au même moment, les valeurs de ceux-ci sont les mêmes. Ils sont tous deux le nombre de secondes depuis la date de référence, qui peuvent être formatés en sortie en UTC ou en heure locale. Dans la variable de date, ils sont tous deux UTC.
Objectif c:
NSDate *UTCDate = [NSDate date]
Rapide:
let UTCDate = NSDate.date()
Pour expliquer cela, nous pouvons utiliser un NSDateFormatter dans un terrain de jeu:
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 sortie de la date varie, mais la date est constante. C'est exactement ce que vous dites. Il n'y a pas de NSDate local.
Pour savoir comment obtenir des microsecondes, vous pouvez l’utiliser (placez-le au bas du même terrain de jeu):
let seconds = date.timeIntervalSince1970
let microseconds = Int(seconds * 1000) % 1000 // chops off seconds
Pour comparer deux dates, vous pouvez utiliser date.compare(otherDate)
.
Xcode 9 • Swift 4 (fonctionne également 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) ?? ""
}
}
Test du terrain de jeu
Date().preciseLocalTime // "09:13:17.385" GMT-3
Date().preciseGMTTime // "12:13:17.386" GMT
Date().nanosecond // 386268973
Cela pourrait vous aider également à formater vos dates:
une date est indépendante de tout fuseau horaire, utilisez donc un Dateformatter et attachez un fuseau horaire pour l'affichage:
Rapide:
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]);
let date = Date()
print(date) // printed date is UTC
Si vous utilisez playground , utilisez une instruction print pour vérifier l'heure. Playground affiche l'heure locale jusqu'à ce que vous l'imprimiez. Ne comptez pas sur le panneau latéral droit du terrain de jeu.
Ce code donne la date en UTC. Si vous avez besoin de l'heure locale, vous devez appeler l'extension suivante avec le fuseau horaire sous la forme 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)
}
}
Pour l'heure UTC, utilisez-le comme suit: Date().currentUTCTimeZoneDate
Pour le moment (avec les dernières modifications apportées à Swift), NSDate.date()
n'est plus disponible.
Au lieu de cela, il vous suffit d’initialiser NSDate
pour obtenir la date et l’heure actuelles.
Pour l'essayer, dans un terrain de jeu:
var d = NSDate()
d
et vous obtiendrez:
Oct 22, 2014, 12:20 PM"
Swift
Vous pouvez obtenir la date en fonction de votre fuseau horaire actuel à partir 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)
}
}
Appelle comme ça:
Date().currentTimeZoneDate()
Mon Xcode Version 6.1.1 (6A2008a)
En terrain de jeu, testez comme ceci:
// 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
J'ai trouvé un moyen plus facile d'obtenir le format UTC dans Swift4. Mettez ce code dans la cour de récréation
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"*
En plus des autres réponses, vous pouvez écrire une extension pour la classe Date afin d’obtenir des données formatées dans TimeZone spécifique afin de les transformer en fonction d’utilité pour une utilisation ultérieure. Comme
extension Date {
func dateInTimeZone(timeZoneIdentifier: String, dateFormat: String) -> String {
let dtf = DateFormatter()
dtf.timeZone = TimeZone(identifier: timeZoneIdentifier)
dtf.dateFormat = dateFormat
return dtf.string(from: self)
}
}
Maintenant, vous pouvez l'appeler comme
Date().dateInTimeZone(timeZoneIdentifier: "UTC", dateFormat: "yyyy-MM-dd HH:mm:ss");