DatePickerDialogで日付選択 + 曜日表示 | Kotlin



DatePickerを使って日付選択を行う！ということをしていたところ、
あれ？曜日が表示されない。
曜日出そうと試行錯誤しても、番号だけ表示される....
ということにぶち当たってしまいました:frowning2:

結論、
DatePickerDialogで日付表示をさせて、
その日付から曜日を求めている感じで落ち着いた。

ただ、DatePickerではCalenderを使用していますが、
曜日表示するところではLocalDateを使用しているので、
良くないとかあるのかな？という疑問は残ってる。

ので、これで良いのか悪いのか、もしよろしければ何故良くないのか、普通はこうやってやるんだよ～って教えてくださる方がいたら嬉しいです:pray:
(おかしくないよ！って事もお知らせいただけると安心します..)


## 完成図

![DatePicker選択前.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2499099/2ec702b5-3b09-51bd-f020-ad89877d3b80.jpeg)
初期値に今日の日付が入ったEditTextを表示
![DatePickerDialog.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2499099/f8c9f186-7f2a-566d-e809-19d102501e71.jpeg)
DatePickerが表示されて、好きな日を選ぶ
![DatePicker選択後.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2499099/18d1fc42-0e41-cee2-bf84-b90f448c823e.jpeg)
選んだ日付が曜日付きで表示される


(TryFireStoreなのは無視で...)


## Fragment

```xml:fragment_input.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <EditText
        android:id="@+id/date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginTop="16dp"
        android:layout_marginStart="16dp"
        />
  </androidx.constraintlayout.widget.ConstraintLayout>

```

タップで日付が表示されるEditTextを設置

```Kotlin:InputFragment.kt
class InputFragment() : Fragment() {


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        super.onCreateView(inflater, container, savedInstanceState)

        return inflater.inflate(R.layout.fragment_input, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        /**
         * 日付の初期値設定
         * 値：現在日付
         * 表示：yyyy年MM月dd日(E)
         */

        //Editテキストを取得
        val date = view.findViewById<EditText>(R.id.date)
        //現在日付を取得
        val current = LocalDate.now()
        //表示する際のフォーマットを決める
        val formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日(E)")
        //現在日付をフォーマットに合わせる
        val dateFormat = current.format(formatter)

        //キーボードを表示させない
        date.setRawInputType(InputType.TYPE_NULL)
        //EditTextに現在日付を表示
        date.setText(dateFormat.toString())

        /**
         * 日付の変更
         * 値：選択された日付
         * 表示：yyyy年MM月dd日(E)
         */

        //EditTextがタップされた時
        date.setOnClickListener {
            //DatePickerFragmentのインスタンスを作成
            //EditTextを渡す
            val datePicker = DatePickerFragment(date)
            //FragmentManagerを取得する
            val fragmentManager = requireActivity().supportFragmentManager
            //DatePickerを表示
            datePicker.show(fragmentManager,"DatePickerDialog")
        }
    }
}
```

これが今回の最初に表示されるFragmentの内容
コード全部載せたけど、この時点ではDatePickerDialogを作成していないので
エラー出ます:point_up:

## DatePickerDialog


```Kotlin:InputFragment.kt

class DatePickerFragment(private val editText: EditText): DialogFragment(),DatePickerDialog.OnDateSetListener{

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {

        //Calender()を取得
        val calendar: Calendar = Calendar.getInstance()
        //年を示すフィールドの値を取得
        val year = calendar.get(Calendar.YEAR)
        //月を示すフィールドの値を取得
        val month = calendar.get(Calendar.MONTH)
        //日を示すフィールドの値を取得
        val day = calendar.get(Calendar.DAY_OF_MONTH)

        //指定された日付でDatePickerを作成して返す
        return DatePickerDialog(
            requireContext(),
            this,
            year,
            month,
            day
        )
    }

//日付選択がされた時の処理
    override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
        //DatePickerにて選択された日付(年月日)をもとにLocalDateのインスタンスを取得
        val setLocalDate = LocalDate.of(year,month+1,dayOfMonth)
        //表示する際のフォーマットを決める
        val format = DateTimeFormatter.ofPattern("yyyy年MM月dd日(E)")
        //選択された日付をフォーマットに合わせる
        val date = setLocalDate.format(format)
        //editTextに表示させる
        editText.setText(date)
    }
}
```

monthに対して1足しているのは0から開始されるので、
1足さないと0月始まりで毎月-1になってしまうから

これでFragmentの方のエラーも無くなったはず！！
実行すると完成図のように動く。
動かないよって場合は、
MainActivityから最初のフラグメントへの遷移の処理はこの記事に書いてないので
それ忘れているか、先に全部コピペしてなにかimport出来てないとかかな？:disappointed:


#### DateTimeFormatterでゼロ埋め
上記の実装内容では日付を
2023年01月01日(日)というように、一桁の月と日には0を足してる。

```Kotlin
 DateTimeFormatter.ofPattern("yyyy年MM月dd日(E)")
```

以下のように変更すると、2023年1月1日(日)になるのでゼロ足さない時はこっち。
```Kotlin
 DateTimeFormatter.ofPattern("yyyy年M月d日(E)")
```

## まとめ

日付系ってなんだか頭こんがらがるのわたしだけ？:frowning2:
でもとりあえずOKということで！！！


参考記事：

https://developer.android.com/reference/android/app/DatePickerDialog

https://java-reference.com/java_date_format.html