我将 UTC 日期时间存储在服务器上,并通过 JSON 请求数据以在客户端上显示。 问题是服务器按与客户端不同的时区返回时间。 如何在不硬编码偏移量的情况下让本地日期时间显示在客户端上?
我正在使用 ASP.NET MVC 并将日期和时间存储在 SQL Server 2008 数据库中作为“日期时间”。数据库中的日期时间格式为 2013-03-29 08:00:00.000。
你没有说UTC时间是如何表示的。通常使用自 1970-01-01T00:00:00Z 以来的秒数 UNIX 时间值。如果这就是您使用的,您可以通过乘以 1,000 并将其传递给 Date 构造函数来在客户端创建一个日期对象:
var unixTimeValue = '1364694508';
var clientDateObject = new Date(unixTimeValue * 1000);
如果您使用的是 .NET,该值可能已经以毫秒为单位,因此您无需乘以 1,000。您需要检查源代码以查看传递的值以及使用的纪元(如果它是时间值)。
Javascript 日期对象基于与 UNIX 相同纪元的时间值,但使用毫秒。标准日期方法(getFullYear、getMonth、getDate 等)将根据系统设置返回本地时区的值。 UTC 方法(getUTCFullYear、getUTCMonth、getUTCDate 等)同时返回 UTC 值。
因此,如果您要传递时间值,请使用它在客户端上创建日期对象并使用标准方法读取值,这样您就拥有了 UTC 时间值的本地等效值。
如果您传递像 2013-03-31T14:32:22Z 这样的日期时间字符串,您可以使用 Date.UTC 将其转换为日期对象,以将字符串转换为时间值,然后将其传递给日期构造函数:
function dateFromUTCString(s) {
s = s.split(/[-T:Z]/ig);
return new Date(Date.UTC(s[0], --s[1], s[2], s[3], s[4], s[5]));
}
var s = '2013-03-31T14:32:22Z';
alert(dateFromUTCString(s)); // Mon Apr 01 2013 00:32:22 GMT+1000 (EST)
如果您的输入字符串是不同的格式,您可能需要调整传递给 Date.UTC 的参数的分割模式和顺序。
如果字符串格式为2013-03-29 08:00:00.000(假设UTC),则可以使用:
function dateFromUTCString(s) {
s = s.split(/[\D]/ig);
return new Date(Date.UTC(s[0], --s[1], s[2], s[3], s[4], s[5], s[6]||0));
}
var s = '2013-03-29 08:00:00.000';
alert(dateFromUTCString(s)); // Fri Mar 29 2013 18:00:00 GMT+1000 (EST)
但要小心额外的空格。您可能需要修剪任何前导或尾随空格,并确保只有一个分隔日期和时间部分。
不要使用Date.parse。在 ES5 之前,它完全依赖于实现。现在它已部分标准化 if 字符串符合 ES5 指定的 ISO8601 格式。但并非所有正在使用的浏览器都支持这一点,因此不可靠,并且仍然依赖于实现。最好的解决方案(即在任何地方都适用的解决方案)是手动解析给定的值。
如果格式如下:“1364835180000-0700”,那么您可以使用减去偏移量以获得 UTC 时间值的函数相当轻松地处理该问题,并将其提供给日期构造函数。我假设 -0700 意味着格林威治以西 7 小时(javascript 时区偏移具有相反的含义,格林威治以西是 +ve)。
抱歉,一定是发错了,急着去开会。
// Where s is a time value with offset
function toDate(s) {
// Include factor to convert mins to ms in sign
var sign = s.indexOf('-') > -1? 6e4 : -6e4;
s = s.split(/[\+\-]/);
var l = s[1].length;
// Convert offset in milliseconds
var offset = sign*s[1].substring(l-2,l) + sign*s[1].substring(l-4, l-2)*60;
// Add offset to time value to get UTC and create date object
return new Date(+s[0] + offset);
}
var s = "1364835180000-0700"
alert(toDate(s)); // Tue Apr 02 2013 09:53:00 GMT+1000 (EST)
以 UTC 形式返回 DateTime 并使用 .toLocaleString() 在客户端上进行转换:
@ViewBag.Time = Model.Time.ToUniversalTime().Ticks / TimeSpan.TicksPerMillisecond
<script>
var time = new Date(@ViewBag.Time);
var localTimeString = time.toLocaleString();
alert(localTimeString);
</script>