在视图中将UTC日期时间转换为本地日期时间

4

我无意中发现Azure使用UTC时间。这没问题,但是我在部署时才发现了这一点!(在调试模式下,它只使用我的计算机时间,所以这被忽视了)

因此,我需要能够将日期时间显示为用户的本地时间。我不介意(并且更喜欢)它以UTC格式显示。 然而,在我的应用程序中有很多不同的地方出现日期,所以我想知道获取所有显示本地时间的快速和简便方法是什么。我考虑使用日期时间的编辑器模板。这是个好主意吗?我会使用什么来进行转换?

2个回答

1

这里是我设计的编辑器和显示模板,允许用户输入并显示他们所在时区的时间,并将其转换为UTC进行提交。

每个模型UTC DateTime字段都需要设置UIHint属性为自定义值“UTCTime”,以选择正确的显示和编辑模板。没有此注释的模型中的日期时间不会受到影响:

    [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;
    }

}

这仅用于我们的管理页面,因此在文本框后面有一个不太用户友好的跨度,显示编辑框转换的结果。


0

这个 链接 能帮到你吗?

问题在于你无法真正知道服务器上用户所在的时区。你最多只能猜测一个人的文化,但不能确定时区。而文化“en-us”可以假设用户在美国至少有4个时区。

另一种方法是让用户在使用您的网站时选择他们喜欢的时区。然后,您可以将此选择保存在cookie或个人资料中。有了用户的时区,您可以使用类似于以下方法的方法在时区之间进行转换:

var localDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, timeZone.TimeZoneInfo);

在编程中使用 TimeZoneInfo 类型的静态方法 ConvertTimeFromUtc。同时,你有一个 TimeZoneInfo 实例(在我的情况下是自定义类型的属性),它保留了用户的 TimeZoneInfo 设置。

回顾一下 jQuery 解决方案 - 你可以在 document.ready() 上调用这个小函数。只是要记得将所需的 CSS 类添加到你的时间显示字段中。

但最终,如果你的目标是面向多时区访问者,则可能需要询问他们首选时区以在后端进行转换,并明确地显示那些没有选择首选时区的用户的时间是 UTC 时间。


我怀疑上面的代码将在客户端浏览器上运行。由于Razor语法,代码将在服务器上执行并将时间转换为服务器本地时区,而不是客户端本地时区。一些纯JavaScript或jQuery库可能会解决这个问题。 - AKS
@AKS 当你仔细阅读答案时,你会注意到它建议即使在服务器上,你也知道最终用户的时区。然后你可以使用它进行转换。 - astaykov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接