Вот что я нашел в своем тестировании MVC3 (на самом деле не ответ). Если сериализуемым DateTime является до 2007 года, когда DST был изменен в США, любая сериализация дат, происходящая на сервере, будет отключена на 1 час при работе с DateTimes, попадающим в дыру, в которой был изменен DST. (http://en.wikipedia.org/wiki/DST_in_the_US). Похоже, что для всех дат используются самые последние правила летнего времени.
Пример.
Server Time: Friday, March 12, 2004 10:15:00 AM
JSON Serialization: /Date(1079115300000)/
JS Time Formated: 10:15
Saturday, March 13, 2004 10:15:00 AM
JSON Serialization: /Date(1079201700000)/
JS Time Formated: 10:15
Sunday, March 14, 2004 10:15:00 AM
JSON Serialization: /Date(1079288100000)/
JS Time Formated: 11:15 (failed used the post 2007 DST rules)
Server Time: Monday, March 15, 2004 10:15:00 AM
JSON Serialization: /Date(1079374500000)/
JS Time Formated: 11:15 (failed used the post 2007 DST rules)
Последние два элемента не смогли правильно сериализовать данные.
В этом тестовом примере сервер и клиент размещены на одном компьютере, и все исправления были применены.
Фрагмент кода с сервера
public ActionResult GetDates()
{
return Json( GetTimeList(),
"text/x-json",
System.Text.Encoding.UTF8, JsonRequestBehavior.AllowGet);
}
private List<TestModel> GetTimeList()
{
List<TestModel> model = new List<TestModel>();
DateTime temp = new DateTime(2003, 1, 1, 10, 15, 0);
int HourInc = 24;
for (int i = 0; i < 2200; i ++)
{
model.Add(new TestModel { ServerDate = temp.ToLongDateString() + " " + temp.ToLongTimeString(), ServerTime = temp, ServerTimeString = temp.ToString("HH:mm") });
temp = temp.AddHours(HourInc);
}
return model;
}
Код от клиента
<script type="text/javascript">
$(function () {
$.getJSON('/test/GetDates', function (data) {
var newhtml = '';
var s = '<td>';
var e = '</td>';
newhtml = "<tr><th>ServerDate</th><th>ServerTime</th><th>JsonDate</th><th>JsaonFormatedTime</th></tr>";
$.each(data, function () {
var formatedTime = formatDateTime(parseJSON(this.ServerTime))
var st = formatedTime == this.ServerTimeString ? "pass" : "fail";
newhtml += '<tr class="' + st + '">';
newhtml += s + this.ServerDate + e;
newhtml += s + this.ServerTimeString + e;
newhtml += s + this.ServerTime + e;
newhtml += s + formatedTime + e;
newhtml + '</tr>';
})
$('#test').html(newhtml)
});
});
var reDateNet = /\/Date\((\-?\d+)\)\//i;
function parseJSON (value) {
if (value == '/Date(-62135568000000)/') return null; // .net min date
else if (reDateNet.test(value)) {
return new Date(parseInt(reDateNet.exec(value)[1], 10));
}
return value;
}
function formatDateTime(dt) {
var s = '', d = dt.getHours();
s += (d < 10 ? '0' + d : d) + ':';
d = dt.getMinutes();
s += (d < 10 ? '0' + d : d);
return s;
}
</script>