【问题标题】:Initialise moment.js with UTC datetime value使用 UTC 日期时间值初始化 moment.js
【发布时间】:2018-03-22 20:43:10
【问题描述】:

在我的应用程序中,所有日期时间都以 UTC 格式存储在数据库中。然后,当服务器端代码呈现 HTML 时,这些日期将转换为正确的时区。

但是,我在客户端 JavaScript 中使用 moment.js 将 UTC 日期时间转换为本地时区时遇到问题。

在下面的示例中,存储在数据库中的 UTC 日期为 2017-10-10 16:53:10.127。我在英国,夏令时仍然有效,所以我希望日期时间呈现为 2017 年 10 月 10 日 17:53:10 - 比 UTC 值早一个小时。

function foo() {
    $.get({
        url: '/foo/583',
        cache: false,
        success: function(data) {
            console.log('Raw:        ' + data.UpdatedAtUtc);

            var utc = moment.utc(data.UpdatedAtUtc);
            console.log('Moment UTC: ' + utc.format('DD MMM YYYY HH:mm:ss'));
            console.log('Moment Local:' + utc.local().format('DD MMM YYYY HH:mm:ss'));
        }
    });
}

这个函数的控制台输出如下:

Raw:          /Date(1507650790127)/
Moment UTC:   10 Oct 2017 15:53:10
Moment Local: 10 Oct 2017 16:53:10

使用this online converter,我已经确认 JSON 中的原始日期时间值代表我的 UTC 值(2017 年 10 月 10 日,下午 4:53:10 UTC),所以我很高兴 MVC 支持 - end 正确转换 UTC 值,而不会混淆时区。

客户端调试器报告的值是正确的“/Date(1507650790127)/”,这是我传递给moment提供的utc()方法的值.js 并理解它会将其解释为 UTC 日期时间值。

utc() 方法的documentation 声明:

如果您希望将日期作为 UTC 日期进行交互,请使用 moment.utc:

moment.utc('2016-01-01T23:35:01');

所以我假设我使用正确。然而,我的测试的输出表明 datetime 值被视为本地时间,因为 utc() 方法的格式化输出缩短了一个小时的时间,将其写入控制台为 15:53 而不是 16:53

如何使用 /Date()/ 字符串正确初始化 moment.js?

【问题讨论】:

  • 请注意1507650790127是10 October 2017 15:53:10.127 UTC(见epochconverter.com),所以我认为你的代码没问题。
  • 您使用的在线转换器正在显示该时间戳的 本地 表示(对我来说,GMT+2,它显示的是下午 5:53)。
  • 看来我当时选错了在线转换器!难怪我一直在兜圈子!看起来罪魁祸首很可能是 MVC 的 Controller.JSON() 方法,那么如果它在转换为 /Date()/ 之前将我的 UTC 日期值转换为本地时间。太棒了:(/感谢你们的帮助!

标签: javascript asp.net-mvc datetime momentjs utc


【解决方案1】:

感谢 VincencoC 和 robertklep 指出从我的 MVC 后端传递的值是问题所在 - moment.js 工作正常。

事实证明,Controller.JSON() 方法假设我的日期在本地时区,并在序列化为 JSON 之前将它们从本地转换为 UTC。

为了解决这个问题,我向 MVC 项目添加了一个新类,以使用来自 NuGet 的 Newtonsoft JSON.Net 库提供自定义 JSON 序列化:

public class JsonNetResult : JsonResult
{
    private readonly string _json;

    public JsonNetResult(object data, JsonRequestBehavior behavior = JsonRequestBehavior.AllowGet)
    {
        _json = JsonConvert.SerializeObject(data, Formatting.None, new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });
        JsonRequestBehavior = behavior;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.HttpContext.Response;
        response.ContentType = "application/json";
        response.Write(_json);
    }
}

为了使用该类,我更新了相关操作以返回 JsonNetResult 而不是 JsonResult,并更改了返回值,如下所示:

public JsonNetResult AuditTrail(int id)
{
    var data = GetAuditData(id);

    //return this.Json(data, JsonRequestBehavior.AllowGet);
    return new JsonNetResult(data);
}

这现在将我所有的 DateTimes 格式化为“YYYY-MM-DD HH:mm:ss”格式而不是 /Date()/ 并且在此过程中不进行时区转换。

【讨论】:

    猜你喜欢
    • 2015-12-14
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 2014-06-11
    • 2013-10-24
    • 2016-12-18
    • 2018-07-08
    相关资源
    最近更新 更多