web-dev-qa-db-fra.com

Conversion de date entre les fuseaux horaires rapide

J'ai une date stockée sur la base de données de mon serveur en ligne qui est dans GMT. Je charge la date et la convertis dans le fuseau horaire de l'utilisateur à l'aide du code suivant: 

 if let messagedate = oneitem["timestamp"] as? String {
     let dateFormatter = NSDateFormatter()
     dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
     let date = dateFormatter.dateFromString(messagedate)
     let source_timezone = NSTimeZone(abbreviation: "GMT")
     let local_timezone = NSTimeZone.systemTimeZone()
     let source_EDT_offset = source_timezone?.secondsFromGMTForDate(date!)
     let destination_EDT_offset = local_timezone.secondsFromGMTForDate(date!)
     let time_interval : NSTimeInterval = Double(destination_EDT_offset - source_EDT_offset!)


     let final_date = NSDate(timeInterval: time_interval, sinceDate: date!)
     curr_item.date = final_date
 }

Maintenant, je dois reconvertir la date en GMT afin de la communiquer au serveur, mais je ne sais pas comment la reconvertir en GMT.

10
Alk

Ne pourriez-vous pas simplement réutiliser votre formateur de données avec un fuseau horaire différent et le convertir? Tel que 

dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT")
let gmtDate = dateFormatter.dateFromString(string: "your old date as string here")
15
Amloelxer

environ 50 fois plus efficace

extension Date {
    func convertToLocalTime(fromTimeZone timeZoneAbbreviation: String) -> Date? {
        if let timeZone = TimeZone(abbreviation: timeZoneAbbreviation) {
            let targetOffset = TimeInterval(timeZone.secondsFromGMT(for: self))
            let localOffeset = TimeInterval(TimeZone.autoupdatingCurrent.secondsFromGMT(for: self))

            return self.addingTimeInterval(targetOffset - localOffeset)
        }

        return nil
    }
}
9
quemeful

Version simplifiée:

extension Date {
    func convertToTimeZone(initTimeZone: TimeZone, timeZone: TimeZone) -> Date {
         let delta = TimeInterval(timeZone.secondsFromGMT() - initTimeZone.secondsFromGMT())
         return addingTimeInterval(delta)
    }
}
5
mukaissi

Puisque NSDate est toujours en GMT/UTC, le fuseau horaire n’est pertinent que pour l’afficher ou l’obtenir de l’utilisateur. Supposez simplement que c'est UTC en interne, convertissez-le pour l'utilisateur (en le réglant sur NSDateFormatter) si nécessaire, et vous n'aurez plus à vous soucier du problème.

3
David Berry

Basé sur la réponse de mukaissi , mais l'ordre de franchise dans l'expression a été corrigé.

extension Date {    
    func convert(from initTimeZone: TimeZone, to targetTimeZone: TimeZone) -> Date {
        let delta = TimeInterval(initTimeZone.secondsFromGMT() - targetTimeZone.secondsFromGMT())
        return addingTimeInterval(delta)
    }    
}
0
Nikaaner

Je suggère

  • vous définissez le fuseau horaire GMT sur votre dateFormatter pour récupérer directement un NSDate au format UTC (il est conseillé de ne disposer que de NSDates au format UTC)
  • lorsque vous devez l'afficher, vous utilisez un autre NSDateFormatter avec le fuseau horaire local défini (c'est par défaut)
  • lorsque vous devez envoyer une date à votre serveur, vous utilisez à nouveau dateFormatter pour générer une chaîne.
0
PierreMB