【Swift】TimeZone初期化時の注意点 【サマータイム】
TimeZoneの初期化
日本時間はグリニッジ標準時となるGMTより +9時間 した時間となります。
swiftのDate型はGMT基準となるため、DateFormatter等で文字列に変換する場合
TimeZoneを日本時間に指定する必要があります。
TimeZoneの初期化には、identifierの指定と、GMTからの時間差で指定する方法があり、
どちらにしても結果的に時間を +9時間調整するので、好きな方を使って構いません。
TimeZone(identifier: "Asia/Tokyo")
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
上部のラベルは、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/2/24 00:00:00
となっています。
1951 年 9 月 8 日
次はApple本社付近のサンフランシスコにあやかり、
サンフランシスコ講和条約が締結された日にさかのぼってみます。
1951/9/8 00:00:00
!!??
なんということでしょう!!
ラベルへの変換が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
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)
}
}
becky3/timezone_summertime_test: 日本におけるサマータイムの影響について確認するプロジェクト
https://github.com/becky3/timezone_summertime_test
Author And Source
この問題について(【Swift】TimeZone初期化時の注意点 【サマータイム】), 我々は、より多くの情報をここで見つけました https://qiita.com/beckyJPN/items/a5c6612cc15b2596971e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .