【Flutter】DateTimeを「何日前」「何分前」など現在時刻との差分で表示させる方法

今回は、flutterで、「何日前」、「何分前」など現在時刻からの差分で表示していきます。


# 現在時刻より「〜日前」「〜分前」の時間をとって来きて画面に表示する

ソースコード

```dart:main.dart

// 現在の時刻
final DateTime now = DateTime.now();

class Date extends StatelessWidget {
  // 30秒前の時刻
  final DateTime thirtySecondsAgo = now.add(Duration(seconds: 30) * -1);
  // 30分前の時刻
  final DateTime thirtyMinutesAgo = now.add(Duration(minutes: 30) * -1);
  // 5時間前の時刻
  final DateTime fiveHoursAgo = now.add(Duration(hours: 30) * -1);
  // 30日前の時刻
  final DateTime thirtyDaysAgo = now.add(Duration(days: 30) * -1);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(mainAxisAlignment: MainAxisAlignment.center, children: <
            Widget[
          // ⓵
          Text(DateFormat('yyyy/MM/dd(E) HH:mm:ss').format(now)),
          // ②
          Text(DateFormat('yyyy/MM/dd(E) HH:mm:ss').format(thirtySecondsAgo)),
          // ③
          Text(DateFormat('yyyy/MM/dd(E) HH:mm:ss').format(thirtyMinutesAgo)),
          // ④
          Text(DateFormat('yyyy/MM/dd(E) HH:mm:ss').format(fiveHoursAgo)),
          // ⑤
          Text(DateFormat('yyyy/MM/dd(E) HH:mm:ss').format(thirtyDaysAgo)),
        ]),
      ),
    );
  }
}
```
実際の画面がこちら
![スクリーンショット 2020-08-04 0.23.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408813/c721c5c0-601a-cc1f-33fd-2f2c993229c7.png)

ひとまず、ここまでで使った技術を紹介

### DateTime.add()
[FlutterのDateTimeクラス](https://api.flutter.dev/flutter/dart-core/DateTime-class.html)には、addというメソッドが用意せれていてこれを用いて指定した期間、前か後の時刻（DateTime)をとってこれる。

例えば、30秒後なら以下のようにすればとって来れます。

` final thirtySecondsAfter = DateTime.add(Duration(seconds: 30)) `

addの引数に[Duration](https://api.flutter.dev/flutter/dart-core/Duration-class.html)を渡してあげれば簡単にとってこれます。

Flutter の公式ドキュメント 「DateTime class」
https://api.flutter.dev/flutter/dart-core/DateTime-class.html

### DateTimeをフォーマットを指定してStringに変換

まずは、[pub.dev](https://pub.dev/)から[intl](https://pub.dev/packages/intl)というライブラリを使えるようにします。

```dart:pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  intl: ^0.16.1
```
```dart:main.dart
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
```
これでintlが使えるようになりました

次に、フォーマットを指定してStringに変換していきます。

例：`DateFormat('yyyy/MM/dd(E)').format(DateTime date)`

・このようにDataFormatの引数に指定するFormatを渡す。
　　　　　　　　⬇️
・formatの引数にStringに変換したい時刻（DateTime)を渡してあげる
　　　　　　　　⬇️
・これをTextの引数に渡すと表示できる

参考にした記事
・pub.devのintlパッケージ
https://pub.dev/packages/intl
・flutterでDateTimeとStringの変換方法とTimeZoneとLocale
https://qiita.com/ko2ic/items/bd0d20d72c66e8231c5c

# 現在時刻との差分を表示する

ソースコード

```dart:main.dart
final DateTime now = DateTime.now();

class Date extends StatelessWidget {
  final List<DateTime> dates = [
    // 30秒前の時刻
    now.add(Duration(seconds: 30) * -1),
    // 30分前の時刻
    now.add(Duration(minutes: 30) * -1),
    // 5時間前
    now.add(Duration(hours: 30) * -1),
    // 30日前
    now.add(Duration(days: 30) * -1)
  ];

  @override
  Widget build(BuildContext context) {
    final difference = dates.map((date) => Text(fromAtNow(date))).toList();
    return Scaffold(
      body: Center(
        child: Column(
            mainAxisAlignment: MainAxisAlignment.center, children: difference),
      ),
    );
  }
}

String fromAtNow(DateTime date) {
  final Duration difference = DateTime.now().difference(date);
  final int sec = difference.inSeconds;

  if (sec >= 60 * 60 * 24) {
    return '${difference.inDays.toString()}日前';
  } else if (sec >= 60 * 60) {
    return '${difference.inHours.toString()}時間前';
  } else if (sec >= 60) {
    return '${difference.inMinutes.toString()}分前';
  } else {
    return '$sec秒前';
  }
}
```

実際の画面
<img width="390" alt="スクリーンショット 2020-08-04 1.32.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408813/303440a1-6fdf-4264-b579-65fc1cf8239b.png">

###この方法を解説
実際にはここの部分で、現在時刻との差分をStringに変換しています。

```
String fromAtNow(DateTime date) {
  final Duration difference = DateTime.now().difference(date);
  final int sec = difference.inSeconds;

  if (sec >= 60 * 60 * 24) {
    return '${difference.inDays.toString()}日前';
  } else if (sec >= 60 * 60) {
    return '${difference.inHours.toString()}時間前';
  } else if (sec >= 60) {
    return '${difference.inMinutes.toString()}分前';
  } else {
    return '$sec秒前';
  }
}
```

### 手順
**1. まずは、DateTimeクラスの[difference](https://api.flutter.dev/flutter/dart-core/DateTime/difference.html)メソッドを使って差分をDurationで返します。
例では、DataTime.nowとdateの差分を取ってきました。**

例：　`final Duration difference = DateTime.now().difference(date);`

**２. DurationのinSecondsメソッドで差分（Duration)を秒数(int)に変換してあげる**

例：　`final int sec = difference.inSeconds;`

**3. 60秒以下の場合は、〜秒前のように場合分けする**

例：　`if(sec < 60) {return '$sec秒前';}`

以上！！

###参考になる記事

Flutter の公式ドキュメント 「DateTime class」
https://api.flutter.dev/flutter/dart-core/DateTime-class.html
・pub.devのintlパッケージ
https://pub.dev/packages/intl
・flutterでDateTimeとStringの変換方法とTimeZoneとLocale
https://qiita.com/ko2ic/items/bd0d20d72c66e8231c5c
・一週間前、または、現在の日時からn日後、n日前の日付を取得する - C#プログラミング
https://www.ipentec.com/document/csharp-get-a-week-ago-datetime