Dom*_*Bat 16 c# datetime json date json.net
我们将JSON发送到由swagger定义的API,其中一些属性是DateTime,格式为yyyy-MM-ddThh:mm:ss.000Z(毫秒必须是3位数或者在端点处验证失败),有些属于Date(否)时间)属性.
我看到许多消息说使用这样的格式化程序:
var jsonSettings = new JsonSerializerSettings();
jsonSettings.DateFormatString = "yyyy-MM-ddThh:mm:ss.000Z"; //try .fffZ too
var jsonObject= Newtonsoft.Json.JsonConvert.DeserializeObject<OurSwaggerObject>(json , setting);
Run Code Online (Sandbox Code Playgroud)
但这并没有将DateTimes转换为正确的格式,C#如何处理仅Date类型?它似乎总是序列化为DateTime.MinValue()
这是一个例子:
有人将json作为字符串发送给我,但日期和日期时间以不正确的格式发送给端点.我希望swagger类和json反序列化可以格式化它们,但事实并非如此.
这是招摇的生成类
public class OurSwaggerObject
{
[Newtonsoft.Json.JsonProperty("dateTimeField", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
[System.ComponentModel.DataAnnotations.RegularExpression(@"^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z$")]
public DateTime dateTimeField { get; set; }
[Newtonsoft.Json.JsonProperty("dateField", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
[System.ComponentModel.DataAnnotations.RegularExpression(@"^\d{4}-\d\d-\d\d$")]
public DateTime dateField { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
所以我试着强迫json是正确的,但我做错了或者缺少了什么
string json = @"{ 'dateTimeField': '1995-04-07T00:00:00',
'dateField': '1995-04-07T00:00:00'
}";
/* The json we need to satisfy the swagger endpoint is:
{ 'dateTimeField': '1995-04-07T00:00:00.000Z',
'dateField': '1995-04-07'
}
*/
OurSwaggerObject deserialisedIntoObject = Newtonsoft.Json.JsonConvert.DeserializeObject<OurSwaggerObject>(json);
string serialisedToString = Newtonsoft.Json.JsonConvert.SerializeObject(deserialisedIntoObject);
//serialisedToString= "{\"dateTimeField\":\"1995-04-07T00:00:00\",\"dateField\":\"1995-04-07T00:00:00\"}"
var jsonSettings = new JsonSerializerSettings();
jsonSettings.DateFormatString = "yyyy-MM-ddThh:mm:ss.fffZ"; //this won't help much for the 'date' only field!
deserialisedIntoObject = Newtonsoft.Json.JsonConvert.DeserializeObject<OurSwaggerObject>(json,jsonSettings);
serialisedToString = Newtonsoft.Json.JsonConvert.SerializeObject(deserialisedIntoObject, jsonSettings);
//serialisedToString="{\"dateTimeField\":\"1995-04-07T00:00:00\",\"dateField\":\"1995-04-07T00:00:00\"}"
Run Code Online (Sandbox Code Playgroud)
Pan*_*vos 27
正如我在评论中提到的,JSON中没有标准的日期表示.ISO8601是事实上的标准,即几年前大多数人开始使用它.ISO8601并没有要求毫秒.如果另一个端点需要它们,则违反了事实标准.
Json.NET从4.5版开始使用IOS8601.目前的是10.0.3.以下代码:
JsonConvert.SerializeObject(DateTime.Now)
Run Code Online (Sandbox Code Playgroud)
回报
"2017-09-08T19:01:55.714942+03:00"
Run Code Online (Sandbox Code Playgroud)
在我的机器上.注意时区偏移量.这也是标准的一部分.Z是指UTC.
您可以指定自己的时间格式,前提是它是正确的格式.在这种情况下,它应该是yyyy-MM-ddTH:mm:ss.fffZ.请注意fff毫秒和 HH 24小时.
以下代码
var settings=new JsonSerializerSettings{DateFormatString ="yyyy-MM-ddTH:mm:ss.fffZ"};
var json=JsonConvert.SerializeObject(DateTime.Now,settings);
Run Code Online (Sandbox Code Playgroud)
回报
"2017-09-08T19:04:14.480Z"
Run Code Online (Sandbox Code Playgroud)
格式字符串并没有强制时区转换.您可以告诉Json.NET通过DateTimeZoneHandling设置将时间视为Local或Utc:
var settings=new JsonSerializerSettings{
DateFormatString ="yyyy-MM-ddTH:mm:ss.fffZ",
DateTimeZoneHandling=DateTimeZoneHandling.Utc};
var json=JsonConvert.SerializeObject(DateTime.Now,settings);
Run Code Online (Sandbox Code Playgroud)
退货:
"2017-09-08T16:08:19.290Z"
Run Code Online (Sandbox Code Playgroud)
UPDATE
正如马特约翰逊所解释的那样,Z只是一个文字,同时K产生一个Z或一个偏移,取决于DateTimeZoneHandling设置.
yyyy-MM-ddTH:mm:ss.fffKDateTimeZoneHandling.Utc 的格式字符串:
var settings=new JsonSerializerSettings{
DateFormatString ="yyyy-MM-ddTH:mm:ss.fffK",
DateTimeZoneHandling=DateTimeZoneHandling.Utc};
var json=JsonConvert.SerializeObject(DateTime.Now,settings);
Run Code Online (Sandbox Code Playgroud)
将返回 :
2017-09-11T9:10:08.293Z
Run Code Online (Sandbox Code Playgroud)
改变DateTimeZoneHandling.Utc将返回
2017-09-11T12:15:12.862+03:00
Run Code Online (Sandbox Code Playgroud)
顺便说一句,Json.NET 的默认行为除了强制毫秒精度之外.
最后,.NET没有Date-only类型还.DateTime用于日期和日期+时间值.您可以使用DateTime.Date属性获取DateTime的日期部分.您可以使用DateTime.Today检索当前日期.
时间由Timespan类型表示.您可以使用DateTime.TimeOfDay从DateTime值中提取一天中的时间.Timespan不是严格意义上的时间类型,因为它可以代表超过24小时.
那是什么还?
支持显式日期,TimeOfDay正在通过CoreFX Lab项目.这包含极有可能出现在.NET运行时中的"实验性"功能,如UTF8支持,Date,String,Channles.其中一些已经显示为单独的NuGet包.
可以通过复制代码或通过实验性NuGet源添加它们来使用System.Time类