web-dev-qa-db-fra.com

NSDate - Convertir la date en GMT

J'ai besoin de pouvoir convertir une valeur NSDate en une date GMT.

Comment puis-je convertir une valeur NSDate en une valeur NSDate au format GMT, indépendamment des paramètres régionaux de date que l'appareil iPhone utilise?

50
Mick
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm";

    NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
    [dateFormatter setTimeZone:gmt];
    NSString *timeStamp = [dateFormatter stringFromDate:[NSDate date]];
    [dateFormatter release];
132
Howard

Travailler avec le temps dans Cocoa peut être compliqué. Lorsque vous obtenez un objet NSDate, il se trouve dans le fuseau horaire local. [[NSTimeZone defaultTimeZone] secondsFromGMT] vous donne le décalage du fuseau horaire actuel par rapport à GMT. Ensuite, vous pouvez le faire:

NSDate *localDate = // get the date
NSTimeInterval timeZoneOffset = [[NSTimeZone defaultTimeZone] secondsFromGMT]; // You could also use the systemTimeZone method
NSTimeInterval gmtTimeInterval = [localDate timeIntervalSinceReferenceDate] - timeZoneOffset;
NSDate *gmtDate = [NSDate dateWithTimeIntervalSinceReferenceDate:gmtTimeInterval];

Maintenant, gmtDate devrait avoir la date correcte en GMT pour vous. Pour l'afficher, regardez NSDateFormatter, en particulier les méthodes setDateStyle et setTimeStyle. Vous créez un NSDateFormatter, le configurez comme vous le souhaitez, puis appelez stringFromDate: pour obtenir une chaîne bien formatée.

42
Alex

Réponse d'Howard est correct et veuillez voter et l'accepter.

Pour référence, je pense qu'il est utile d'expliquer la différence entre les objets de date et les représentations de date localisées.

Dans de nombreux langages de programmation, les objets de date sont utilisés pour représenter des moments uniques. Ignorant les arguments Relativistes , on peut supposer qu'à tout moment, nous pouvons définir un point dans le temps qui est universellement égal pour chacun, quelle que soit la façon dont nous mesurons le temps.

Si, à chaque instant, nous pouvions construire une étiquette unique, cette étiquette pourrait être contournée et référencée sans ambiguïté. Le but des objets de date est d'agir comme une étiquette universelle unique pour un moment donné .

On pourrait trouver un certain nombre de techniques pour construire un tel schéma d'étiquetage et la façon dont chaque objet de date choisit de le faire est sans importance pour quiconque les utilise.

Un exemple peut être d'utiliser un décalage numérique à partir d'un événement universel ( X secondes depuis l'explosion du Soleil).

Ce n'est que lorsque nous souhaitons prendre un point dans le temps et le sérialiser en une chaîne lisible par l'homme que nous devons gérer la complexité des fuseaux horaires, des paramètres régionaux, etc.

( Chaîne de date locale ) + ( Formateur de date ) => Point d'heure

Time Point + ( Formateur de date ) => ( Chaîne de date locale )

Chaque point de temps est universel ... il n'y a pas de point de temps new yorkais , ou heure gmt , ce n'est qu'une fois que vous convertissez un point temporel en une chaîne locale (à l'aide d'un formateur de date) qu'une association à un fuseau horaire apparaît.

Remarque: Je suis sûr qu'il existe de nombreux blogs/articles sur ce problème, mais mon google foo me fait défaut à cette heure. Si quelqu'un a l'enthousiasme pour développer ce problème, n'hésitez pas à le faire.

16
Akusete

Bien que la réponse d'Alex soit un bon début, elle ne traitait pas de l'heure d'été (heure d'été) et ajoutait une conversion inutile vers/à partir de la date de référence. Ce qui suit fonctionne pour moi:

Pour convertir une date locale en GMT, en tenant compte de l'heure d'été:

NSDate *localDate = <<your local date>>
NSTimeInterval timeZoneOffset = [[NSTimeZone systemTimeZone] secondsFromGMTForDate:localDate];
NSDate *gmtDate = [localDate dateByAddingTimeInterval:-timeZoneOffset]; // NOTE the "-" sign!

Pour convertir une date GMT en date locale, en tenant compte de l'heure d'été:

NSDate *gmtDate  = <<your gmt date>>
NSTimeInterval timeZoneOffset = [[NSTimeZone systemTimeZone] secondsFromGMTForDate:gmtDate];
NSDate *localDate = [gmtDate dateByAddingTimeInterval:timeZoneOffset];

Une petite remarque: j'ai utilisé dateByAddingTimeInterval, qui est uniquement iOS 4. Si vous utilisez OS 3 ou une version antérieure, utilisez addTimerInterval.

5
thevoid

Swift 4:

//UTC or GMT ⟺ Local 

extension Date {

    // Convert local time to UTC (or GMT)
    func toGlobalTime() -> Date {
        let timezone = TimeZone.current
        let seconds = -TimeInterval(timezone.secondsFromGMT(for: self))
        return Date(timeInterval: seconds, since: self)
    }

    // Convert UTC (or GMT) to local time
    func toLocalTime() -> Date {
        let timezone = TimeZone.current
        let seconds = TimeInterval(timezone.secondsFromGMT(for: self))
        return Date(timeInterval: seconds, since: self)
    }

}
4
Krunal

Avez-vous essayé de consulter la documentation de NSDateFormatter?

NSDateFormatter

NSDateFormatter semble avoir certaines méthodes pour jouer avec TimeZones, en particulier

-setTimeZone:

Je ne l'ai pas testé moi-même, mais j'imagine que si vous définissez GMT comme fuseau horaire à une date qui est à l'origine représentée dans un autre fuseau horaire, il affichera la date avec les ajustements corrects pour correspondre au nouveau fuseau horaire.

3
Jasarien