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のコード
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