Поскольку документация не покрывает это в достаточной мере, мне потребовался день, чтобы исследовать источники флаттера и проб и ошибок различных вещей, чтобы решить его.Так что может также поделиться им.
Golang по умолчанию кодирует время. Время в RFC3339 при сериализации в Json (как в данном примере).Flutter явно поддерживает RFC3339, так почему же он не работает?Ответ - небольшая разница в том, как поддерживается часть доли секунды.В то время как Golang дает точность 7 цифр, Dart поддерживает только до 6 цифр и не обрабатывает нарушения корректно.Таким образом, если пример исправлен так, чтобы иметь только 6 цифр точности, он будет очень хорошо разбираться в Dart:
{
...
"dateCreated": "2018-09-29T19:51:57.413978-07:00",
...
}
Для общего решения этой проблемы у вас есть два варианта: 1. усечь дополнительноеточность из строки, или 2. реализовать свой собственный анализ.Давайте предположим, что мы расширили класс DateTime
и создали ваш собственный CustomDateTime
.Новый класс имеет метод parse
, переопределенный для удаления всего лишнего после 6 цифр перед передачей его методу разбора родительского класса.
Теперь мы можем использовать CustomDateTime
в наших классах Dart.Например:
@JsonSerializable()
class MyObj {
CustomDateTime dateCreated;
MyObj( this.dateCreated);
factory MyObj.fromJson(Map<String, dynamic> json) => _$MyObjFromJson(json);
Map<String, dynamic> toJson() => _$MyObjToJson(this);
}
Но, конечно, теперь генерация кода не работает, и мы получаем следующую ошибку:
Error running JsonSerializableGenerator
Could not generate 'toJson' code for 'dateCreated'.
None of the provided 'TypeHelper' instances support the defined type.
К счастью, пакет json_annotation
теперь имеет простое решение для нас- JsonConverter
.Вот как это использовать в нашем примере:
Сначала определите конвертер, который объясняет генератору кода, как конвертировать наш тип CustomDateTime
:
class CustomDateTimeConverter implements JsonConverter<CustomDateTime, String> {
const CustomDateTimeConverter();
@override
CustomDateTime fromJson(String json) =>
json == null ? null : CustomDateTime.parse(json);
@override
String toJson(CustomDateTime object) => object.toIso8601String();
}
Во-вторых, мы просто аннотируем этот конвертердля каждого класса, который использует наш тип данных CustomDateTime:
@JsonSerializable()
@CustomDateTimeConverter()
class MyObj {
CustomDateTime dateCreated;
MyObj( this.dateCreated);
factory MyObj.fromJson(Map<String, dynamic> json) => _$MyObjFromJson(json);
Map<String, dynamic> toJson() => _$MyObjToJson(this);
}
Это удовлетворяет генератор кода и вуаля!Мы можем читать json с метками времени RFC3339, которые приходят из времени Голанга. Время.