全局调整日期时间

时间:2011-02-04 15:26:40

标签: javascript datetime

我有一个处理多个时区的ExtJS应用程序。服务器上的时间以UTC格式存储。

所有日期在发送到服务器时都被序列化为ISO8601,因此UTC日期是正确的。

一切正常,但用户的系统时间不正确。理想情况下,我想使用服务器时间来纠正这个问题。

我不想做的是入侵所有创建新Date实例的代码,以调整每个新对象的时间。这意味着很多重复。

我有没有想过要调整所有Date实例的时间,只有一次?

2 个答案:

答案 0 :(得分:3)

当然可以。只需用您自己的对象替换默认的Date对象即可。这是一个粗略的实现:

(function() {

function adjust(d) {
     // Here's where you can make whatever adjustments you want.
     // This will be called each time a new Date object is first created.
     // This example will add an hour to every Date object.
    d.setHours(d.getHours()+1);
    return d;
}

var _Date = Date; // Hide the native Date object in our closure...

Date = function(y, M, d, h, m, s, f) { // ...and replace the global version with our own.
    var newDate;
    // Valid Date constructors:
    // Date() - current system time
    // Date(milliseconds) - milliseconds since the UNIX epoch (1 Jan 1970 00:00:00 UTC)
    // Date(dateString)
    // Date(year, month, day, hours, minutes, seconds, milliseconds)
    switch (typeof y) {
        case 'string':
            newDate = new _Date(y);
            break;
        case 'number':
            // Unfortunately, we can't just `.apply(this, arguments)` since we're using the `new` operator.
            if (typeof M == 'number')
            if (typeof d == 'number')
            if (typeof h == 'number')
            if (typeof m == 'number')
            if (typeof s == 'number')
            if (typeof f == 'number') newDate = new _Date(y, M, d, h, m, s, f);
            else newDate = new _Date(y, M, d, h, m, s);
            else newDate = new _Date(y, M, d, h, m);
            else newDate = new _Date(y, M, d, h);
            else newDate = new _Date(y, M, d);
            else newDate = new _Date(y, M);
            else newDate = new _Date(y);
            break;
        default:
            newDate = new _Date();
    }
    return adjust(newDate);
};
Date.UTC = function(y, M, d, h, m, s, f) { throw new Error('Not implemented.'); };
Date.now = function() { return new Date(); };
Date.parse = function(d) { return  _Date.parse(d) };
})();

测试:

console.log(new Date().toString());
console.log(new Date(1234).toString());
console.log(new Date('2011-02-04 11:00:00').toString()); // IE's date string parser won't recognize this format, but Chrome's does.  Use DateJS if necessary.
console.log(new Date(2011, 1, 4, 11, 0, 0, 0).toString());

...输出:

Fri Feb 04 2011 13:04:29 GMT-0500 (Eastern Standard Time)
Wed Dec 31 1969 20:00:01 GMT-0500 (Eastern Standard Time)
Fri Feb 04 2011 12:00:00 GMT-0500 (Eastern Standard Time)
Fri Feb 04 2011 12:00:00 GMT-0500 (Eastern Standard Time)

需要考虑的事项:

  • 特别是因为你正在使用大型第三方库,谁知道Date如何工作的相互依赖性,你可能会看到一些奇怪的东西。祝你好运。
  • 此代码的放置非常重要。它需要包含 修改Date对象prototype之后的任何代码(例如DateJS),但之前任何内容尝试实例化Date。在执行此操作后修改Date.prototype的任何内容均无效。
  • 我在Chrome和IE中进行了最低限度的测试。似乎工作。
  • Chrome的开发人员工具通常会将Date显示为他们所代表的日期(即在控制台和监视表达式中),但如果处于活动状态,则只能看到“日期”。

答案 1 :(得分:0)

你不能用javascript做到这一点。要调整客户端计算机的日期/时间,您需要在kernel32.dll中对setLocalTime或setSystemTime进行p / invoke调用。为此,您需要在浏览器的沙箱外部进行访问。 您可以通过测试某些阈值差异的差异来解决这个问题,如果不是太大则忽略它,否则请使用服务器时间。