【Swift】日付から干支と12星座を識別するプログラムの作り方と計算方法!
この記事からわかること
- Swiftで日付から干支と
12星座 を識別する方法
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
Swiftで任意の日付の干支や12星座を識別するプログラムを作る方法をまとめていきます。まずはどの言語でも使えるように基本的な計算方法をみていきます。
干支の計算方法
干支にはそもそも「十干(じっかん)」と「十二支(じゅうにし)」の2種類がありますが今回は十二支を識別する場合をみていきます。
十二支の種類
子・丑・寅・卯・辰・巳・午・未・申・酉・戌・亥
十二支は全部で12種類あり、12年で一周します。なので西暦を12で割った余りの数で十二支を識別することができます。
2016 ÷ 12 = 168 ... 0
2017 ÷ 12 = 168 ... 1
2022 ÷ 12 = 168 ... 6
2022年は「寅年」なので余りが6の時は寅ということになります。なので子(ねずみ)は4、そのまま順番に567..と増えていく感じになります。
ちなみに十干は以下の通りです。
十干の種類
甲・乙・丙・丁・戊・己・庚・辛・壬・癸
12星座の計算方法
誕生日の12星座は「黄道十二星座」と呼ばれる実在する星座が元になっています。干支は西暦でしたが12星座は日付で分かれています。
日付から12星座を識別するのは簡単で各星座ごとに当てはまる期間が決まっているのでその期間内かどうかを識別すればOKです。
星座 | 誕生日 |
---|---|
おひつじ座(牡羊座) | 3/21~4/19 |
おうし座(牡牛座) | 4/20~5/20 |
ふたご座(双子座) | 5/21~6/21 |
かに座(蟹座) | 6/22~7/22 |
しし座(獅子座) | 7/23~8/22 |
おとめ座(乙女座) | 8/23~9/22 |
てんびん座(天秤座) | 9/23~10/23 |
さそり座(蠍座) | 10/24~11/22 |
いて座(射手座) | 11/23~12/21 |
やぎ座(山羊座) | 12/22~1/19 |
みずがめ座(水瓶座) | 1/20~2/18 |
うお座(魚座) | 2/19~3/20 |
Swiftでの干支識別コード
ここからはSwiftを使用した場合のコードを記載していきます。
渡された日付の十二支を返すコード
func zodiac(_ date:Date) -> String {
let df = DateFormatter()
df.dateFormat = "yyyy/MM/dd"
df.locale = Locale(identifier: "ja_JP")
let nowYear = df.string(from: date).prefix(4)
guard Int(nowYear) != nil else {
// 文字列の場合
return "..."
}
let num = Int(nowYear)! % 12
switch num {
case 4:
return "ねずみ"
case 5:
return "うし"
case 6:
return "とら"
case 7:
return "うさぎ"
case 8:
return "たつ"
case 9:
return "へび"
case 10:
return "うま"
case 11:
return "ひつじ"
case 0:
return "さる"
case 1:
return "とり"
case 2:
return "いぬ"
case 3:
return "いのしし"
default:
return "..."
}
}
解説
メソッド名「zodiac」は日本語で「干支」という意味です。引数に日付型(Date)の値を受け取り公式に当てはめて余りを算出しています。
Date型→String型→Int型
の順番にキャストしていき計算できるようにしています。一応String型→Int型
へのキャストはエスケープできるようにして起きました。
Swiftでは余りを%
で算出できます。
Swiftで12星座識別コード
渡された日付の12星座を返す
func signOfZodiac(_ date:Date) -> String {
let df = DateFormatter()
df.dateFormat = "yyyy/MM/dd"
df.locale = Locale(identifier: "ja_JP")
let thisYear = df.string(from: date).prefix(4)
let nowYear = "\(thisYear)/" // "2023/" ←スラッシュまで抜き出す
let lateYear = "\(Int(thisYear)! + 1)/" // "2024/" 翌年形式
switch date {
case df.date(from: String(nowYear + "3/21"))!...df.date(from: String(nowYear + "4/20"))!:
return "おひつじ座"
case df.date(from: String(nowYear + "4/20"))!...df.date(from: String(nowYear + "5/21"))!:
return "おうし座"
case df.date(from: String(nowYear + "5/21"))!...df.date(from: String(nowYear + "6/22"))!:
return "ふたご座"
case df.date(from: String(nowYear + "6/22"))!...df.date(from: String(nowYear + "7/23"))!:
return "かに座"
case df.date(from: String(nowYear + "7/23"))!...df.date(from: String(nowYear + "8/23"))!:
return "しし座"
case df.date(from: String(nowYear + "8/23"))!...df.date(from: String(nowYear + "9/23"))!:
return "おとめ座"
case df.date(from: String(nowYear + "9/23"))!...df.date(from: String(nowYear + "10/24"))!:
return "てんびん座"
case df.date(from: String(nowYear + "10/24"))!...df.date(from: String(nowYear + "11/23"))!:
return "さそり座"
case df.date(from: String(nowYear + "11/23"))!...df.date(from: String(nowYear + "12/22"))!:
return "いて座"
case df.date(from: String(nowYear + "12/22"))!...df.date(from: String(lateYear + "1/1"))!:
return "やぎ座"
case df.date(from: String(nowYear + "1/1"))!...df.date(from: String(nowYear + "1/20"))!:
return "やぎ座"
case df.date(from: String(nowYear + "1/20"))!...df.date(from: String(nowYear + "2/19"))!:
return "みずがめ座"
case df.date(from: String(nowYear + "2/19"))!...df.date(from: String(nowYear + "3/21"))!:
return "うお座"
default:
return "..."
}
}
※やぎ座に関しては12/22〜1/19までですがswitch文の仕様上、範囲を指定する値が「低 < 高」とする必要があり、以下のようなエラーが発生するため2つに分割しています。
Thread 1: Fatal error: Can't form Range with upperBound < lowerBound
2023/2/21 追記:12/22~1/1にしないと12/31がマッチしなかったので修正しました。
解説
メソッド名「signOfZodiac
」は日本語で「十二星座」という意味です。こちらも引数に日付型(Date)の値を受け取ります。
12星座に該当する日付は決まってますが、年を固定値で定義すると範囲外になってしまうので引数として渡された日付の年だけ(スラッシュも含む)を取得しはめ込んでいます。
switch文では...
(閉範囲演算子)を使って条件にレンジ(範囲)を指定できるのでDate型の日付範囲を定義しています。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。
私がSwift UI学習に使用した参考書
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。