google / json_serializable.dart

Generates utilities to aid in serializing to/from JSON.
https://pub.dev/packages/json_serializable
BSD 3-Clause "New" or "Revised" License
1.54k stars 392 forks source link

Feature request: FromJson format to local time #1420

Open trtiger4520 opened 2 months ago

trtiger4520 commented 2 months ago

Due to the need to display local time in the application

Want to add an option in the configuration file to allow users to choose whether to use local time

Achievable:

Thanks


config:

targets:
  $default:
    builders:
      json_serializable:
        options:
          parse_local_time: true // default: false

from:

part of 'example.dart';

Person _$PersonFromJson(Map<String, dynamic> json) => Person(
      firstName: json['firstName'] as String,
      lastName: json['lastName'] as String,
      dateOfBirth: json['dateOfBirth'] == null
          ? null
          : DateTime.parse(json['dateOfBirth'] as String),
    );

to:

part of 'example.dart';

Person _$PersonFromJson(Map<String, dynamic> json) => Person(
      firstName: json['firstName'] as String,
      lastName: json['lastName'] as String,
      dateOfBirth: json['dateOfBirth'] == null
          ? null
          : DateTime.parse(json['dateOfBirth'] as String).toLocal(),
    );
pattobrien commented 2 months ago

Avoid manually changing to local time every time you use it Avoid modifying automatically generated files

This is easily solvable by creating your own JsonConverter as shown:

import 'package:json_annotation/json_annotation.dart';

part 'date_converter.g.dart';

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

  @override
  DateTime fromJson(String value) {
    return DateTime.parse(value).toLocal(); // implement your custom `fromJson` logic here
  }

  @override
  String toJson(DateTime value) {
    return value.toUtc().toIso8601String();  // implement your custom `toJson` logic here
  }
}

@JsonSerializable()
class Person {
  final String firstName;
  final String lastName;
  @LocalDateConverter() // annotate the field requiring custom serialization logic
  final DateTime dateOfBirth;

  const Person({
    required this.firstName,
    required this.lastName,
    required this.dateOfBirth,
  });

  factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);

  Map<String, dynamic> toJson() => _$PersonToJson(this);
}

Does that solve your problem?

trtiger4520 commented 2 months ago

@pattobrien Thanks Reply

I understand that using JsonConverter can solve the conversion problem

However, my situation here is: the current project uses swagger_dart_code_generator, which is also part of the automatic generation. At that time, I looked at the contents of the files on both sides and found no better solution, so I came up with this idea.

I'll look for other solutions


in addition I forked this repository and tried to adjust it, but found that ToFromStringHelper is placed in the final variable of the file. It seems that bringing config into the affected content will require adjusting a lot of structural issues.