使用 UTC 日期时间值初始化 moment.js

Initialise moment.js with UTC datetime value

在我的应用程序中,所有日期时间都以 UTC 格式存储在数据库中。当服务器端代码呈现 HTML.

时,这些日期随后会转换为正确的时区

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

在下面的示例中,数据库中存储的 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 值(10/10/2017,4:53:10 PM UTC),所以我我很高兴 MVC 后端能够正确转换 UTC 值而不会弄乱时区。

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

utc() 方法的 documentation 指出:

If you wish to interact with the date as a UTC date, use moment.utc:

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

所以我假设我正在正确使用它。然而,我的测试输出表明日期时间值被视为本地时间,因为 utc() 方法的格式化输出已经缩短了一个小时的时间,将其作为 15:53 而不是 16:53

写入控制台

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

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

事实证明,Controller.JSON() 方法假设我的日期在本地时区,并在序列化为 JSON.

之前将它们从本地转换为 UTC

为了解决这个问题,我在 MVC 项目中添加了一个新的 class 以使用 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);
    }
}

为了使用 class,我已将相关操作更新为 return JsonNetResult 而不是 JsonResult,并更改了 return 值,如下所示:

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()/ 并且在此过程中不进行时区转换。