【问题标题】:Moment.js set the base time from the serverMoment.js 从服务器设置基准时间
【发布时间】:2013-11-06 21:59:29
【问题描述】:

我一直在阅读文档,但似乎找不到从服务器而不是客户端设置日期的方法?

比如这样的

moment().set('server time')

然后 moment() 将根据服务器的时间而不是客户端计算机的时间返回日期对象。

此功能是否存在,如果不存在,您会使用哪些推荐方法?现在我正在轮询服务器以获取服务器的时间,但是您可以想象这不是很有效。

更新了代码示例和摘要

我正在构建一个拍卖应用程序。所以服务器时间很关键。例如,如果用户篡改了他们的时间设置或者他们的时间是手动配置的,客户可能会看到一个已经结束的拍卖,而实际上它还有几分钟的时间。所有时间检查显然都是在服务器上完成的,但这就是我需要客户端和服务器同步的原因。现在您可以看到我每隔几秒就轮询服务器以获取最新时间。但是,我需要设置 moment() 以从我从服务器传递的变量中调用基本时间。所以每次我调用 moment() 时,它都会基于最初传入的时间而不是 new Date()。

app.getTime = ->
    setInterval ->
        $.get app.apiUrl + 'public/time', (time)  -> 
            app.now = moment(time).format('YYYY-MM-DDTHH:mm')
    , app.fetchTimeInterval

在我的应用程序的其他地方,我像这样使用应用程序的服务器时间

collection = new Auction.DealershipBasket [], query: "?$orderby=Ends&$filter=Ends lt datetime'#{app.now}'"

相反,我想调用以下命令,它会从服务器返回时间,我只需要使用来自上面 url 的 get 请求配置一次。

 now = moment().format('YYYY-MM-DDTHH:mm')

【问题讨论】:

  • 必须是准确的服务器时间吗?否则,我建议只使用服务器中的时区来转换本地时间。由于大多数时钟都是通过时间服务器同步的,因此差异应该非常小(当然,除非有人篡改了他们的时间设置)。
  • 检查更新的问题。
  • 我会研究一种获取服务器时间一次然后将差异存储到本地时间的方法。然后你可以用你自己的函数来包装你对时刻的调用,相应地调整时间。
  • 嗯。非常有趣的想法。我绝对认为那值得一试。只是认为 Moment 会让你指定一个基准时间。可能应该查看源代码,看看分叉和添加功能是多么容易。

标签: javascript date momentjs


【解决方案1】:

最好的方法是向服务器询问当前时间,然后计算服务器时间和客户端时间之间的偏移量。然后,函数可以通过使用当前客户端日期并应用服务器差异来返回任何阶段的服务器时间。

这是一个例子:

var serverDate;
var serverOffset;
$.get('server/date/url', function(data){
   // server returns a json object with a date property.
   serverDate = data.date;
   serverOffset = moment(serverDate).diff(new Date());
});

function currentServerDate()
{
    return moment().add('milliseconds', serverOffset);
}

【讨论】:

  • 这就是我正在做的事情,但我每次都需要轮询服务器以获取日期。 moment.set throws 没有方法“set”。 moment().set('time') 也不起作用。
  • 答案修改为计算服务器日期偏移
  • 完美运行。谢谢。
  • 可以使用响应头Date。成为跨域 (CORS) 的问题,需要 Access-Control-Expose-Headers
【解决方案2】:

从 Moment.js 2.10.7 开始,可以使用change the time source(参见介绍它的PR)。

您可以使用它来将 Moment.js 看到的时间与您服务器的时间同步。

function setMomentOffset(serverTime) {
  var offset = new Date(serverTime).getTime() - Date.now();
  moment.now = function() {
    return offset + Date.now();
  }
}

【讨论】:

  • 获取serverTime的中转时间呢?网络延迟不会总是让服务器看起来像是落后了几毫秒吗?如果您正在执行 date.fromNow(),这可能是一个问题,您可能会在“几秒钟内”了解刚刚发生的事情。
  • 是的,它会,但是对于我设置时钟以在客户端是没有设置时钟的 Raspberry Pi 时显示的用例,这是可以接受的。如果您要比较的日期来自同一台服务器,那也可能不是问题。您可以添加一个条件来检查在“现在”之前创建日期,以表示“刚刚”或其他内容,如果这对您来说是个问题。
  • @RMK 我正在使用 npm 库 ntp-client 来获得更准确的时间戳,因为协议考虑了往返时间。
【解决方案3】:

title: 改变时间源 版本:2.11.0 签名:|

moment.now = function () { return +new Date(); }

如果你想改变 Moment 看到的时间,你可以指定一个方法 返回自 Unix 纪元(1970 年 1 月 1 日)以来的毫秒数。

默认为:

moment.now = function () {
    return +new Date();
}

这将在调用moment() 时使用,以及在省略标记时使用的当前日期 format()。一般来说,任何需要当前时间的方法都会在后台使用它。

Changing Time Source

【讨论】:

    【解决方案4】:

    让我们试试这个:

    var momentFromServer = moment(input);

    var clampedMoment = momentFromServer.max();

    我发现 momentjs 文档中提到了这一点。

    有时,服务器时钟与客户端时钟并不完全同步。这最终会显示人性化的字符串,例如“几秒钟内”而不是“几秒钟前”。您可以使用 moment#max() 来防止这种情况: https://momentjs.com/docs/#/manipulating/max/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-04
      相关资源
      最近更新 更多