【问题标题】:.NET Core - converting date of read JSON file.NET Core - 读取 JSON 文件的转换日期
【发布时间】:2018-09-10 12:53:17
【问题描述】:

有什么方法可以转换从 JSON 文件中读取的日期?我的文件中的示例记录是:

{
    "UserID": 73274,
    "Created": "17-03-2018 06:35",
    "Office": "Washington"
},

我正在做的是导入 JSON 文件并将其内容保存到数据库。问题是,当日期为DD-MM-YYYY hh:ss 格式时,它根本不起作用。但是当日期是YYYY-MM-DDThh:mm:ss 格式时,一切都很好。如何在读取此文件后将日期解析为另一种格式并对已解析日期的文件执行以下操作?

我负责此操作的部分控制器是:

if (file.ContentType == "application/json")
{
    try
    {
        using (var reader = new StreamReader(file.OpenReadStream()))
        {
            content = reader.ReadToEnd();
        }
     }
     catch
     {
         return BadRequest(Messages.fileNotChosen);
     }
     try
     {
         userObjects = JsonConvert.DeserializeObject<List<UserImportModel>>(content);
     }
     catch
     {
         return BadRequest();
     }
 }

当日期格式为 YYYY-MM-DDThh:mm:ss 时,正确计算 userObjects 并且控制器移动到我执行添加到数据库的部分。当日期格式为DD-MM-YYYY hh:ss时,userObjects = 0,控制器移动到catch,然后返回BadRequest()。

编辑:UserImportModel 类的代码:

public class UserImportModel
{

    public string UserID { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
    public DateTime Created { get; set; }

    public string Office { get; set; }

}

【问题讨论】:

  • this question 的可能重复项
  • 如果格式是固定的,这里有一个 Json.Net 的解决方案:stackoverflow.com/questions/21256132/… 但是如果你有多种日期格式,那么你可能需要手动反序列化字符串。
  • 恕我直言XY Problem。您应该始终将您的日期作为 ISO 日期传递并返回,因为您不一定知道用户的全球化设置。 UI(WPF、WinForms、HTML/JavaScript、Angular 等)应该占用 ISO 时间(它包含时区信息等)并以用户语言格式和时区显示

标签: c# asp.net json date asp.net-core


【解决方案1】:

如果你需要反序列化不同格式的日期,你必须创建一个自定义的JsonConverter

public class MultiFormatDateTimeConverter : JsonConverter
{
    private List<string> formats;

    public MultiFormatDateTimeConverter(List<string> formats)
    {
       this.formats = formats;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DateTime);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        string dateString = (string)reader.Value;

        foreach (string format in formats)
        {
            if (DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date))
            {
                return date;
            }
        }
        throw new JsonException("Unable to parse \"" + dateString + "\" as a date.");
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

使用示例:

var settings = new JsonSerializerSettings();
settings.DateParseHandling = DateParseHandling.None;
settings.Converters.Add(new MultiFormatDateTimeConverter(new List<string> { "DD-MM-YYYY hh:ss", "YYYY-MM-DDThh:mm:ss" }));

userObjects = JsonConvert.DeserializeObject<List<UserImportModel>>(content, settings);

【讨论】:

  • 您的解决方案完成了这项工作。它还允许我指定许多要转换为 ISO8601 标准的日期格式,所以我会坚持下去。非常感谢。
【解决方案2】:

JSON.Net 使用 标准 8601 来表示日期时间。完整日期时间表达式的扩展格式是:“YYYY-MM-DDTHH:MM:SS”。 JSON.Net "Deserializer" 方法 (DeserializeObject) 被重载以接受自定义格式化程序,您可以使用 de IsoDateTimeConverterDateTimeFormat 属性中指定字符串“dd”的格式

userObjects = JsonConvert.DeserializeObject<List<UserImportModel>>(content, 
                   new IsoDateTimeConverter { DateTimeFormat = "dd-MM-yyyy hh:mm:ss" });

另一种选择是在调用 DeserializeObject 方法之前使用正则表达式替换 JSON 字符串中所有格式错误的 ISO 日期

【讨论】:

  • 我尝试使用 IsoDateTimeConverter,因为我在其他线程中找到了类似的解决方案,但它对我不起作用。结果我在 DateTimeFormat 属性格式中指定了我想要的日期格式,而不是我在 JSON 文件中的格式。多可惜。如果其他一切都失败了,使用正则表达式也是一个好主意。
猜你喜欢
  • 2019-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
相关资源
最近更新 更多