我正在尝试将对象从JSON数据反序列化为C#类(我使用的是Newtonsoft Json.NET):
数据包含字符串值中的日期,如09/12/2013
,格式为dd/mm/yyyy
。
如果我致电JsonConvert.DeserializeObject<MyObject>(data);
日期加载到C#类的日期时间属性,如mm/dd/yyyy
,然后日期值是2013年9月12日(而不是2013年12月9日)。
是否可以配置JsonConvert以正确的格式获取日期?
答案 0 :(得分:44)
您可以使用IsoDateTimeConverter
并指定DateTimeFormat
以获得所需的结果,例如:
MyObject obj = JsonConvert.DeserializeObject<MyObject>(jsonString,
new IsoDateTimeConverter { DateTimeFormat = "dd/MM/yyyy" });
演示:
class Program
{
static void Main(string[] args)
{
string json = @"{ ""Date"" : ""09/12/2013"" }";
MyObject obj = JsonConvert.DeserializeObject<MyObject>(json,
new IsoDateTimeConverter { DateTimeFormat = "dd/MM/yyyy" });
DateTime date = obj.Date;
Console.WriteLine("day = " + date.Day);
Console.WriteLine("month = " + date.Month);
Console.WriteLine("year = " + date.Year);
}
}
class MyObject
{
public DateTime Date { get; set; }
}
输出:
day = 9
month = 12
year = 2013
答案 1 :(得分:6)
您也可以在JsonSerializer中配置它:
var serializer = new JsonSerializer
{
DateFormatString = "dd/MM/yyyy"
};
答案 2 :(得分:6)
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
var dateTimeConverter = new IsoDateTimeConverter { DateTimeFormat = "dd/MM/yyyy" };
myObject obj = JsonConvert.DeserializeObject<myObject>(myJSONString, dateTimeConverter);
答案 3 :(得分:3)
这就是我用的:
public class CustomDateTimeConverter : IsoDateTimeConverter
{
public CustomDateTimeConverter()
{
base.DateTimeFormat = "dd/MM/yyyy";
}
}
然后您将执行以下操作:
public class MyObject
{
[JsonConverter(typeof(CustomDateTimeConverter))]
public DateTime Date {get;set;}
}
然后使用您以前做过的任何普通方式反序列化...
MyObject obj = JsonConvert.DeserializeObject<MyObject>(json);
其他方式与@pimbrouwers所说的相同:
public class MyObject
{
[JsonProperty("Date")] //Naturally Case Sensetive
private string dateJson {get;set;}
// it would be good to look at @pimbrouwers answer and use nullable
[JsonIgnore]
public DateTime Date
{
get
{
return DateTime.ParseExact(dateJson,"dd/MM/yyyy",CultureInfo.InvariantCulture);
}
set
{
dateJson = value.ToString("dd/MM/yyyy");
}
}
}
我也只写了这样一个自定义DateTime转换器,它可以与您的自定义范围格式或日历相匹配
public class CustomDateTimeConverterJalali : DateTimeConverterBase
{
//I had no use for WriteJson section, i just wrote it, so i do not guarantee it working
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
var nullableType = Nullable.GetUnderlyingType(value.GetType());
var isNullable = nullableType != null;
DateTime date;
if (isNullable)
date = ((DateTime?) value).Value;
else
date = (DateTime) value;
PersianCalendar pc = new PersianCalendar();
writer.WriteValue(pc.GetYear(date) + "/" + pc.GetMonth(date) + "/" + pc.GetDayOfMonth(date));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
//this should likely be null, but since the provider json returned empty string, it was unavoidable... (i'm not sure what we will read using reader, if data is actually null on the json side, feel free to experiment
if (string.IsNullOrWhiteSpace((string) reader.Value))
{
return null;
}
var strDate = reader.Value.ToString();
PersianCalendar pc = new PersianCalendar();
var dateParts = strDate.Split('/');
DateTime date = pc.ToDateTime(int.Parse(dateParts[0]), int.Parse(dateParts[1]), int.Parse(dateParts[2]),
0, 0, 0, 0);
return date;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(DateTime);//DateTime=>true | DateTime?=>true
}
}
您提供的其他方式是一次配置的,可能更简单,并且在大多数情况下可能有用。...但是在这里,提供商为我提供了一项服务,该服务以两种格式提供日期对象,其中一个对象在不同的日历中分别提供两个日期...所以很高兴知道我在此处提供的这两种方式
答案 4 :(得分:2)
在WebConfig中添加文化:
<system.web>
<globalization culture="pt-BR" uiCulture="pt-BR" enableClientBasedCulture="true"/>
</system.web>
然后在WebApiConfig.cs
文件
var jsonFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
JsonSerializerSettings jSettings = new JsonSerializerSettings()
{
Culture = System.Globalization.CultureInfo.CurrentCulture
};
jsonFormatter.SerializerSettings = jSettings;
文化pt-BR
使用默认的dd-MM-yyyy
,如果您不想将文化放在WebConfig中,则只能为该对象创建实例。
答案 5 :(得分:0)
根据我的经验,最简单和最简单的解决方案始终是在您的CLR对象(string
)上添加MyObject
属性,以供JSON.Net使用。同样在您的对象上,您放置一个DateTime
属性,仅作为getter,它将使用您期望的格式解析您使用JSON.Net反序列化的日期时间字符串。
这使您可以使用开箱即用的反序列化器,并依靠良好的“塑造”来完成工作。没有麻烦,没有大惊小怪。
public class MyObject
{
public string dtStr { get; set; }
public DateTime? dt
{
get
{
DateTime? d = null;
if (!string.IsNullOrWhiteSpace(dtStr) && DateTime.TryParseExact(dtStr, "dd/mm/yyyy", CultureInfo.InvariantCultureDateTimeStyles.None, out d)
{
return d;
}
return d;
}
}
}
答案 6 :(得分:0)
根据newtonsoft,您可以将JsonSerializerSettings Class与
一起使用DateFormatString
field。我也按照下面提到的方式来做我的项目。
string json = @"[
'7 December, 2009',
'1 January, 2010',
10 February, 2010'
]";
IList<DateTime> dateList = JsonConvert.DeserializeObject<IList<DateTime>>(json, new
JsonSerializerSettings
{
DateFormatString = "d MMMM, yyyy"
});
foreach (DateTime dateTime in dateList)
{
Console.WriteLine(dateTime.ToLongDateString());
}
// Monday, 07 December 2009
// Friday, 01 January 2010
// Wednesday, 10 February 2010
答案 7 :(得分:0)
实际上上面提到的这些都没有完全解决我的问题。我发现 if any of my column data is null then NewtonSoft.JSON will suffer.
我的情况是我有一个从服务序列化并在 UI 中反序列化的数据集没有提供任何设置。
我所做的基本上是在 service(JsonConvert.SerializeObject) 和 UI(JsonConvert.DeserializeObject) 中添加以下设置
var settings = new JsonSerializerSettings
{
Culture = new System.Globalization.CultureInfo("tr-TR"),
DateFormatString = "dd.MM.yyyy",
NullValueHandling = NullValueHandling.Ignore
};
编辑:
当我执行上述操作时,Newtonsoft
将在反序列化时更改我的列顺序。因此,我只是使用以下代码更改 serialize
层中的 service
设置而不是这些设置,然后一切都开始按我预期的那样工作。
string serializedDataSet= JsonConvert.SerializeObject(dataset, Formatting.Indented, new IsoDateTimeConverter { DateTimeFormat = "dd.MM.yyyy" });