MVC - UTC日期到LocalTime

Ami*_*esh 12 asp.net-mvc date

我们有一个MVC项目,我需要显示转​​换为用户本地时间的UTC日期.在我的模型中,我传递了UTC日期,在视图中我尝试执行以下操作:

<%: Html.DisplayFor(m=> m.SomeDate.ToLocalTime()) %>
Run Code Online (Sandbox Code Playgroud)

这引发了一个例外.任何人都可以指出我如何将UTC日期转换为本地日期时间以便在客户端显示的正确方向.我们将日期存储为UTC,并且在显示时,这些日期将需要转换为本地机器等效日期.

Cha*_*ran 13

DateTime now = DateTime.UtcNow;
DateTime localNow = TimeZoneInfo.ConvertTimeFromUtc(now, TimeZoneInfo.Local);
Run Code Online (Sandbox Code Playgroud)

  • 新闻快讯:当客户端请求您的页面时,剃刀视图(cshtml)构建在服务器端,然后流式传输到客户端. (10认同)
  • @Amitesh,在您的问题的示例中,您正在尝试转换服务器端的日期. (3认同)

Tre*_*oll 9

您需要存储用户时区服务器端,然后使用类似的东西(虽然它应该在控制器中完成,而不是视图):

@TimeZoneInfo.ConvertTimeFromUtc(Model.CreatedOn, TimeZoneInfo.FindSystemTimeZoneById("E. Australia Standard Time"))
Run Code Online (Sandbox Code Playgroud)


Mik*_*e S 7

您不能在服务器上执行 ToLocalTime() ,因为服务器采用 UTC。您要么需要:

  1. 让客户端以某种方式发送它的时区(这可能很棘手,因为默认情况下您不会通过 GET 请求获取它)
  2. 让服务器向下发送 UTC,客户端将其转换为本地时间。如果您使用 AJAX,这会自然发生,但仅使用剃刀视图就很麻烦:

这是我用来使 Razor 视图的第二种方法非常容易的技巧:

服务器呈现具有特殊类“.mytime”和自定义属性“utc”中指定的 utc 时间(来自服务器)的元素:

   <div class="mytime" utc ="@date.ToString("o")"></div>
   <span class="mytime" utc ="2018-12-28T02:36:13.6774675Z"></span>
Run Code Online (Sandbox Code Playgroud)

请注意, .ToString("o") 是如何以 UTC 时间写入的。

然后让本地 jQuery 函数遍历所有具有“mytime”类的元素,读取属性中的 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);
    });
});
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个用于渲染的 MVC razor helper:

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")));
}
Run Code Online (Sandbox Code Playgroud)

所以现在我的视图只包含上面的 JQuery 和脚本,然后执行:

Created at @Html.LocalDate(Model.CreatedDate)
Run Code Online (Sandbox Code Playgroud)

由于这是在 jQuery 的 $() onload 中调用的,因此它一直在服务器发送完毕后运行。

像魅力一样工作!


小智 5

感觉有点混乱,但这在 MVC3 客户端中有效

@DateTime.Parse(Html.DisplayFor(m=> m.SomeDate).ToString()).ToLocalTime().ToString()
Run Code Online (Sandbox Code Playgroud)


Jig*_*iya 5

在 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);
    }

}
Run Code Online (Sandbox Code Playgroud)

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);
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

4).对包含模型数据的操作应用LocalDateTimeConverter过滤器以返回视图。

在所有这些步骤之后,您可以在视图中看到结果,其中包含转换为本地日期时间的日期时间信息。