Flutter Custom DateTime Serialization with JsonConverter

Hi,

When I working on my last project, I taken an error about parsing datetime. Dart support RFC3339 but, there is a problem. The problem is Dart supports second fraction only 6 digits. But datatime that came from api is 7 digits.

Like that;

“2019–01–16T16:56:34.6213896

We must convert to;

“2019–01–16T16:56:34.621389

I found elegant solution for this problem. We can use custom json converter. This is simple but very affective solution. With this solution we can convert any data type and our custom types.

I serialize json with “json_serializable”. I like this way. Because I think that is very simple way. You can found more info about json_serializable from this page.

We are create our model class.

import 'package:json_annotation/json_annotation.dart';

part 'publication_document.g.dart';

@JsonSerializable()
class PublicationDocument {
  final int id;
  final int publicationId;

  final DateTime publicationDate;
  final DateTime createTime;
  final DateTime updateTime;
  final bool isFree;

  PublicationDocument({
    this.id,
    this.publicationId,
    this.publicationDate,
    this.createTime,
    this.updateTime,
    this.isFree,
  });

  factory PublicationDocument.fromJson(Map<String, dynamic> json) =>
      _$PublicationDocumentFromJson(json);
  Map<String, dynamic> toJson() => _$PublicationDocumentToJson(this);
}

When we are use standart model, we will take an error like that;

FormatException (FormatException: Invalid date format 2019–01–16T16:56:34.6213896)

We can solve this problem very simple. But how?

First we must use custom json converter for DateTime. For achive this, we are creating our converter.

import 'package:json_annotation/json_annotation.dart';

class CustomDateTimeConverter implements JsonConverter<DateTime, String> {
  const CustomDateTimeConverter();

  @override
  DateTime fromJson(String json) {
    if (json.contains(".")) {
      json = json.substring(0, json.length - 1);
    }

    return DateTime.parse(json);
  }

  @override
  String toJson(DateTime json) => json.toIso8601String();
}

We must import “json_annotation” and than implement JsonConverter with override “fromJson” and “toJson” functions.

In my senario, Line 3, I say this converter return DateTime in “fromJson” Line 8, I check for contains “.” Line 9, I remove last digit Line 12, I convert string to DateTime

You can write your implementation.

After that we are updating our model class;

import 'package:json_annotation/json_annotation.dart';
import 'package:my_app/shared/helpers/custom_datetime.dart';

part 'publication_document.g.dart';

@JsonSerializable()
@CustomDateTimeConverter()
class PublicationDocument {
  final int id;
  final int publicationId;

  final DateTime publicationDate;
  final DateTime createTime;
  final DateTime updateTime;
  final bool isFree;

  PublicationDocument({
    this.id,
    this.publicationId,
    this.publicationDate,
    this.createTime,
    this.updateTime,
    this.isFree,
  });

  factory PublicationDocument.fromJson(Map<String, dynamic> json) =>
      _$PublicationDocumentFromJson(json);
  Map<String, dynamic> toJson() => _$PublicationDocumentToJson(this);
}

We are add only 2 line,

Line 2, this is for using our custom converter Line 7, with this line build_runner know we are convert DateTime with our converter.

After that we are run “ flutter packages pub run build_runner build”

Now our parsing class will updated with our converter;

You are see our converter in Line 15, 19, 23.

Thats all.

Have nice day..

Apr 29, 2019

© 2024

Email LinkedIn Medium