在 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 插入的那一刻——我的时区设置丢失了,正在使用本地时间(服务器的)。
应用流程是这样的:
- (客户端)用户提交表单
- (客户端)执行数据验证
- (服务器) 调用 Meteor 方法
- (服务器)执行数据验证(与之前的代码相同)
- (服务器)应用业务逻辑
- (服务器)插入数据库
我在第 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
然后确保时间在 earlyArrival
和 lateArrival
之间,比如 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";
}
}
TL;DR moment.tz.setDefault()
的范围是什么?
我确定我的问题是因为我对 JavaScript 和 Meteor 都缺乏经验,但我已经连续好几天都在为这个问题苦苦挣扎了。
我正在开发一个必须考虑客户端时区的应用程序,但我在强制服务器代码使用客户端时区方面遇到了很大困难。一路上的某个地方——从客户端按下 "Submit" 到 Meteor 插入的那一刻——我的时区设置丢失了,正在使用本地时间(服务器的)。
应用流程是这样的:
- (客户端)用户提交表单
- (客户端)执行数据验证
- (服务器) 调用 Meteor 方法
- (服务器)执行数据验证(与之前的代码相同)
- (服务器)应用业务逻辑
- (服务器)插入数据库
我在第 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
然后确保时间在 earlyArrival
和 lateArrival
之间,比如 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";
}
}