若手エンジニアの趣味ブログ

Flutterでのタイムゾーンの取り扱い – timezoneパッケージの活用

はじめに

タイムゾーンはモバイルアプリケーションの品質とユーザー体験に大きな影響を与えます。ユーザーのローカルタイムゾーンを認識することで、アプリはユーザーが必要とする時間に正確な情報を提供することができます。

また、グローバルな視野を持つアプリにとって、各地域のタイムゾーンを理解することはサービスの品質を保つために不可欠です。このように、タイムゾーンはアプリ開発者がユーザー体験を最適化し、サービスを向上させる上で必要な要素なのです。

Flutterではこのタイムゾーンを簡単に扱うためにtimezoneパッケージが提供されています。

timezoneパッケージの利点

timezoneパッケージを使うと、世界中のさまざまなタイムゾーンを簡単に扱うことができます。タイムゾーン間で時間を変換したり、特定のタイムゾーンの現在の時間を取得したりすることが可能になります。手作業でこれらを行うのは複雑でエラーが発生しやすいため、このパッケージを積極的に使っていくと良いですね。

使い方

今回は、グローバルなメンバーが在籍するアプリ開発チームを対象としたタスク管理アプリを作ってみました。このアプリでは、特定の管理者がタスクを追加し、それを他のメンバーが確認できます。

しかし、チームメンバーが世界中に散らばっているため、各タスクの期限をどのように表示するかが問題になります。それぞれのメンバーが自分のタイムゾーンで期限を確認できるようにするために、timezoneパッケージを活用します。

サンプルコード

まず、timezoneパッケージをプロジェクトに追加します:

dependencies: 
  flutter: 
    sdk: 
  flutter timezone: ^0.8.0

アプリケーションの起動時にタイムゾーンデータベースを初期化します:

import 'package:timezone/timezone.dart' as tz;

void main() {
  tz.initializeTimeZones();
  runApp(MyApp());
}

timezoneパッケージの関数名とアプリの関数名が衝突しないようtzというプレフィックスをつけて

次に、タスクの詳細を表示するウィジェットを作成します。このウィジェットは、ユーザ名、タスク名、タスクの期限、ユーザのロケーションの表示と受け取った期限をユーザのタイムゾーンの期限に変換する役割を果たします。

class TaskItem extends StatelessWidget {
  const TaskItem({
    super.key,
    required this.userName,
    required this.taskName,
    required this.taskDeadline,
    required this.location,
  });

  final String userName;
  final String taskName;
  final TZDateTime taskDeadline;
  final String location;

  @override
  Widget build(BuildContext context) {
    final userTimeZone = tz.getLocation(location);

// タスクの期限をユーザーのタイムゾーンに変換。
    final localDeadline = tz.TZDateTime.from(taskDeadline, userTimeZone);

    return Card(
      child: ListTile(
        title: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('担当者:$userName'),
            Text('タスク名:$taskName'),
          ],
        ),
        subtitle: DefaultTextStyle.merge(
          style: const TextStyle(
            fontSize: 13,
            fontWeight: FontWeight.w600,
          ),
          child: Row(
            children: [
              Text('期限: ${localDeadline.toFormattedString()}'),
              const SizedBox(width: 16),
              Text('場所:$location'),
            ],
          ),
        ),
      ),
    );
  }
}
final localDeadline = tz.TZDateTime.from(taskDeadline, userTimeZone);
最後にタスク一覧を表示するウィジットを作成します。このウィジットでは、ロケーション、タスク期限、ユーザ名、ユーザのロケーションをタスク詳細ウィジットの引数に渡し、ListViewウィジットを使ってリスト形式でタスクを表示しています。


class TimeZoneSample extends StatelessWidget {
  TimeZoneSample({super.key});

// タスク作成場所で設定した期限
  final taskCreationLocationDeadLine = DateTime(2023, 5, 16, 20, 30);

// タスクを作成した場所
  static const taskCreationLocation = 'America/Los_Angeles';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('今日のタスク'),
      ),
      body: Center(
        child: Column(
          children: [
            const Text('タスク作成場所:$taskCreationLocation'),
            Text('期限:${taskCreationLocationDeadLine.toFormattedString()}'),
            Expanded(
              child: ListView(
                children: [
                  TaskItem(
                    userName: '山田太郎',
                    taskName: 'アプリアイコンの設定',
                    taskDeadline: taskCreationLocationDeadLine
                        .toTZDateTime(taskCreationLocation),
// ユーザーのタイムゾーンを'Asia/Tokyo'とします。
                    location: 'Asia/Tokyo',
                  ),
                  TaskItem(
                    userName: 'アレクサンドル',
                    taskName: 'スプラッシュアイコンの設定',
                    taskDeadline: taskCreationLocationDeadLine
                        .toTZDateTime(taskCreationLocation),
// ユーザーのタイムゾーンを'Asia/Vladivostok'とします。
                    location: 'Asia/Vladivostok',
                  ),
                  TaskItem(
                    userName: 'マキシム',
                    taskName: 'チュートリアル画面の作成',
                    taskDeadline: taskCreationLocationDeadLine
                        .toTZDateTime(taskCreationLocation),
// ユーザーのタイムゾーンを'Europe/Moscow'とします。
                    location: 'Europe/Moscow',
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
完成品はこちらです。
簡単ですね!
ユーザのロケーションごとにタスク期限が変わっています。
ちなみに'America/Los_Angeles'といったタイムゾーンを自動で取得するにはflutter_native_timezoneパッケージを使うと取得できるみたいです。
final String currentTimeZone = await FlutterNativeTimezone.getLocalTimezone();

まとめ

今回はtimezoneを使って簡単なアプリケーションを作成してみました!

皆さんもぜひtimezoneパッケージを使ってみてくださいね!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

PHP Code Snippets Powered By : XYZScripts.com