我们将 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);
但这不会将 DateTimes 转换为正确的格式,C# 如何处理仅 Date 类型?它似乎总是序列化为 DateTime.MinValue()
这是一个例子:
有人以字符串形式向我发送 json,但发送到端点的日期和日期时间格式不正确。我希望 swagger 类和 json 反序列化能够格式化它们,但事实并非如此。
这是 swagger 生成的类
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; }
}
所以我尝试强制 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\"}"
正如我在评论中提到的,JSON 中没有标准的日期表示形式。 ISO8601 是“事实上的”标准,即大多数人几年前就开始使用它。 ISO8601 不需要需要毫秒。如果另一个端点需要它们,则违反了事实上的标准。 Json.NET从4.5版本开始一直使用IOS8601。当前版本是 10.0.3。代码如下:
JsonConvert.SerializeObject(DateTime.Now)
退货
"2017-09-08T19:01:55.714942+03:00"
在我的机器上。注意时区偏移。这也是标准的一部分。
Z
表示 UTC。
您可以指定自己的时间格式,前提是它是正确的。在这种情况下,应该是yyyy-MM-ddTHH:mm:ss.fffZ
。请注意
fff
代表毫秒,HH
代表 24 小时。
以下代码
var settings = new JsonSerializerSettings {
DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffZ"
};
var json = JsonConvert.SerializeObject(DateTime.Now, settings);
退货
"2017-09-08T19:04:14.480Z"
格式字符串
不强制进行时区转换。您可以通过
Local
设置告诉 Json.NET 将时间视为 Utc
或
DateTimeZoneHandling
:
var settings = new JsonSerializerSettings {
DateFormatString = "yyyy-MM-ddTH:mm:ss.fffZ",
DateTimeZoneHandling = DateTimeZoneHandling.Utc
};
var json = JsonConvert.SerializeObject(DateTime.Now, settings);
退货:"2017-09-08T16:08:19.290Z"
更新
正如 Matt Johnson 所解释的,Z
K
会生成
Z
或偏移量,具体取决于
DateTimeZoneHandling
设置。
格式字符串
yyyy-MM-ddTH:mm:ss.fffK
与 DateTimeZoneHandling.Utc
:
var settings = new JsonSerializerSettings {
DateFormatString ="yyyy-MM-ddTH:mm:ss.fffK",
DateTimeZoneHandling = DateTimeZoneHandling.Utc
};
var json = JsonConvert.SerializeObject(DateTime.Now, settings);
会回来:2017-09-11T9:10:08.293Z
更改为
DateTimeZoneHandling.Utc
将会返回
2017-09-11T12:15:12.862+03:00
顺便说一句,除了强制的毫秒精度之外,这是 Json.NET 的默认行为。
最后,.NET 还没有Date
。
DateTime
用于日期和日期+时间值。您可以使用 DateTime.Date属性获取DateTime 的日期部分。您可以使用 DateTime.Today 检索当前日期。 一天中的时间由
TimeSpan
类型表示。您可以使用 DateTime.TimeOfDay
从
DateTime
值中提取一天中的时间。
Timespan
不是严格意义上的时间类型,因为它可以代表超过 24 小时。那是什么
?
支持明确的日期,TimeOfDay
CoreFX Lab项目
实现。其中包含“实验性”功能,这些功能“极有可能”出现在 .NET 运行时中,例如 UTF8 支持、日期、字符串、通道。其中一些已经作为单独的 NuGet 包出现。人们已经可以使用 System.Time 类,可以通过复制代码或通过实验性 NuGet 源添加它们
DateTime currentDateTime = DateTime.Now.ToUniversalTime();
var jsonDateTime = GetJSONFromUserDateTime(currentDateTime);
DateTime getDateTime = GetUserDateTimeFromJSON(jsonDateTime);
/// <summary>
/// Convert UserDateTime({9/7/2018 8:37:20 AM}) to JSON datetime(1536309440373) format
/// </summary>
/// <param name="givenDateTime"></param>
/// <returns></returns>
public static string GetJSONFromUserDateTime(DateTime givenDateTime)
{
string jsonDateTime = string.Empty;
if (givenDateTime != null)
{
JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
};
jsonDateTime = JsonConvert.SerializeObject(givenDateTime, microsoftDateFormatSettings);
jsonDateTime = jsonDateTime.Replace("\"\\/Date(", "").Replace(")\\/\"", "");
}
return jsonDateTime;
}
/// <summary>
/// Convert JSON datetime(1536309440373) to user datetime({9/7/2018 8:37:20 AM})
/// </summary>
/// <param name="jsonDateTime"></param>
/// <returns></returns>
public static dynamic GetUserDateTimeFromJSON(string jsonDateTime)
{
dynamic userDateTime = null;
if (!string.IsNullOrEmpty(jsonDateTime))
{
JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
};
userDateTime = JsonConvert.DeserializeObject("\"\\/Date(" + jsonDateTime + ")\\/\"", microsoftDateFormatSettings);
}
return userDateTime;
}
如果像 Willie Esteche 一样您希望转换一个太低的数字,您可能已经得到了 Unix 日期时间值。他的解决方案确实有效,但从 .Net Framework 4.6 开始,有一种更简单的方法可以做到这一点。
给定值 1500013000,首先使用 FromUnixTimeSeconds() 方法将其转换为 DateTimeOffset,然后简单地获取 DateTime 组件。
DateTime dt = DateTimeOffset.FromUnixTimeSeconds(1500013000).UtcDateTime;
转换回来(假设UTC)是这样执行的:
long Udt = new DateTimeOffset(dt,TimeSpan.Zero).ToUnixTimeSeconds();
你可以试试这个:
DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
就我而言,我在 vb.net 中使用此配置,它很容易转换为 c #
settings.NullValueHandling = NullValueHandling.Ignore
settings.DateTimeZoneHandling = DateTimeZoneHandling.Local
BE = JsonConvert.DeserializeObject(Of EN_BE)(str, settings)
2020-08-02T01:41:05.000000Z
我转换为与数据库相同的正确值
2020-08-01 20:41:05