例如. 2012年1月2日14:00:00 UTC应显示为1/2/2012 9:00 AM给用户在纽约,美国(UTC -0500)和02/01/2012 14:00给用户英国伦敦.
这个看似简单的任务被证明是非常困难的. MSDN has an article具有相同的标题,但它谈论解析用户输入而不是显示服务器端数据,因此它不完全适用.
通过JavaScript可以在客户端轻松确定时区偏移量
offset = new Date().getTimezoneOffset();,
但JavaScript对日期/时间格式提供的支持非常差.所有你得到的是toLocaleString()方法,这导致丑陋的长字符串,如2012年1月2日星期一上午9:00:00.没有提供更短的格式,因此在客户端我们遇到了良好的时区信息和糟糕的日期/时间格式功能.
服务器上的情况正好相反.我们可以利用Accept-Language HTTP标头来获取用户区域设置(not the best choice,but may be good enough),然后使用已知区域设置的.NET数据库,因此我们的代码沿着
CultureInfo userCulture = new CultureInfo(Request.UserLanguages [0]);
加上一些错误处理.
但后来我们陷入了时区问题.是的,可以通过JavaScript获取它,然后作为cookie或回发数据传回,但是如果我们需要在应用程序的第一页上显示日期呢?有人可能会争辩说,第一页始终是登录页面,但是当会话之间持有用户登录信息时,情况并非如此(“记住我”选项).解决方案可能是将时区偏移量保存为用户配置文件的一部分,但随后可能很容易变得陈旧(在会话之间开启和关闭夏令时).
解决方法
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(),但不同浏览器的结果差别很大,大多数似乎都忽略了本地设置.