在javascript中构建时间戳

building a timestamp in javascript

本文关键字:时间戳 构建 javascript      更新时间:2023-09-26

当页面加载时,我在页面中注入了以下数据:

var TimeZoneOffset = parseFloat($('#DataUserTimeZoneOffset').html());
var TheDay = parseInt($('#DataUserDayToday').html(), 10);
var TheMonth = parseInt($('#DataUserMonthToday').html(), 10);
var TheYear = parseInt($('#DataUserYearToday').html(), 10);
var TheHours = parseInt($('#DataUserTimeStampHours').html(), 10);
var TheMinutes = parseInt($('#DataUserTimeStampMinutes').html(), 10);

我像这样在document.ready上建立日期:

var TheDateToday = new Date();
TheDateToday.setUTCFullYear(TheYear, TheMonth, TheDay);
TheDateToday.setUTCHours(TheHours, TheMinutes, 0, 0);

然后,我像这样确定本地时间:

var TheLocalTime = new Date(TheDateToday.getTime() + TimeZoneOffset);

我根本不想依赖用户的时钟来显示时间。我使用用户的时间来计算我创建的本地时间与用户计算机上的时间之间的偏移量。所以我这样做:

var UserBrowserTime = new Date();
var UserTimeOffset = TheLocalTime.getTime() - UserBrowserTime.getTime();

在我的应用程序中,用户创建了存储在本地存储中的对象。这些对象有一个名为TimeCreated的属性。每隔一分钟,这些对象就被ajax发送回服务器。但是,如果用户从站点断开连接,当他返回时可能仍有一些本地存储等待ajax,因此我不能将在服务器上接收ajax调用的时间用作创建这些对象的时间。相反,我希望将对象及其TimeCreated时间戳ajax回传给服务器。为了构建这个时间戳,我想获得用户的时间,并添加我在页面加载时创建的UserTimeOffset。

这能行吗?我是不是把事情复杂化了?要解决的问题是,存储在本地存储中的数据可以在创建时间之后很久才ajax,并且当服务器接收到数据时,它必须知道对象是在什么时间创建的。

我正在考虑的另一种选择是用SetTimeout函数构建我自己的时钟,每1000ms,向UserBrowserTime变量添加一秒,并将其用作我的时间戳。

谢谢你的建议。

通常的技巧是使用UTC。创建一个本地日期对象,并使用来自服务器的UTC数据设置它(我猜这就是你现在正在做的)。

然后您可以确定本地偏移量(即本地系统与服务器发送的"正确"时间之间的差异)为:

var offset = TheDateToday - new Date();

现在当你需要时间的时候,你可以这样做:

var now = new Date((new Date()).getTime() + offset);

您将错过本地机器和服务器之间的任何延迟,希望是短的。当您将内容发送回服务器时,请使用UTC时间戳。一个简单的函数是:

function padZ(n) {
  return (n<10? '0' : '') + n;
}
function getUTCTimestamp(d) {
  return d.getUTCFullYear() + '-' + padZ(d.getUTCMonth() + 1) +
         '-' + padZ(d.getUTCDate()) + 'T' + padZ(d.getUTCHours()) + ':' +
         padZ(d.getUTCMinutes()) + ':' + padZ(d.getUTCMinutes()) + 'Z';
}
var d = new Date();
alert(d + ''n' + getUTCTimestamp(d));  // something like 2011-11-10T14:18:23Z

我想知道这两种方法是否可以有效地处理延迟。我不知道实际的答案,但是来自服务器的时间肯定不能保证立即得到处理。

如果页面呈现缓慢,那么从服务器提供参考时间到将其与客户端时间进行比较之间可能会有几秒钟的时间滴答滴答。

当然,根据你的例子,我猜快一分钟不会杀东西吧?当然,即使在接收和比较之间只有几秒钟的延迟,你也可以很容易地偏离一分钟,除非你跟踪到秒。

由于JS不是一个真正的线程语言,任何CPU密集型的东西都可能扭曲setTimeout的准确性,并导致这种方法也慢慢失去准确性。

我过去使用的一种方法是实现一个类似ntpd的脚本,它轮询服务器,与本地时间同步,然后偶尔轮询更新,看看我们是否失去了同步。这并不难实现,只要你不介意几秒钟的变化(由于网络延迟)。

当然,使用像nodejs这样的解决方案或其他保证产生快速和快速结果的服务器,通过像AWS这样的CDN交付,可以真正将差异减少到接近完美,假设这种准确性甚至是必要的。