【发布时间】:2014-03-27 08:34:37
【问题描述】:
我今天在我的一个项目中使用 Kendo UI 图表,发现在不同的浏览器中有一个奇怪的行为,我在 x 轴上有日期,它会在不同时区的不同浏览器中自动转换日期。
与 UTC+5 一样,它显示的日期范围从 2014 年 3 月 1 日到 2014 年 3 月 31 日,而在 UTC-6 中,它显示的日期范围从 2014 年 2 月 28 日到 2014 年 3 月 30 日。
【问题讨论】:
我今天在我的一个项目中使用 Kendo UI 图表,发现在不同的浏览器中有一个奇怪的行为,我在 x 轴上有日期,它会在不同时区的不同浏览器中自动转换日期。
与 UTC+5 一样,它显示的日期范围从 2014 年 3 月 1 日到 2014 年 3 月 31 日,而在 UTC-6 中,它显示的日期范围从 2014 年 2 月 28 日到 2014 年 3 月 30 日。
【问题讨论】:
这基本上是由于客户端和服务器的时区之间的差异以及这些日期在双方被传输并重新创建为 Date (JS) /DateTime (.NET) 对象的形式。
基本上整个情况都在here详细解释。 Chart 使用的数据源与 Grid 使用的数据源相同,因此没有区别。
这是我的一个项目中的一些示例代码,您可以使用它们。检查 requestEnd 处理程序
@(Html.Kendo().Grid<KendoMVCWrappers.Models.Person>().Name("persons")
.DataSource(dataSource => dataSource
.Ajax()
.Events(ev => ev.RequestEnd("convert"))
.Model(model => model.Id(m => m.PersonID))
.Read(read => read.Action("GetPersons", "Home"))
.Update(up => up.Action("UpdatePerson", "Home"))
)
.Filterable()
.Columns(columns =>
{
columns.Bound(c => c.PersonID);
columns.Bound(c => c.Name);
columns.Bound(c => c.BirthDate);
columns.Command(cmd => cmd.Edit());
})
.Pageable()
.Sortable()
)
<script type="text/javascript">
function convert(e) {
if (e.response.Data && e.response.Data.length) {
var offsetMiliseconds = new Date().getTimezoneOffset() * 60000;
var persons = e.response.Data;
for (var i = 0; i < persons.length; i++) {
persons[i].BirthDate = persons[i].BirthDate.replace(/\d+/,
function (n) { return parseInt(n) + offsetMiliseconds }
);
}
}
}
</script>
还有 ViewModel 的 setter 代码。使用 setter 可以缓解整个情况,因为您必须在多个地方执行此操作(在从数据库获取对象和从 ModelBinder 创建对象之前创建对象之前)。
public class Person
{
public int PersonID { get; set; }
public string Name { get; set; }
private DateTime birthDate;
public DateTime BirthDate
{
get { return this.birthDate; }
set
{
this.birthDate = new DateTime(value.Ticks, DateTimeKind.Utc);
}
}
}
祝你好运!
【讨论】:
尝试解析日期时出现空响应错误,如 onRequestEnd 中的这篇文章中所述。 http://www.telerik.com/support/code-library/using-utc-time-on-both-client-and-server-sides
我通过解析数据源解析方法而不是 requestEnd 来解决这个问题。
parse :function(data)
{
return ConvertToUTC(data);
}
function ConvertToUTC(data)
{
// iterate over all the data elements replacing the Date with a version
// that Kendo can work with.
$.each(data, function(index, item){
if(index == "data")
{
for(i =0 ;i< item.length; i++)
{
// Days is my date property in item collection
item[i].Days = item[i].Days.replace(/\d+/,
function (n) {
var time = parseInt(n);
return parseInt(time) + new Date(time).getTimezoneOffset() * 60000;
}
);
}
}
});
return data;
}
【讨论】: