web-dev-qa-db-ja.com

タイムゾーン間の日付の変換swift

GMTにあるオンラインサーバーデータベースに保存されている日付があります。日付を読み込んで、次のコードを使用してユーザーのタイムゾーンに変換します:

 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
 }

ここで、サーバーに通信するために日付をGMTに戻す必要がありますが、GMTに戻す方法がわかりません。

12
Alk

別のタイムゾーンでデータフォーマッタを再度使用して変換することはできませんか?といった

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

約50倍の効率

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
    }
}
10
quemeful

よりシンプルなバージョン:

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

NSDateは常にGMT/UTCであるため、タイムゾーンは、ユーザーに表示するとき、またはユーザーから取得するときにのみ関連します。内部的には常にUTCであると想定し、必要に応じて(NSDateFormatterで設定することにより)ユーザー用に変換すれば、問題を心配する必要はなくなります。

4
David Berry

mukaissi's answer に基づいていますが、式の控除可能の順序は修正されています。

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

私は提案します

  • dateFormatterにGMTタイムゾーンを設定して、UTCのNSDateを直接取得します(UTCのNSDateのみを使用することをお勧めします)
  • 表示する必要がある場合は、ローカルタイムゾーンが設定された別のNSDateFormatterを使用します(デフォルトです)
  • サーバーに日付を送信する必要がある場合は、dateFormatterを再度使用して文字列を生成します
0
PierreMB