Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Datetime timezone deserialization

I've developed a Rest API for my app. It sends to the app dates in the following format 2018-09-07T17:29:12+02:00, where I guess +2:00 represents my timezone as part of one object.

In my Flutter app, once I deserialize the received object, it substracts two hours to the actual received DateTime object.

The class I'm trying to deserialize is defined as follows:

import 'package:json_annotation/json_annotation.dart';

part 'evento.g.dart';

@JsonSerializable(nullable: false)
class Evento {
  final int id;
    final String nombre;
    final String discoteca;
    final int precio_desde;
    final int edad_minima;
    final DateTime fecha_inicio;
    final DateTime fecha_fin;
    final DateTime fecha_fin_acceso;
    final String cartel;
  final bool incluyeCopa;
    Evento(this.id, this.nombre, this.discoteca, this.precio_desde, this.edad_minima, this.fecha_inicio, this.fecha_fin, this.fecha_fin_acceso, this.cartel, this.incluyeCopa, this.num_tipos);
  factory Evento.fromJson(Map<String, dynamic> json) => _$EventoFromJson(json);
  Map<String, dynamic> toJson() => _$EventoToJson(this);
} 
like image 447
pitazzo Avatar asked Sep 13 '18 17:09

pitazzo


3 Answers

DateTime can only represent local time and UTC time.

It supports timezone offset for parsing, but normalizes it to UTC

print(DateTime.parse('2018-09-07T17:29:12+02:00').isUtc);

prints true.

You can then only convert between local and UTC time using toLocal() or toUtc()

like image 64
Günter Zöchbauer Avatar answered Nov 08 '22 05:11

Günter Zöchbauer


Try calling the .toLocal() method on the date when you deserialize it.

This is what the docs say

Use the methods toLocal and toUtc to get the equivalent date/time value specified in the other time zone.

like image 42
Sebastian Avatar answered Nov 08 '22 04:11

Sebastian


One more way with json_serializable and freezed.

Create a class for converting DateTime.

import 'package:freezed_annotation/freezed_annotation.dart';

class DatetimeJsonConverter extends JsonConverter<DateTime, String> {
  const DatetimeJsonConverter();

  @override
  DateTime fromJson(String json) => DateTime.parse(json).toLocal();

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

After that just add it to every DateTime property in your classes.

@DatetimeJsonConverter() @JsonKey(name: 'created_at') required DateTime createdAt,

And it will be converted to Local\UTC time accordingly.

like image 2
awaik Avatar answered Nov 08 '22 04:11

awaik