MVC - UTC日期到LocalTime

时间:2011-05-11 02:43:17

标签: asp.net-mvc date

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

<%: Html.DisplayFor(m=> m.SomeDate.ToLocalTime()) %>

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

9 个答案:

答案 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()。您要么需要:

  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>

请注意.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的答案)