LoginSignup
4
4

More than 3 years have passed since last update.

【Swift】TimeZone初期化時の注意点 【サマータイム】

Last updated at Posted at 2019-07-03

TimeZoneの初期化

日本時間はグリニッジ標準時となるGMTより +9時間 した時間となります。
swiftのDate型はGMT基準となるため、DateFormatter等で文字列に変換する場合
TimeZoneを日本時間に指定する必要があります。

TimeZoneの初期化には、identifierの指定と、GMTからの時間差で指定する方法があり、
どちらにしても結果的に時間を +9時間調整するので、好きな方を使って構いません。

identifier
TimeZone(identifier: "Asia/Tokyo")
GMT
TimeZone(secondsFromGMT: 9 * 60 * 60) // 9時間分の秒数

TimeZone - Foundation | Apple Developer Documentation
https://developer.apple.com/documentation/foundation/timezone

TimeZoneの動作検証

と思ってたんですが、
実は、それぞれの指定で時間の表現に差が出てしまうのです。。。

試しに、UIDatePickerで設定した時間をラベルに表示しながら確認してみましょう。。

1970 年 1 月 1 日

では、まず UNIX時間の下限値である 1970年から。
1970/1/1 00:00:00
1970.png
上部のラベルは、DatePickerで選択した日付をDateFormatterでStringに変換して
表示しています。

また、DatePickerのTimeZoneはidentifier: "Asia/Tokyo"で指定しており、
DateFormatterはsecondsFromGMT: 9 * 60 * 60で指定しています。

どちらも+9時間調整なので、表記は当然1970/1/1 00:00:00となっています。

1955 年 2 月 24 日

更に時をさかのぼり、iPhoneを作ったスティーブジョブスの誕生日にしてみましょう。
1955/2/24 00:00:00
1955.png
こちらも、問題なく1955/2/24 00:00:00となっています。

1951 年 9 月 8 日

次はApple本社付近のサンフランシスコにあやかり、
サンフランシスコ講和条約が締結された日にさかのぼってみます。
1951/9/8 00:00:00
1951.png

!!??
なんということでしょう!!
ラベルへの変換が1951/9/7 23:00:00となってしましました・・・

どちらも日本時間なのはずなのに。。

日本におけるサマータイム

というわけで、identifierでの指定とsecondsFromGMTの指定で
1時間の差異がでてしまいました。

実は 1950年あたりで日本ではサマータイムが採用されていたため、
この差が生まれるようです。

70年前の日本で実施されていた「サマータイム」が3年で廃止された理由
https://www.buzzfeed.com/jp/kotahatachi/summer-time-1948

具体的に説明すると、identifierでの指定の場合、日本という地域での指定になります。
一方、GMTでの指定の場合、標準時との時間差での指定になるので、日本という情報がありません。
そのため、サマータイム調整が発生しないようです。

サマータイムの期間

サマータイムの具体的な期間については、国立天文台のwikiにまとめてありました。

期間
昭和23年 (1948) 5/1 12:00 ~ 9/12 0:00
昭和24年 (1949) 4/2 12:00 ~ 9/11 0:00
昭和25年 (1950) 5/6 12:00 ~ 9/10 0:00
昭和26年 (1951) 5/5 12:00 ~ 9/9 0:00

暦Wiki/時刻/夏時刻 - 国立天文台暦計算室
https://eco.mtk.nao.ac.jp/koyomi/wiki/BBFEB9EF2FB2C6BBFEB9EF.html

identifier: "Asia/Tokyo"でこの期間を利用した場合、
サマータイムと認識され、1時間マイナスされてしまいます。。
(サマータイム期間なので1時間足されているはずという前提で 結果1時間引いた値になる)

以前、2020年の東京オリンピックに向けてサマータイムを導入しようと言う議論がありましたが、
実はすでに日本で採用された実績があり、結果的に辞めて欲しい意見が多く4年で終了していたんですね。。

なぜこれをまた採用しようと思ったのか・・・

と、それはどうでもよく、日本にはサマータイムがあったため、
TimeZoneの指定には気をつけましょうという話でした。

特別な理由がなければ、TimeZoneの初期化時はGMTで統一しておいた方が
変な問題に悩まされなくて良いかもですね。

今回実験したViewControllerのコード

ViewController.swift

import UIKit

class ViewController: UIViewController {

    let adjustSecondsForJapan : TimeInterval = 9 * 60 * 60

    @IBOutlet weak var datePicker: UIDatePicker!
    @IBOutlet weak var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        setupDatePicker()
    }

    private func setupDatePicker() {
        datePicker.datePickerMode = .date
        datePicker.timeZone = TimeZone(identifier: "Asia/Tokyo")
        datePicker.date = Date(timeIntervalSince1970: -adjustSecondsForJapan)
        datePicker.locale = Locale(identifier: "ja-JP")
    }

    private func getDateStrings(from date: Date) -> String {
        let formatter = DateFormatter()
        formatter.timeZone = TimeZone(secondsFromGMT: Int(adjustSecondsForJapan))
        formatter.dateFormat = "yyyy/MM/dd HH:mm:ss"
        return formatter.string(from: date)

    }

    @IBAction func didChangeDatePicker(_ sender: UIDatePicker) {

        label.text = getDateStrings(from: sender.date)

    }
}

github

becky3/timezone_summertime_test: 日本におけるサマータイムの影響について確認するプロジェクト
https://github.com/becky3/timezone_summertime_test

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4