毎度おなじみのタイムゾーンの罠にハマったので記録しておきます。
今回サーバーから返却される値は下記の二種類ありました。
2024-11-14T00:00:00.000+09:00
のような ISO 8601 形式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メソッドの方法であれば)時間情報を削除する
が味噌になります。