Преобразование из UTC Datetime в местное datetime в представлении
Поэтому я случайно столкнулся с реальностью того, что Azure работает по времени UTC. Это нормально, за исключением того факта, что я узнал об этом только тогда, когда он был развернут! (Когда он находится в режиме отладки, он просто использует мое время компа, так что это было упущено)
Поэтому мне нужно иметь возможность просто отображать дату и время для пользователя, как там время. Я не против (и предпочитаю) это в UTC. Однако у меня есть много разных мест, где даты появляются в моем приложении, поэтому я задаюсь вопросом, как быстро и грязно решить, чтобы все дисплеи отображали местное время. Я думал об использовании шаблона редактора для даты и времени. Это хорошая идея? Что бы я использовал, чтобы сделать преобразование?
2 ответа
Вот шаблоны редактора и отображения, которые я придумал, которые позволяют пользователю вводить и отображать время в своем часовом поясе, а также преобразовывать его в UTC для отправки.
Для атрибута UIHint необходимо установить пользовательское значение "UTCTime" для каждого поля UTC DateTime модели, как показано ниже, для выбора правильных шаблонов отображения и редактирования. DateTimes в моделях без этой аннотации не будет применяться:
[UIHint("UTCTime")]
[DataType(DataType.DateTime)]
public DateTime LastSeen { get; set; }
/Views/Shared/EditorTemplatesUTCTime.cshtml:
@model DateTime?
@{
var name = Html.GetFieldNameForModel(); // See the HTML extension at the end of this post
var boxName = name + ".Value";
var boxId = name + "_Value";
var divId = name + "_UTC";
}
@Html.TextBoxFor(m => m.Value, new { type = "datetime", onBlur ="$('#" + name + "').val(UTCDateFuncs.ToUTCDate($('#" + boxId + "').val()));$('#" + divId + "').html('UTC:' + $('#" + name + "').val());$('#" + boxId + "').attr('title','UTC:' + $('#" + name + "').val());" })<span id="@divId"></span>
<script>
new function () {
var utcVal = $('#@(boxId)').val();
$('#@(boxId)').val(UTCDateFuncs.FromUTCDate(utcVal));
$('#@(boxId)').attr('title', 'converted from UTC ' + utcVal);
}
</script>
@Html.HiddenFor(m=>m)
\ Views \ Shared \ DisplayTemplates \ UTCTime.cshtml
@model DateTime?
@if(Model.HasValue){<span class="UTCTime">@Model</span>}
Обязательный javascript в шаблоне сайта или где-то еще (но не в шаблоне):
// UTC Date
$(function () {
$('.UTCTime').each(function () {
var oldtext = $(this).html();
var result = UTCDateFuncs.FromUTCDate(oldtext);
$(this).html(result);
$(this).attr("title", "Converted from UTC " + oldtext);
});
});
var UTCDateFuncs = {
ToUTCDate: function (datetext) {
try {
var n = new Date(datetext);
offsetms = n.getTimezoneOffset() * 60 * 1000;
n = new Date(n.valueOf() + offsetms);
result = n.toDateString() + " " + n.toLocaleTimeString();
}
catch (ex) {
console.warn("Error converting time", ex);
}
return result;
},
FromUTCDate: function (datetext) {
var result;
try {
var n = new Date(datetext);
offsetms = n.getTimezoneOffset() * 60 * 1000;
n = new Date(n.valueOf() - offsetms);
result = n.toDateString() + " " + n.toLocaleTimeString();
}
catch (ex) {
console.warn("Error converting time", ex);
}
return result;
}
};
Также использует это расширение HTML: \Controllers\Extensions\HtmlExtensions.cs
using System;
using System.Web.Mvc;
public static class HtmlExtensions
{
public static string GetFieldNameForModel<TModel>(this HtmlHelper<TModel> htmlHelper)
{
var ti = htmlHelper.ViewData.TemplateInfo;
var name = ti.HtmlFieldPrefix;
return name;
}
}
Это используется исключительно на наших административных страницах, поэтому после текстового поля есть не очень удобный диапазон, который показывает результат преобразования для окна редактора.
Вам это поможет?
Проблема в том, что вы не знаете часовой пояс пользователя на сервере. В лучшем случае можно догадаться о своей культуре, но не о часовом поясе. И культура "en-us" может иметь как минимум 4 часовых пояса, если предположить, что пользователь находится в США.
Другой подход заключается в том, чтобы пользователь выбирал / выбирал предпочтительный часовой пояс при работе с вашим сайтом. Затем вы можете сохранить этот выбор в файле cookie или в профиле. Имея часовой пояс пользователя, вы можете конвертировать между часовыми поясами следующим способом:
var localDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, timeZone.TimeZoneInfo);
Где вы используете статический метод ConvertTimeFromUtc типа TimeZoneInfo. А также у вас есть экземпляр TimeZoneInfo (в моем случае это свойство моего пользовательского типа), в котором хранится пользовательская настройка TimeZoneInfo.
Возвращаясь к решению jQuery - вы можете использовать это, вызывая эту маленькую функцию в document.ready(). Просто имейте в виду, чтобы добавить желаемый класс CSS в ваши поля отображения времени.
Но, в конце концов, если вы нацеливаетесь на посетителей с несколькими часовыми поясами, вы можете попросить их указать предпочитаемый часовой пояс, чтобы выполнить преобразование на бэкенде, и явно показать, что время указано в UTC для пользователей, которые не выбрали предпочитаемый часовой пояс. Часовой пояс.