[チュートリアル5]世界各国の時間を表示するアプリを作る[compose multiplatform]

# はじめに
[公式ドキュメント](https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-multiplatform-new-project.html)の和訳と要約＋αです。
前回は[これ](https://qiita.com/shunk0616/items/627a172416530ccade70)です。

# ページの基本要素を作る
*composeApp/src/commonMain/kotlin*のApp.ktを開いてください。

現在のコードを消して以下のコードを挿入してください。

```
@Composable
fun App() {
    MaterialTheme {
        var timeAtLocation by remember { mutableStateOf("No location selected") }
        Column {
            Text(timeAtLocation)
            Button(onClick = {
                timeAtLocation = "13:30"
            }) {
                Text("Show Time At Location")
            }
        }
    }
}
```

それに伴い以下のimportを挿入してください。

```
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
```
### 簡単な解説

このレイアウトは、2つのコンポーザブルを含むカラム（列）です。最初のコンポーザブルはテキストで、2つ目はボタンです。

2つのコンポーザブルはtimeAtLocationプロパティを共有して持っています。
テキストコンポーザブルはこの状態のオブザーバー（監視者）なので、timeAtLocationプロパティの中身をリアルタイムで表示しています。
ボタンコンポーザブルはonClickハンドラーを使って、クリックされたらtimeAtLocationの中身に"13:30"を入れています。


# ユーザーの入力を受け付けるようにする
ここでの目標は、ユーザーが都市名を入力すると、その場所の時刻が表示されるようにすることです。

そのためにユーザーが入力できるフォームをTextFiledコンポーザブルで実装します。

App.ktを以下の内容に書き換えてください。
```
@Composable
fun App() {
    MaterialTheme {
        var location by remember { mutableStateOf("Europe/Paris") }
        var timeAtLocation by remember { mutableStateOf("No location selected") }

        Column {
            Text(timeAtLocation)
            TextField(value = location, onValueChange = {
                location = it
            })
            Button(onClick = {
                timeAtLocation = "Time at $location is 13:30"
            }) {
                Text("Show Time At Location")
            }
        }
    }
}
```
importにはこれを追加してください。
```
import androidx.compose.material.TextField
```

### 簡単なコード解説
TextFieldとlocationプロパティを追加しました。
TextFieldは文字の入力フォームで、onValueChangeイベントハンドラーによって、文字が入力されるとその文字をlocationに代入します。
そのlocationをtimeAtLocationで使って、Textの中とかで使っています。

# 時間を計算する
ユーザーの入力を使って、表示する時間を計算します。そのためにcurrentTimeAt()というファンクションを作りましょう

## currentTimeAt()
App.ktに戻って、以下のコードを追加します。
ファイルの一番下で大丈夫です。
```
fun currentTimeAt(location: String): String? {
    fun LocalTime.formatted() = "$hour:$minute:$second"

    return try {
        val time = Clock.System.now()
        val zone = TimeZone.of(location)
        val localTime = time.toLocalDateTime(zone).time
        "The time in $location is ${localTime.formatted()}"
    } catch (ex: IllegalTimeZoneException) {
        null
    }
}
```

それに伴って、以下のimport分も追加しましょう。

```
import kotlinx.datetime.Clock
import kotlinx.datetime.IllegalTimeZoneException
import kotlinx.datetime.LocalTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
```

# currentAtTime()を使ってみる
App()コンポーザブルの中で先ほど作ったcurrentTimeAt()を使うように修正しましょう。

App.ktの29行目あたりに、
> timeAtLocation = "Time at $location is 13:30"
こういう記述があると思います。
これを以下のように修正してください。

> timeAtLocation = currentTimeAt(location) ?: "Invalid Location"

これによって、元々は固定で13:30を表示していたところに、currentTimeAtファンクションにlocationの値を渡した時の返り値を表示するようになります。

元々のチュートリアルはもうちょっとあるんですが、ちょっと長いのでここまで！

# 次
残りは[次の記事](https://qiita.com/shunk0616/items/43fdb94556d0236375d0)でやります！