はじめに
時刻を選択できる TimePicker は、使用するデバイスの時刻の表示形式によってUIが変わります。
- 12時間形式: AM/PMセレクターあり。
- 24時間形式: AM/PMセレクターなし。奇数時刻(1時, 23時等)を選択する場合は表示されている時刻の間をタップする。
12時間形式 | 24時間形式 |
---|---|
![]() |
![]() |
デバイスの時刻の表示形式によらず、UIを固定したいことがあり調査したのでそれについて記載します。
実装
デバイスの時刻の表示形式によらずUIを固定したい場合は、alwaysUse24HourFormat
を指定すれば可能です。
alwaysUse24HourFormatが
- true -> 24時間形式のUI
- false -> 12時間形式のUI
例: 12時間形式のUIで固定したい場合
void _selectTime() async {
final TimeOfDay? newTime = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
builder: (context, child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: false),
child: child!,
);
},
);
}
おまけ: TimeOfDayのフォーマットについて
TimeOfDay
は format()
メソッドを持っており、hh:mm
の形式で出力してくれます。しかし、これもデバイスの時計の設定が12時間形式か24時間形式かで変わってきます。
例えば以下のような感じで出力した場合。
Text(
'Selected time: ${_time.format(context)}',
),
下図のように、デバイスの時計の設定が12時間形式の場合は、hh:mm AM/PM
の形式で出力されます。
12時間形式 | 24時間形式 |
---|---|
![]() |
![]() |
これをデバイスの設定によらず固定にしたい場合は、以下のような拡張関数を作るとよさそう。
TimeOfDayのフィールドを用いて整形する拡張関数 (24時間形式で固定)
Flutter Convert TimeOfDay to 24 hours format - technicalfeeder.com で紹介されていた方法です。
TimeOfDay
のhour
とminute
を用いて整形します。1時2分の場合、1:2
のようにならないように padLeft(2, "0")
で調整します。
extension TimeOfDayConverter on TimeOfDay {
String to24hours() {
final hour = this.hour.toString().padLeft(2, "0");
final min = this.minute.toString().padLeft(2, "0");
return "$hour:$min";
}
}
MaterialLocalizationsを使った拡張関数 (24時間/12時間形式どちらの固定も可)
TimeOfDay#format()
の実装は以下のようになっていました。
String format(BuildContext context) {
assert(debugCheckHasMediaQuery(context));
assert(debugCheckHasMaterialLocalizations(context));
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
return localizations.formatTimeOfDay(
this,
alwaysUse24HourFormat: MediaQuery.of(context).alwaysUse24HourFormat,
);
}
なので、MaterialLocalizations#formatTimeOfDay()
を呼び、引数の alwaysUse24HourFormat
に特定のboolを渡してやる拡張関数を作るという方法もあります。
24時間形式で固定したい場合は true
を渡して以下のような感じ。
extension TimeOfDayFormatter on TimeOfDay {
String to24hours(BuildContext context) {
final MaterialLocalizations localizations =
MaterialLocalizations.of(context);
return localizations.formatTimeOfDay(
this,
alwaysUse24HourFormat: true,
);
}
}
逆に alwaysUse24HourFormat: false
とすれば常に hh:mm AM/PM
の形式で出力ができます。
以上です。
参考
showTimePicker - api.flutter.dev
How to use 24 hour clock when invoking showTimePicker() in Flutter? - stackoverflow.com
Flutter Convert TimeOfDay to 24 hours format - technicalfeeder.com