web-dev-qa-db-fra.com

Obtenir l'heure UTC et l'heure locale de l'objet NSDate

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:

  1. Comment obtenir l'heure UTC et l'heure locale (ainsi date donne l'heure locale) dans les objets NSDate.
  2. Comment puis-je obtenir une précision de secondes pour l'objet 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.

59
p0lAris

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.

Swift

print(NSDate())

Sortie: 2014-07-23 17:56:45 +0000

Objectif c

NSLog(@"%@", [NSDate date]);

Sortie: 2014-07-23 17:58:15 +0000

Résultat - Aucune différence.

28
RaffAl

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).

62
Steven Fisher

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:

enter image description here

41
Leo Dabus

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]);
22
Daij-Djan
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. enter image description here

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

19
abhimuralidharan

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"  
12
Ali

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()
7
Piyush Sanepara

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
4
fujianjin6471

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"*
1
Usuf

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");
0
Asad Ali Choudhry