亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Flutter 使用來自 Golang RFC3339 的 DateTime 解析 json:

Flutter 使用來自 Golang RFC3339 的 DateTime 解析 json:

Go
縹緲止盈 2023-04-24 15:57:26
當嘗試讀取在 Dart / Flutter 中使用 golangs json 包生成的 json 文件時,我注意到解析日期會產生錯誤:FormatException: Invalid date format一個示例是在 Go 服務器上生成的以下 json:{    ...    "dateCreated": "2018-09-29T19:51:57.4139787-07:00",    ...}我正在使用代碼生成方法進行 json(反)序列化,以避免編寫所有樣板代碼。json_serializable 包是可用于此目的的標準包。所以我的代碼如下所示:@JsonSerializable()class MyObj {  DateTime dateCreated;  MyObj( this.dateCreated);  factory MyObj.fromJson(Map<String, dynamic> json) => _$MyObjFromJson(json);    Map<String, dynamic> toJson() => _$MyObjToJson(this); }
查看完整描述

2 回答

?
米脂

TA貢獻1836條經驗 獲得超3個贊

因為文檔沒有充分涵蓋這一點,所以我花了一天時間研究顫動源和不同事物的反復試驗來解決它。所以不妨分享一下。


Golang 默認情況下在序列化為 Json 時在 RFC3339 中編碼 time.Time(如在給定的示例中)。Flutter 明確支持 RFC3339,為什么它不起作用?答案是秒小數部分的支持方式略有不同。雖然 Golang 產生 7 位數字的精度,但 Dart 最多只支持 6 位數字并且不會優雅地處理違規情況。因此,如果將示例更正為只有 6 位精度,它將在 Dart 中解析得很好:


{

    ...

    "dateCreated": "2018-09-29T19:51:57.413978-07:00",

    ...

}

為了以通用的方式解決這個問題,您有兩個選擇:1. 從字符串中截斷額外的精度,或者 2. 實現您自己的解析。假設我們擴展DateTime類并創建您自己的CustomDateTime. 新類重寫了parse方法,在將其交給父類的解析方法之前刪除 6 位數字后的所有多余部分。


現在我們可以在我們的 Dart 類中使用了CustomDateTime。例如:


@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軟件包現在為我們提供了一個簡單的解決方案 - The 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); 

}

這滿足了代碼生成器和 Voila!我們可以讀取帶有來自 golang time.Time 的 RFC3339 時間戳的 json。


查看完整回答
反對 回復 2023-04-24
?
泛舟湖上清波郎朗

TA貢獻1818條經驗 獲得超3個贊

我有同樣的問題。我找到了一個非常簡單的解決方案。我們可以使用帶有 JsonConverter 的自定義轉換器。


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();

}

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);

}


查看完整回答
反對 回復 2023-04-24
  • 2 回答
  • 0 關注
  • 297 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號