NSDate - convertir la Date en GMT

j'ai besoin de la possibilité de convertir une valeur NSDate à une date GMT.

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

50
demandé sur Krunal 2009-12-08 00:10:28

6 réponses

    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
répondu Howard 2010-01-13 16:58:46

travailler avec le temps dans le cacao peut être compliqué. Lorsque vous obtenez un objet NSDate , il est dans le fuseau horaire local. [[NSTimeZone defaultTimeZone] secondsFromGMT] vous donne le décalage du fuseau horaire de GMT. Alors vous pouvez faire ceci:

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 voulez, et ensuite, appelez stringFromDate: pour obtenir une chaîne bien formatée.

42
répondu Alex 2009-12-07 21:32:07

la réponse de Howard est correcte et veuillez La voter et l'accepter.

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

dans de nombreux langages de programmation, les objets date sont utilisés pour représenter des points uniques dans le temps. En ignorant les arguments relativistes on peut supposer qu'à n'importe quel moment nous pouvons définissez un point dans le temps qui est égal universellement pour chacun, quelle que soit la façon dont nous mesurons le temps.

si pour chaque point dans le temps nous pouvions construire une étiquette unique, cette étiquette pourrait être transmise et référencée sans ambiguïté. le but des objets 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 système d'étiquetage et comment chaque date object choisit de le faire est sans importance pour quiconque les utilise.

un exemple pourrait être d'utiliser un décalage numérique d'un événement universel ( X secondes depuis l'explosion du soleil ).

ce n'est que lorsque nous voulons prendre un time point et le sérialiser en une chaîne lisible par l'homme que nous devons traiter les complexités des fuseaux horaires, des locales, etc...

( Local Chaîne De Date ) + ( Date De Formateur ) => Point De Temps

Point De Temps + ( Date De Formateur ) => ( Local Chaîne De Date )

chaque point temporel est universel... il n'y a rien de tel qu'un Heure de new york , ou heure gmt , seulement une fois que vous convertissez un point de temps à une chaîne locale (en utilisant un formatteur de date) Ne toute association à un fuseau horaire apparaît.

Note: je suis sûr qu'il y a de nombreux blogs/articles sur cette même question, mais mon Google foo me lâche à cette heure. Si quelqu'un a l'enthousiasme nécessaire pour développer cette question, n'hésitez pas à le faire.

16
répondu Akusete 2017-05-23 12:33:50

bien que la réponse d'Alex ait été un bon début, elle ne traitait pas de L'heure avancée (DST) et a ajouté une conversion inutile à/de la date de référence. Les œuvres suivantes pour moi:

pour passer d'une date locale à GMT, en tenant compte de DST:

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

pour passer d'une date GMT à une date locale, en tenant compte de DST:

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

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

5
répondu thevoid 2010-08-09 21:46:25

avez-vous essayé de regarder la documentation pour NSDateFormatter?

NSDateFormatter

NSDateFormatter semble avoir quelques méthodes pour jouer avec les fuseaux horaires, en particulier

-setTimeZone:

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

3
répondu Jasarien 2009-12-07 21:33:01

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

}
3
répondu Krunal 2018-01-09 11:13:16