在 Meteor 中使用 moment.tz.setDefault() 的范围是什么?

What is the scope of moment.tz.setDefault() when used in Meteor?

TL;DR moment.tz.setDefault()的范围是什么?

我确定我的问题是因为我对 JavaScript 和 Meteor 都缺乏经验,但我已经连续好几天都在为这个问题苦苦挣扎了。

我正在开发一个必须考虑客户端时区的应用程序,但我在强制服务器代码使用客户端时区方面遇到了很大困难。一路上的某个地方——从客户端按下 "Submit" 到 Meteor 插入的那一刻——我的时区设置丢失了,正在使用本地时间(服务器的)。

应用流程是这样的:

  1. (客户端)用户提交表单
  2. (客户端)执行数据验证
  3. (服务器) 调用 Meteor 方法
  4. (服务器)执行数据验证(与之前的代码相同)
  5. (服务器)应用业务逻辑
  6. (服务器)插入数据库

我在第 1 步捕获时区,然后 尝试 将它传递到所有步骤,但我一定遗漏了一些东西,因为在第 4 步到第 5 步之间时区(似乎)丢失了.快是,我不明白为什么。我已经检查了 100 次并尝试了各种不同的排列方式,但无法弄清楚差距在哪里(我用了太多 console.log()s 这太疯狂了。)

因此,我没有尝试在使用 Moment() 的每个点设置时区(因为它默认以本地时间计算)我发现 moment.tz.setDefault() 并尝试在每个点上至少使用一次。我的应用程序中的 js 文件。但是没用。

读到这篇文章可能听起来我没有做足够的测试,但事实并非如此。我在这上面花了 10 个小时,但我就是不明白。我很想分享代码,但我认为正确分享代码太长太复杂,所以我已尽力解释问题。

好消息!你太复杂了:-)

打开浏览器控制台并输入 time = new Date()。注意它是如何在正确的时区?那是因为时区转换发生在客户端。

现在,输入 time.valueOf()。您可能知道,您知道自 1-1-1970 以来的毫秒数……但是在哪个时区?你猜对了,UTC!

因此,如果您所做的只是保存一个数字,并且客户端完全能够将该数字转换为本地时区,为什么不在服务器上保存 UTC 时间呢?你会在你的数据库中得到一个 ISODate() (这是一个奇特的 int64)。然后,当您在客户端检索它时,您可以将它放在他们的本地时间(他们可能正在旅行!)或您选择的任何其他时区。如果是某个城市的聚会,只需获取该城市的时区并将其应用到现场即可。提示:这是使用 moment.js 的合适时间,而不是之前!


编辑时间模式:

根据新信息,我想你有一些东西可以接受 arrivalTime 然后确保时间在 earlyArrivallateArrival 之间,比如 7:00 - 8:30AM。所以,将时间保存为日期

timeToDate = function(time) {
  return new Date('1970 1 1 ' + time);
};
earlyArrival = timeToDate('7:30 AM');
arrivalTime = timeToDate('8:00 AM');
lateArrival = timeToDate('8:30 AM');

然后,通过简单的数学验证:earlyArrival < arrivalTime

或者,如果您使用简单模式(您应该使用),验证模式可能如下所示:

departureTime: {
  type: Date,
  min: timeToDate('5:00 PM'),
  max: timeToDate('6:30 PM'),
  autoValue: function() {
    return timeToDate(this.value);
  },
  custom: function () {
    if (this.value < this.field('arrivalTime').value) {
      return "lateAfterEarly";
    }
  }