我在服务器上有一个ASP.NET应用程序和一个UTC时间戳。我想在正确的时区为用户显示时间戳,并使用本地日期/时间格式。
E.g。 Jan 2, 2012 14:00:00 UTC
应向美国纽约(UTC -0500)的用户显示1/2/2012 9:00 AM
,并向英国伦敦的用户显示为02/01/2012 14:00
。
这个看似简单的任务被证明是非常困难的。 MSDN has an article具有相同的标题,但它涉及解析用户输入而不是显示服务器端数据,因此它不能完全应用。
通过JavaScript
可以在客户端轻松确定时区偏移量 offset = new Date().getTimezoneOffset();
,
但JavaScript对日期/时间格式提供的支持非常差。你得到的只是toLocaleString()
方法,这会产生丑陋的长字符串,例如Monday, January 02, 2012 9:00:00 AM
。没有提供更短的格式,因此在客户端我们遇到了良好的时区信息和糟糕的日期/时间格式功能。
服务器上的情况正好相反。我们可以利用Accept-Language HTTP标头来获取用户区域设置(not the best choice, but may be good enough),然后使用已知区域设置的.NET数据库,因此我们的代码沿着
行。 CultureInfo userCulture = new CultureInfo(Request.UserLanguages[0]);
加上一些错误处理。
但后来我们陷入了时区问题。是的,可以通过JavaScript获取它,然后作为cookie或回发数据传回,但是如果我们需要在应用程序的第一页上显示日期呢?有人可能会争辩说,第一页始终是登录页面,但在会话之间持久保存用户登录信息时却不是这样(“记住我”选项)。解决方案可能是将时区偏移量保存为用户配置文件的一部分,但随后可能很容易变得陈旧(在会话之间开启和关闭夏令时)。
这个问题的综合解决方案是否表现良好且不需要编写大量代码?我很好奇,请指教。
答案 0 :(得分:5)
您应该以标准格式将时间字符串传递给客户端,例如ISO8601:
var timeString = '2012-01-02T16:00:00Z';
某些浏览器会正确解析ISO8601字符串,有些浏览器会解析它,因此请手动解析它。这很简单 - 创建一个本地日期对象,然后设置UTC日期和时间:
function localDateFromUTC(s) {
var x = s.split(/[-\s:tz]/i);
var d = new Date();
d.setUTCFullYear(x[0], x[1], x[2]);
d.setUTCHours(x[3], x[4], x[5]);
return d;
}
var s = '2012-01-02T16:00:00Z';
var d = localDateFromUTC(s);
alert(d); // Shows local date and time for the provided UTC date and time
如果您需要特定输出,则需要手动格式化,例如
function formatDate(d) {
var days = ['Sunday','Monday','Tuesday','Wednesday',
'Thursday','Friday','Saturday'];
var months = ['January','February','March','April','May','June','July',
'August','September','October','November','December'];
return days[d.getDay()] + ', ' + d.getDate() + ' ' +
months[d.getMonth()] + ', ' + d.getFullYear();
}
您可以尝试使用 toLocaleString(),但不同浏览器的结果差别很大,大多数似乎都会忽略本地设置。