5

我将 Utc 日期时间存储在服务器上并通过 json 请求数据以显示在客户端上。问题是服务器按与客户端不同的时区返回时间。如何在不硬编码偏移量的情况下让本地 dateTime 显示在客户端上?

我正在使用 asp.net mvc 并将 SQL Server 2008 数据库中的日期和时间存储为“日期时间”。数据库中的日期时间格式为 2013-03-29 08:00:00.000。

4

2 回答 2

6

你没有说UTC时间是如何表示的。通常使用 UNIX 时间值,即自 1970-01-01T00:00:00Z 以来的秒数。如果这是您正在使用的,您可以在客户端上创建一个日期对象,方法是乘以 1,000 并将其提供给 Date 构造函数:

var unixTimeValue = '1364694508';
var clientDateObject = new Date(unixTimeValue * 1000);

如果您使用的是 .NET,则该值可能已经以毫秒为单位,因此您无需乘以 1,000。您需要检查源以查看传递的值以及使用的纪元(如果它是时间值)。

Javascript 日期对象基于与 UNIX 相同的时间值,但使用毫秒。标准的 Date 方法(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)

但要小心额外的空间。您可能想要修剪任何前导或尾随空格,并确保只有一个分隔日期和时间组件。

编辑 2

不要使用 Date.parse。在 ES5 之前,它完全依赖于实现。现在,如果字符串符合 ES5 指定的类似 ISO8601 的格式,则它已部分标准化。但这并不是所有正在使用的浏览器都支持的,因此不可靠,并且仍然依赖于实现。最好的解决方案(即一种适用于任何地方的解决方案)是手动解析您给出的值。

如果格式类似于:“1364835180000-0700”,那么您可以使用减去偏移量以获得 UTC 时间值的函数相当容易地处理它,并将其提供给日期构造函数。我假设 -0700 表示格林威治以西 7 小时(javascript 时区偏移量具有相反的意义,格林威治以西为 +ve)。

编辑 3

不好意思,一定是发错截图了,赶着开会。

// 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)
于 2013-03-31T02:02:07.513 回答
2

将 DateTime 作为 UTC 返回并在客户端使用 .toLocaleString() 进行转换:

  @ViewBag.Time = Model.Time.ToUniversalTime().Ticks / TimeSpan.TicksPerMillisecond

  <script>
       var time = new Date(@ViewBag.Time);
       var localTimeString = time.toLocaleString();
       alert(localTimeString);
  </script>
于 2013-03-31T00:59:39.847 回答