C# ASP MVC Web API中带时区的日期时间+;环境足迹
我使用的是ASP MVC Web API+EF,我的客户端得到的是DateTime,而没有关于时区的信息。我试图在WebApiConfig中设置设置,但未成功:C# ASP MVC Web API中带时区的日期时间+;环境足迹,c#,entity-framework,datetime,asp.net-web-api,timezone,C#,Entity Framework,Datetime,Asp.net Web Api,Timezone,我使用的是ASP MVC Web API+EF,我的客户端得到的是DateTime,而没有关于时区的信息。我试图在WebApiConfig中设置设置,但未成功: config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local; 只有一种方法对我有效:使用DateTimeKind创建DateTime的新实例。本地: public IEnumerabl
config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling
= DateTimeZoneHandling.Local;
只有一种方法对我有效:使用DateTimeKind创建DateTime的新实例。本地:
public IEnumerable<ClientDto> Execute()
{
var clients = this.DbContext.Clients.Select(
m => new ClientDto
{
Id = m.Id,
NotificationSendingTime = m.NotificationSendingTime,
. . .
}).ToList();
clients.ForEach(m => m.NotificationSendingTime =
m.NotificationSendingTime.HasValue
? new DateTime(m.NotificationSendingTime.Value.Ticks, DateTimeKind.Local)
: m.NotificationSendingTime);
return clients;
}
在服务器端更新客户端:
if (command.CommandArg.NotificationSendingTime.HasValue)
{
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(string.IsNullOrWhiteSpace(command.CommandArg.TimeZoneId) ? "Greenwich Standard Time" : command.CommandArg.TimeZoneId);
var utc = TimeZoneInfo.ConvertTimeToUtc(command.CommandArg.NotificationSendingTime.Value, timeZoneInfo);
command.CommandArg.NotificationSendingTime = utc.Date + new TimeSpan(utc.Hour, 0, 0);
}
client.NotificationSendingTime = command.CommandArg.NotificationSendingTime;
client.TimeZoneId = command.CommandArg.TimeZoneId;
this.DbContext.SaveChanges();
在获取数据后的my angularJS控制器中:
$scope.notificationSendingTime = $scope.formData.NotificationSendingTimeOffset;
$scope.formData.NotificationSendingTime
= $filter('date')($scope.notificationSendingTime, 'HH:mm');
在提交数据之前,在my angularJS控制器中:
$scope.notificationSendingTime = $scope.formData.NotificationSendingTimeOffset;
$scope.formData.NotificationSendingTime
= $filter('date')($scope.notificationSendingTime, 'HH:mm');
时间选择器在所有浏览器中都能正常工作!谢谢。如果您将时区信息存储在单独的列中,我认为让EF进行转换并不简单。我建议将此功能放在模型本身中。对于这个简单的示例,DTO看起来是一个很好的候选者:
[DataContract]
public class Client
{
[DataMember]
public DateTime Created { get; set; }
[DataMember]
public string CreatedTimeZoneId { get; set; }
}
public class ClientDto
{
private readonly Client _client;
public ClientDto(Client client)
{
_client = client;
}
public DateTimeOffset Created
{
get
{
//TODO: Should be moved in separate helper method.
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(_client.CreatedTimeZoneId);
return new DateTimeOffset(_client.Created, timeZoneInfo.BaseUtcOffset);
}
}
}
通过使用DateTimeOffset
类型,您将不再担心时区处理。JSON.NET可以很好地使用这种类型:
// Simulate DB call
var clients = new List<Client>
{
new Client
{
Created = new DateTime(2015, 4, 27, 11, 48, 22, DateTimeKind.Unspecified),
CreatedTimeZoneId = "FLE Standard Time"
}
};
var clientDtos = clients.Select(client => new ClientDto(client));
var json = JsonConvert.SerializeObject(clientDtos);
如果有任何原因不这样做:
notificationsonsendingtime=m.NotificationSendingTime.ToLocalTime()
,即当我在Select中使用.ToLocalTime()时,在Select
中使用@Alex进行转换,我会得到以下异常:LINQ to Entities无法识别方法'System.DateTime ToLocalTime()',这个方法不能转换成存储表达式。哦,是的,当然,你是对的,它将成为查询的一部分。你在数据库中使用什么数据类型来存储日期字段?在JSON中,您是否希望日期的格式为2015-04-27T00:05:00+03:00
?在我的DB表中,我有一列TimeZoneId,其中时区以“FLE标准时间”、“夏威夷标准时间”等格式存储。这个时区信息应该添加到我的DateTime中。据我所知,客户端是执行此操作的最佳场所。感谢您的回复,好主意,但我得到“本地dateTime参数的UTC偏移量与偏移量参数不匹配”。以这种方式创建DateTimeOffset的新实例时出现异常。您能写一个引发异常的日期和时区示例吗?我找到了整个博客
[{"Created":"2015-04-27T11:48:22+02:00"}]