我正在使用ASP MVC Web API + EF,而我的客户正在获取没有时区信息的DateTime。我试图在WebApiConfig中设置设置但没有成功:
config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling
= DateTimeZoneHandling.Local;
唯一的方法是为我工作:使用DateTimeKind.Local创建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;
}
但在这种情况下,我必须使用.ToList()并为每个项目设置新的DateTime和时区。
如何设置WebApi或EF以自动添加有关时区的信息?感谢。
更新
我似乎找到了解决方案。 我的HTML:
<!-- Timepicker -->
<input id="notificationSendingTime"
name="notificationSendingTime"
type="text"
class="form-control"
data-ng-model="notificationSendingTime"
bs-timepicker
data-time-format="HH:mm"
data-time-type="date"
data-length="1" data-minute-step="30"
data-arrow-behavior="picker" />
<!-- Timezone -->
<button type="button" class="btn btn-default full-width time-zone" ng-model="formData.TimeZoneId"
data-html="1" data-animation="" placeholder="Time Zone..."
ng-options="timeZone.Id as timeZone.FriendlyName for timeZone in timeZones" bs-select>
Action <span class="caret"></span>
</button>
我的客户端:
public class ClientDto
{
public int Id { get; set; }
public DateTime? NotificationSendingTime { get; set; }
public DateTimeOffset? NotificationSendingTimeOffset
{
get
{
if (!this.NotificationSendingTime.HasValue)
{
return null;
}
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(string.IsNullOrWhiteSpace(this.TimeZoneId) ? "Greenwich Standard Time" : this.TimeZoneId);
var offset = TimeZoneInfo.ConvertTimeFromUtc(this.NotificationSendingTime.Value, timeZoneInfo);
return offset;
}
}
public string TimeZoneId { get; set; }
}
在服务器端更新客户端:
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();
在获取数据后的angularJS控制器中:
$scope.notificationSendingTime = $scope.formData.NotificationSendingTimeOffset;
在提交数据之前在我的angularJS控制器中:
$scope.formData.NotificationSendingTime
= $filter('date')($scope.notificationSendingTime, 'HH:mm');
timepicker适用于所有浏览器!感谢。
答案 0 :(得分:0)
如果您将时区信息存储在单独的列中,我认为制作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);
生成的JSON将是:
[{"Created":"2015-04-27T11:48:22+02:00"}]