DateFormatter
のshortWeekdaySymbols
から曜日を表示するコードを書いているときに意図する曜日が取得できず「あれ?」となったので備忘のために記事を書きました。
概要
-
Calendar
のcomponent(_:from:)
に.weekday
を渡した戻り値(Int
)をそのままshortWeekdaySymbols
のindexとして利用 - 意図しない曜日が取れたり、落ちたりした
-
weekday
は1始まりなので-1
しないとweekdaySymbols
やshortWeekdaySymbols
のindexとして使えない
以下詳しく書いていきます。
現象
- 意図する曜日が取得できない
- 落ちることもある
上手くいかなかったのは下記コードです。
意図する曜日が取得できない or 落ちる例
/// 引数から日時の文字列を返す
func createDateString(date: Date, calendar: Calendar) -> String {
let dateFormater = DateFormatter()
dateFormater.locale = Locale(identifier: "ja_JP")
let weekdayIndex = calendar.component(.weekday, from: date)
dateFormater.dateFormat = "M月d日 \(dateFormater.shortWeekdaySymbols[weekdayIndex]) H:mm"
return dateFormater.string(from: date)
}
原因
-
Calendar
のcomponent(_:from:)
に.weekday
を渡した戻り値(Int
)をそのままshortWeekdaySymbols
のindexとして利用していたこと
weekday
は1始まりなのでした。
そのためcomponent(_:from:)
で取得した値をそのままindexとして使うと0始まりの配列であるweekdaySymbols
やshortWeekdaySymbols
とズレが生じてしまいます。
- 意図する曜日が取得できない
- 1始まりと0始まりのズレが原因
- 落ちることもある
- 配列の範囲を超えた値が渡される可能性があるため(7が渡されると落ちる)
対応
原因がわかれば対応は簡単ですね。
weekday
の値を-1
してあげればズレがなくなります。
修正例
/// 引数から日時の文字列を返す
func createDateString(date: Date, calendar: Calendar) -> String {
let dateFormater = DateFormatter()
dateFormater.locale = Locale(identifier: "ja_JP")
// .weekdayは1から始まるので、indexとして利用するために - 1 する
let weekdayIndex = calendar.component(.weekday, from: date) - 1
dateFormater.dateFormat = "M月d日 \(dateFormater.shortWeekdaySymbols[weekdayIndex]) H:mm"
return dateFormater.string(from: date)
}
サンプルコード
サンプルコードをGitHubにあげたので、実際に触りたい方はこちらからどうぞ。
https://github.com/taguchi-k/ios-weekday-from-datepicker
開発環境
category | Version |
---|---|
Swift | 3.1 |
XCode | 8.3.2 |
参考