【问题标题】:How to get a worldwide valid timestamp如何获得全球有效的时间戳
【发布时间】:2016-04-27 20:46:22
【问题描述】:

在我的管理面板上,我从日期输入中选择一个日期并将其发送到服务器,服务器将其存储在 MongoDB 日期字段中。在发送之前,我将日期更改为setHour(23,59,59,999),以便倒计时在午夜结束(无论是哪个时区,只要世界上每个人在同一时刻结束,我都不会在意)。

然后(我正在使用 Meteor),我查询字段,它是一个 Date 对象,我用.getTime() 得到它的时间戳,并且由于setInterval,我每分钟计算一次剩下的时间使用新的Date(),并输出hh:mm 格式。

但是,当我将我的电脑放在不同的时区时,在下一个间隔计算时,剩余时间的值会被修改。对于不在同一时区的客户也是如此,这意味着剩余时间的计算可能不是用绝对值完成的。

选择日期:

Meteor.call("saveDate", new Date(new Date(t.find("#form_date").value).setHours(23,59,59,999)));

将其保存在服务器端的mongo中:

saveDate: date => { DailyTopic.insert({ date: date }); };

客户端计算与显示:

getTimeRemaining = function (limit) {
  let endTime = new Date(limit).setHours(23, 59, 59, 999),
      nowTime = Date.now();

  let t = endTime - nowTime;

  let seconds = Math.floor( (t/1000) % 60 ),
      minutes = Math.floor( (t/1000/60) % 60 ),
      hours   = Math.floor( (t/(1000*60*60)) % 24 );

  return ({
    'hours'   : hours,
    'minutes' : minutes,
    'seconds' : seconds
  });
}

Template.debate.onCreated(function () {
  let self = this;

  self.timeLeft = new ReactiveVar(null);

  self.limit = getTodayTopic('fetch');

  self.interval = Meteor.setInterval(function () {
    self.timeLeft.set( getTimeRemaining( getTodayTopic('fetch').date ) );
  }, (1000 * 60));

  setTimeout(function () {
    self.timeLeft.set( getTimeRemaining( getTodayTopic('fetch').date ) );
  }, 3000);

});
 [...]

displayIimeLeft: function () {
    let time = Template.instance().timeLeft.get(),
        sp = " ";

    if (time) {
      return (time.hours + sp + TAPi18n.__('hours') + sp + time.minutes + sp + TAPi18n.__('minutes'));
    }
  }
...

但我的问题是,当我需要它在世界各地都相同时,显示的倒计时会根据客户端时区而变化!

【问题讨论】:

  • Javascript 日期使用 UTC 时间值,表示自 1970-01-01T00:00:00Z 以来的毫秒数。无论主机系统的时区如何,您都可以简单地比较时间值以查看一个日期是在另一个日期之前还是之后。您关心的只是实际值的准确性,这取决于主机时钟的准确性。
  • 是的,这就是我到处阅读的内容,但是一旦我更改计算机时区,倒计时就会消失!这就是为什么只有靠近服务器的人才能正确看到倒计时的原因。我在 GMT+2,当我把我的电脑放在 UTC 或 GMT0 时,倒计时值是错误的,如果足够接近倒计时的结束时间,它就会消失。
  • 我进行了编辑,以便您可以看到我目前拥有的东西(我之前尝试过很多其他的东西)

标签: javascript date meteor timestamp


【解决方案1】:

您只需要从您的服务器创建一个限制日期的日期对象,因为您标记了 Javascript,它会像这样完成:

var time = new Date();

然后,将您需要的任何时间添加到该日期对象,即当前时间。

之后,您可以将该日期对象(具有您的服务器时区)与您的客户端日期(与他们的时区)进行比较

这可以通过Moment.js 轻松完成:

moment(time).fromNow(); // E.g: in 24 Hours.

实际上,这在没有 Moment.js 的情况下也可以轻松完成,但这取决于您。 唯一的技巧是将日期与时区进行比较。

【讨论】:

  • 我确实使用了这种方法,但问题是我需要一个多语言系统。这就是为什么,对于倒计时,我正在寻找一种 hh--mm-ss 格式。
  • 我进行了编辑,以便您可以看到我目前拥有的东西(我之前尝试过很多其他的东西)
【解决方案2】:

如果你只是倒计时到一个特定的时间,你甚至不需要将时间值转换为日期,你可以这样做:

var millisecondsLeft = timeValue - new Date();

就是这样。如果该值为负数,那么您已经过了时间值所代表的时间。

如果您传递希望倒计时的 UTC 时间值,则可以在主机系统上使用 new Date(timeValue) 创建等效日期。

使用此方法,主机时区仅用于呈现人类可读的字符串以供输出,它对日期的时间值没有影响。如果您使用像 toISOString 这样的方法,它始终是 GMT,那么无论它们的时区设置如何,您都会在所有主机上看到完全相同的时间。

因此,如果您想为特定系统倒计时到 2016 年 5 月 25 日中午,然后在该系统上创建一个日期并获取其时间值:

var timeValue = new Date(2016, 4, 25, 12).getTime();

现在您可以在任何其他系统上执行此操作:

var date = new Date(timeValue);

你会得到一个完全相同的瞬间的日期(假设 timeValue 是一个数字,而不是一个字符串)。

在获取时间值之前,只需将适当的偏移量应用于时间值或日期对象(使用 UTC 方法),即可轻松为任何时区的时间创建时间值。

【讨论】:

  • 我进行了编辑,以便您可以看到我目前拥有的东西(我之前尝试过很多其他东西)
猜你喜欢
  • 2020-08-13
  • 1970-01-01
  • 2018-10-22
  • 2014-07-15
  • 1970-01-01
  • 2010-12-02
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
相关资源
最近更新 更多