【发布时间】:2019-12-31 00:13:30
【问题描述】:
问题:
对于内部计算机时钟关闭的用户,您如何规范化 javascript 中的客户端时间戳?请注意,我处理的是 UTC 时间。
上下文:
我有一个 AWS ElasticSearch 实例,其中设置了几个批处理和节流操作,这使得服务器端时间戳不可靠(因为数据可能无序进入,并且顺序很重要)。因此,我需要让我的客户端时间戳更可靠。
约束:
我无法发出任何服务器端请求(需要将 HTTP 请求保持在最低限度),但我可以包含在我的 javascript 首次加载到客户端时生成的服务器端时间戳.
尝试的解决方案:
外部定义的变量:
-
serverTimestamp- UTC 时间戳(以毫秒为单位),在加载 javascript 时在服务器端生成。 -
getCookie- 获取给定键的 cookie 值的函数(如果未找到,则为空字符串)。
文件的缓存控制设置为 "public,max-age=300,must-revalidate"(所以 5 分钟)。
const getTimestamp = (function() {
// This cookie is set on the `unload` event, and so should be greater than
// the server-side timestamp when set.
/** @type {!number} */
const cookieTimestamp = parseInt(getCookie("timestamp_cookie"), 10) || 0;
// This timestamp _should_ be a maximum of 5 minutes behind on page load
// (cache lasts 5 min for this file).
/** @type {!number} */
const storedTimestamp = cookieTimestamp > serverTimestamp ?
cookieTimestamp : serverTimestamp;
return function () {
/** @type {!number} */
const timestamp = Date.now();
// This timestamp should be, at a *maximum*, 5-6 minutes behind
// (assuming the user doesn't have caching issues)
/** @type {!number} */
const backupTimestamp = storedTimestamp
+ parseFloat(window.performance.now().toFixed(0));
// Now let's check to see if the user's clock is
// either too fast, or too slow:
if (
// Timestamp is smaller than the stored one.
// This means the user's clock is too slow.
timestamp < backupTimestamp
// Timestamp is more than 6 minutes ahead. User's clock is too fast.
// (Using 6 minutes instead of 5 to have 1 minute of padding)
|| (timestamp - backupTimestamp) > 360000
) {
return backupTimestamp;
} else {
// Seems like the user's clock isn't too fast or too slow
// (or just maximum 1 minute fast)
return timestamp;
}
}
})();
解决问题:
使用上面的getTimestamp 函数,运行(new Date(getTimestamp())).getUTCDate() 会在第二天为某些用户返回,而getUTCHours 似乎在边缘情况下到处都是。我无法自行诊断问题。
【问题讨论】:
-
不要用时间戳标记从 GMT 开始的日期,如果需要,您可以翻译成您当地的 TZ?
-
我实际上正在尝试将所有内容保持在 GMT / UTC 中。我不希望这特定于任何时区——我正在尝试跨奇怪的时区/浏览器标准化时间。
-
使用 Date.toUTCString() 代替 Date.toString():stackoverflow.com/questions/17545708/…
-
您不能依赖客户端时间,因为它可以更改。您将不得不依靠您控制时间的服务器。在 PHP 中你会做类似
<?php date_default_timezone_set('UTC'); $o = new StdClass; if(isset($_POST['get_time'])){ /* make sure AJAX get_time is set */ $o->time = time(); echo json_encode($o); /* now you have object with time property for javascript AJAX argument */ } ?> -
您需要什么精度(毫秒、秒、分钟?);你是否足够信任客户?即,如果客户端操纵 javascript 或发布错误数据,您的系统可能发生的最坏情况是什么? NTP 的存在是因为很难准确地进行分布式时间同步,但如果您不太关心秒数,并且对修复关闭一天左右的客户端时钟更感兴趣,那么@symcbean 解决方案可能就足够了。我很犹豫,因为你说“顺序很重要”!我对您的最终解决方案感兴趣,希望看到您将其发布为答案。
标签: javascript