我们有一个MVC项目,我需要显示转换为用户本地时间的UTC日期。在我的模型中,我传递了UTC日期,在视图中我尝试执行以下操作:
<%: Html.DisplayFor(m=> m.SomeDate.ToLocalTime()) %>
这会引发异常。任何人都可以指出我如何将UTC日期转换为本地日期时间以便在客户端显示的正确方向。我们将日期存储为UTC,并且在显示时,这些日期将需要转换为本地机器等效日期。
答案 0 :(得分:12)
DateTime now = DateTime.UtcNow;
DateTime localNow = TimeZoneInfo.ConvertTimeFromUtc(now, TimeZoneInfo.Local);
答案 1 :(得分:9)
您需要存储用户时区服务器端,然后使用类似的东西(虽然它应该在控制器中完成,而不是视图):
@TimeZoneInfo.ConvertTimeFromUtc(Model.CreatedOn, TimeZoneInfo.FindSystemTimeZoneById("E. Australia Standard Time"))
答案 2 :(得分:4)
在mvc中,您可以通过操作过滤器解决此问题。
请使用以下步骤:
1)在会话中存储客户端时区偏移信息
2)创建DatetimeConverter助手类。
public class DateTimeConverter
{
public static DateTime? ToLocalDatetime(DateTime? serverDate, int offset)
{
if (serverDate == null) return null;
return serverDate.Value.AddMinutes(offset * -1);
}
}
3)。创建动作过滤器。
public class LocalDateTimeConverter : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var model = filterContext.Controller.ViewData.Model;
if (model != null && filterContext.HttpContext.Session["LocalTimeZoneOffset"] != null)
ProcessDateTimeProperties(model, filterContext);
base.OnActionExecuted(filterContext);
}
private void ProcessDateTimeProperties(object obj, ActionExecutedContext filterContext)
{
if (obj.GetType().IsGenericType)
{
foreach (var item in (IList)obj)
{
ProcessDateTimeProperties(item, filterContext);
}
}
else
{
TypeAccessor member;
List<PropertyInfo> props = new List<PropertyInfo>();
props.AddRange(obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty).ToList());
member = TypeAccessor.Create(obj.GetType());
foreach (PropertyInfo propertyInfo in props)
{
if (propertyInfo.PropertyType == typeof(DateTime) || propertyInfo.PropertyType == typeof(DateTime?))
{
{
member[obj, propertyInfo.Name] = DateTimeConverter.ToLocalDatetime((DateTime?)propertyInfo.GetValue(obj), ((int)filterContext.HttpContext.Session["LocalTimeZoneOffset"]));
}
}
else if (propertyInfo.PropertyType.IsGenericType && propertyInfo.GetValue(obj) != null)
{
foreach (var item in (IList)propertyInfo.GetValue(obj))
{
ProcessDateTimeProperties(item, filterContext);
}
}
}
}
}
}
4)。对包含返回视图的模型数据的操作应用LocalDateTimeConverter过滤器。
在这些步骤之后,您可以在视图中看到包含转换为本地日期时间的dateTime信息的结果。
答案 3 :(得分:2)
感觉有点像kludge,但这在MVC3客户端中起作用
@DateTime.Parse(Html.DisplayFor(m=> m.SomeDate).ToString()).ToLocalTime().ToString()
答案 4 :(得分:2)
由于服务器位于UTC中,因此无法在服务器上执行ToLocalTime()。您要么需要:
这是我用来简化第二种方法以处理Razor视图的技巧:
服务器呈现带有特殊类“ .mytime”和自定义属性“ utc”中指定的utc时间(来自服务器)的元素:
<div class="mytime" utc ="@date.ToString("o")"></div>
<span class="mytime" utc ="2018-12-28T02:36:13.6774675Z"></span>
请注意.ToString(“ o”)是如何以UTC时间编写。
然后使用“ mytime”类遍历所有元素的本地jQuery函数,读取属性中的UTC值,然后进行转换。
$(function () {
var key = $(".mytime").each(function (i, obj) {
var element = $(this); // <div> or <span> element.
var utc = element.attr("utc"); // "2018-12-28T02:36:13.6774675Z"
var d = new Date(utc);
var l = d.toLocaleString(); // Runs client side, so will be client's local time!
element.text(l);
});
});
然后我创建了一个用于渲染的MVC剃刀助手:
public static MvcHtmlString LocalDate(this HtmlHelper helper, DateTime date)
{
// Must use MvcHtmlString to avoid encoding.
return new MvcHtmlString(String.Format("<span class=\"mytime\" utc =\"{0}\"></span>", date.ToString("o")));
}
所以现在我的视图仅包括上面的JQuery和脚本,然后执行了
Created at @Html.LocalDate(Model.CreatedDate)
由于这是在jQuery的$()onload中调用的,因此它将在服务器一直向下发送后运行。
像魅力一样工作!
答案 5 :(得分:1)
所有好的答案。我是这样做的:
@Html.DisplayFor(m=> m.SomeDate.ToLocalTime()
.ToString(
CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern
+ " "
+ CultureInfo.CurrentUICulture.DateTimeFormat.LongTimePattern))
答案 6 :(得分:0)
使用此代码将utc时间转换为本地时间
<%: Html.DisplayFor(m=> m.SomeDate.ToLocalTime().ToString()) %>
您可以在剃刀中使用以下代码
@Html.DisplayFor(m=> m.SomeDate.ToLocalTime().ToString())
答案 7 :(得分:0)
将UTC日期时间转换为LocalDate也可以使用jquery完成。使用jquery执行此操作的主要好处是您已经在azure上托管了您的网站。上面给出的一些方法不起作用。只剩下一个使用jquery / javascript的选项。作为Datetime.Now,如果您的网站托管在azure上,将返回datetime.now.tolocaltime()的utc时间。请在下面的jquery中找到将UTC时间转换为localdatetime的示例。
var date = new Date('2/8/2018 3:57:48 PM UTC');
date.toString() // "Thu Feb 08 2018 21:27:48 GMT+0530 (India Standard Time)"
答案 8 :(得分:0)
在.NET Core项目中,我终于成功使用以下剃刀代码:
@Model.DateUpdated.ToLocalTime().ToString(
CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern
+ " " +
CultureInfo.CurrentUICulture.DateTimeFormat.LongTimePattern)
(灵感来自凯利·R的答案)