kokh log

yumikokhの開発日記

Dart: DateTimeで日付単位の比較

毎度おなじみのタイムゾーンの罠にハマったので記録しておきます。

今回サーバーから返却される値は下記の二種類ありました。

  1. 2024-11-14T00:00:00.000+09:00 のような ISO 8601 形式
  2. 2024-11-14 のような日付のみの情報

これをそのまま DateTime.parse で処理すると下記のような結果が返ってきます。

DateTime.parse('2024-11-14T00:00:00.000+09:00'); // 2024-11-13 15:00:00.000Z
DartTime.parse('2024-11-14'); // 2024-11-14 00:00:00.000

日付が変わった!!
これはなぜかというと、1はISO 8601形式なのでUTC協定世界時)で処理されます(UTCは末尾にZがついてます) が、2はシステム環境のローカル時間で処理されるためです。

例えば、「受け取った日付が昨日かどうか」を判定する実装は下記のようになります。

final a = DateTime.parse('2024-11-14T23:15:00.000+09:00').toLocal(); // ローカルに変換する
final fromA = DateTime(a.year, a.month, a.day); // 日付単位で比較したいため、時間情報無しで初期化
final now = DateTime.now(); // ローカルで今の時間
final yesterday = DateTime(now.year, now.month, now.day - 1);

print(a.year == yesterday.year && a.month == yesterday.month  && a.day == yesterday.day); // 愚直な方法
print(a == yesterday); // コンストラクタの比較
print(a.difference(now).inDays); // differenceメソッドを使う

どの方法でもOKです。

  • DateTimeをローカルに統一する
  • (コンストラクタかdirrerenceメソッドの方法であれば)時間情報を削除する

が味噌になります。

stackoverflow.com