🕥

Timestampを取得して日本語表示にする

2023/11/16に公開

それ本当にできるんですか?

できます!
工夫が必要みたいですけど?

正解かわからないが挑戦してみた!

Timestampを取得して、DateTimeに変換するのだが、自作したロジックを実装する必要があった!
表示されるとこんな感じ!

StreamBuilderでFirestoreからデータを取得する。

全体のコード
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_basic/firebase_options.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends ConsumerWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const TimestampExample(),
    );
  }
}

class TimestampExample extends StatefulWidget {
  const TimestampExample({super.key});

  
  State<TimestampExample> createState() => _TimestampExampleState();
}

class _TimestampExampleState extends State<TimestampExample> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Timestamp Example'),
      ),
      body: StreamBuilder<QuerySnapshot>(
        // Firestoreからデータを取得する
        stream: FirebaseFirestore.instance.collection('post').snapshots(),
        builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
          if (snapshot.hasError) {
            return Text('エラーが発生しました: ${snapshot.error}');
          }

          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Text('読み込み中...');
          }

          return ListView(
            children: snapshot.data!.docs.map((DocumentSnapshot document) {
              // 変数timestampにTimestamp型のデータを代入
              Timestamp timestamp = document['createdAt'];
              // Timestamp型のデータをDateTime型に変換
              DateTime dateTime = timestamp.toDate();
              // 日付をフォーマット
              String yearMonthDay =
                  '${dateTime.year}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.day.toString().padLeft(2, '0')}';
              // 曜日をフォーマット
              String dayOfWeek = _getDayOfWeekInJapanese(dateTime.weekday);
              // 時間をフォーマット
              String time =
                  '${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}:${dateTime.second.toString().padLeft(2, '0')}';
              // 11月16日 木 12:00:00という形式で表示
              return ListTile(
                title: Text('$yearMonthDay $dayOfWeek $time'),
              );
            }).toList(),
          );
        },
      ),
    );
  }
  // 曜日を日本語に変換するメソッド。これは自作したものです。
  String _getDayOfWeekInJapanese(int weekday) {
    switch (weekday) {
      case 1:
        return '月';
      case 2:
        return '火';
      case 3:
        return '水';
      case 4:
        return '木';
      case 5:
        return '金';
      case 6:
        return '土';
      case 7:
        return '日';
      default:
        return '';
    }
  }
}

riverpodで書いた場合
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_basic/firebase_options.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final firestoreStreamProvider = StreamProvider<QuerySnapshot>((ref) async* {
  final stream = FirebaseFirestore.instance.collection('post').snapshots();
  yield* stream;
});

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends ConsumerWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const TimestampExample(),
    );
  }
}

class TimestampExample extends ConsumerWidget {
  const TimestampExample({Key? key}) : super(key: key);

  
  Widget build(BuildContext context, WidgetRef ref) {
    final asyncData = ref.watch(firestoreStreamProvider);
    return Scaffold(
      appBar: AppBar(
        title: const Text('Timestamp Example'),
      ),
      body: asyncData.when(
        data: (snapshot) {
          return ListView(
            children: snapshot.docs.map((DocumentSnapshot document) {
              // 変数timestampにTimestamp型のデータを代入
              Timestamp timestamp = (document.data() as Map<String, dynamic>)['createdAt'];
              // Timestamp型のデータをDateTime型に変換
              DateTime dateTime = timestamp.toDate();
              // 日付をフォーマット
              String yearMonthDay =
                  '${dateTime.year}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.day.toString().padLeft(2, '0')}';
              // 曜日をフォーマット
              String dayOfWeek = _getDayOfWeekInJapanese(dateTime.weekday);
              // 時間をフォーマット
              String time =
                  '${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}:${dateTime.second.toString().padLeft(2, '0')}';
              // 11月16日 木 12:00:00という形式で表示
              return ListTile(
                title: Text('$yearMonthDay $dayOfWeek $time'),
              );
            }).toList(),
          );
        },
        loading: () => CircularProgressIndicator(),
        error: (error, stack) => Text('Error: $error'),
      ),
    );
  }
  // 曜日を日本語に変換するメソッド。これは自作したものです。
  String _getDayOfWeekInJapanese(int weekday) {
    switch (weekday) {
      case 1:
        return '月';
      case 2:
        return '火';
      case 3:
        return '水';
      case 4:
        return '木';
      case 5:
        return '金';
      case 6:
        return '土';
      case 7:
        return '日';
      default:
        return '';
    }
  }
}

riverpod generatorを使用した例

build_runnerのコマンドを打つ必要があるので、お忘れなく。

flutter pub run build_runner watch --delete-conflicting-outputs
riverpod generator
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_basic/firebase_options.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'main.g.dart';

// flutter pub run build_runner watch --delete-conflicting-outputs

Stream firestoreStream(FirestoreStreamRef ref) {
  return FirebaseFirestore.instance.collection('post').snapshots();
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends ConsumerWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const TimestampExample(),
    );
  }
}

class TimestampExample extends ConsumerWidget {
  const TimestampExample({Key? key}) : super(key: key);

  
  Widget build(BuildContext context, WidgetRef ref) {
    final asyncData = ref.watch(firestoreStreamProvider);
    return Scaffold(
      appBar: AppBar(
        title: const Text('Timestamp Generator'),
      ),
      body: asyncData.when(
        data: (snapshot) {
          return ListView(
            children: (snapshot as QuerySnapshot)
                .docs
                .map((DocumentSnapshot document) {
              // 変数timestampにTimestamp型のデータを代入
              Timestamp timestamp =
                  (document.data() as Map<String, dynamic>)['createdAt'];
              // Timestamp型のデータをDateTime型に変換
              DateTime dateTime = timestamp.toDate();
              // 日付をフォーマット
              String yearMonthDay =
                  '${dateTime.year}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.day.toString().padLeft(2, '0')}';
              // 曜日をフォーマット
              String dayOfWeek = _getDayOfWeekInJapanese(dateTime.weekday);
              // 時間をフォーマット
              String time =
                  '${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}:${dateTime.second.toString().padLeft(2, '0')}';
              // 11月16日 木 12:00:00という形式で表示
              return ListTile(
                title: Text('$yearMonthDay $dayOfWeek $time'),
              );
            }).toList(),
          );
        },
        loading: () => CircularProgressIndicator(),
        error: (error, stack) => Text('Error: $error'),
      ),
    );
  }

  // 曜日を日本語に変換するメソッド。これは自作したものです。
  String _getDayOfWeekInJapanese(int weekday) {
    switch (weekday) {
      case 1:
        return '月';
      case 2:
        return '火';
      case 3:
        return '水';
      case 4:
        return '木';
      case 5:
        return '金';
      case 6:
        return '土';
      case 7:
        return '日';
      default:
        return '';
    }
  }
}

最後に

Timestampのデータを取得して、日本語に変換する処理は他にもありそうですが、この方法しか今の所うまくいってないので、技術記事にしました。
他に日本語の日付に変換する方法があれば試してみたいところです。

Jboy王国メディア

Discussion