我有一个经过身份验证的用户,具有给定的时区,例如"柏林,GMT+1"。为了这个问题,假设我在全球范围内有这个:
var timeZone = "Berlin";
var gmtDistance = 1;
让所有与日期相关的 JS 相应地运行的最佳解决方案是什么,这意味着如果我创建一个新的 Date 对象,它将考虑时区。
我认为这很简单,但我似乎没有找到在 Google/SO 上做到这一点的完美方法。我会优先考虑不需要任何外部库的答案。
我的偏好是使用 UTC 时间将所有日期存储在服务器端,当我处理通过 AJAX 调用返回的数据时,创建一个执行一些解析的全局处理程序。
以下示例允许您简单地使用:
app.ajax({
url: '/My/Post/Url',
data: {
MyProperty: 'MyValue'
},
success: function (data, status, xhr) {
// Do stuff here...
},
error: function (xhr, settings, error) {
// Do stuff here...
}
});
但是,它通过将 UTC 时间的日期固定为本地时区来预解析"成功"函数的"data"元素中的任何返回值。请注意 - 执行此操作后,如果您进一步处理数据,则需要在发送回服务器之前对其进行 UN-修复,否则您将将其与偏移量一起发布。
var app = window.app = $.extend(true, {}, app, {
// Creating a namespace for my app which is safe across multiple files.
ajax: function (options) {
var defaultSettings = {
type: 'POST',
async: true
};
// Capture the settings.
var settings = $.extend(true, {}, defaultSettings, options);
// Install our general handlers;
if (settings.success) {
settings.success = function (data, textStatus, jqXHR) {
app.OnPostSuccess(data, textStatus, jqXHR, options.success);
}
} else
settings.success = app.OnPostSuccess;
if (settings.error) {
settings.error = function (jqXHR, ajaxSettings, thrownError) {
app.OnPostError(event, jqXHR, ajaxSettings, thrownError, options.error);
}
} else
settings.error = app.OnPostError;
$.ajax(settings);
},
OnPostSuccess: function (data, textStatus, jqXHR, fn_after) {
// Do my generalized success handling here.
// Fix Dates.
var fixedData = app.FixDate(data);
// Call any other handler that's been specified.
if (typeof fn_after === 'function')
fn_after(fixedData, textStatus, jqXHR);
},
OnPostError: function (jqXHR, ajaxSettings, thrownError, fn_after) {
// Do my generalized error handling here.
// Call any other handler that's been specified.
if (typeof fn_after === 'function')
fn_after(jqXHR, ajaxSettings, thrownError);
},
FixDate: function (obj) {
var fixed = obj;
if (typeof obj == 'string' && obj.indexOf('/Date(') == 0) {
// Microsoft date "/Date(12345678)/" - convert to real date.
fixed = new Date(parseInt(fixed.substr(6, fixed.length - 8), 10));
}
if (typeof fixed === 'object') {
if (fixed.getTimezoneOffset) {
// If the value is a date, apply timezone correction.
var now = new Date();
var offset = now.getTimezoneOffset(); // # of minutes from GMT.
fixed = new Date(fixed.getTime() + offset * 60000);
// This updates the value based on the offset.
} else {
// Otherwise, update each of its properties.
// This fixes objects with dates for properties, recursively.
$.each(fixed, function (index, value) {
fixed[index] = app.FixDate(value);
});
}
}
return fixed;
}
});
所有这些设置都是为了达到这个目的。如果您现在在 OnPostSuccess 中处理日期之类的事情,您可以确保它们始终采用正确的格式 - 并且始终位于正确的时区。
无论是否使用上述 AJAX 方法,都可以按如下方式使用 FixDate 方法:
var MyObj = {
MyDate: "/Date(12345678)/"
};
console.log('Before: ', MyObj.MyDate);
MyObj = app.FixDate(MyObj);
console.log('After: ', MyObj.MyDate);
要查看实际示例,请查看以下 jsFiddle:
http://jsfiddle.net/TroyAlford/TBNVV/
注意:这也包括 AJAX 位 - 但它们未在示例中使用 - 只是为了完整性。
这样的事情呢?
http://www.onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/
var rightNow = new Date();
var jan1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0);
var temp = jan1.toGMTString();
var jan2 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1));
var std_time_offset = (jan1 - jan2) / (1000 * 60 * 60);
也许 Dojo 工具包可以给你一些想法 [ 因为事实上,你不想要外部库;) ]
Dojo 工具包附带了一个很好的日期/时间处理类,并提供完整的本地化支持,即使有时区支持。http://dojotoolkit.org/api/1.6/dojo/date