Flutter DateTime.toIso8601StringにTimeZoneオフセットを追加

2022/08/26に公開

はじめに

Flutterで外部API向けに日時を渡そうとDateTime.toIso8601Stringを使用してみましたが、TimeZoneのオフセットがなく日時のズレが発生してしまいました。
そこでTimeZoneオフセットを追加する方法を記載します。

DateTime.toIso8601String

TimeZoneが設定されているDateTimeの場合、toIso8601StringではTimeZoneオフセットがない状態です。
UTCに変換した後のtoIso8601Stringでは、UTCを表すZが出力されるため、日時のズレをなくすだけなら、それだけでも問題ないかもしれません。

void main() {
  final now = DateTime.now();
  print(now.timeZoneName);
  print(now.toIso8601String());
  print(now.toUtc().toIso8601String());
}
日本標準時
2022-08-26T07:23:11.919
2022-08-25T22:23:11.919Z

TimeZoneオフセットを含むメソッドを追加

UTCに変換すれば問題なさそうですが、変換し忘れよる不具合も発生しそうです。
そこで、TimeZoneオフセットを含むメソッドtoIso8601StringWithTimeZoneOffsetStringをDateTimeに追加してみました。

extension DateTimeStringExtension on DateTime {
  String timeZoneOffsetString() {
    final offset = timeZoneOffset;
    // ignore: prefer_interpolation_to_compose_strings
    return (offset.isNegative ? '-' : '+') +
        offset.inHours.abs().toString().padLeft(2, '0') +
        ':' +
        (offset.inMinutes - offset.inHours * 60).toString().padLeft(2, '0');
  }

  String toIso8601StringWithTimeZoneOffsetString() {
    if (isUtc) {
      return toIso8601String();
    }

    return '${toIso8601String()}${timeZoneOffsetString()}';
  }
}

void main() {
  final now = DateTime.now();
  print(now.timeZoneName);
  print(now.toIso8601StringWithTimeZoneOffsetString());
  print(now.toUtc().toIso8601StringWithTimeZoneOffsetString());
}
日本標準時
2022-08-26T07:32:14.979+09:00
2022-08-25T22:32:14.979Z

まとめ

TimeZoneオフセットを含む日時を出力することができました。
TimeZoneオフセットを含む日時を外部APIなど渡したい場合には、上記のようなメソッドをDateTimeに追加し、それを使用してみてはいかがでしょうか。

参考

https://github.com/dart-lang/sdk/issues/43391

Discussion