开发者

DateTime display is one hour off... sometimes

I've got an ASP.NET MVC 3 application that uses EF 4.1. I pull some data from a database including some DateTime info and display it in a jqGrid. Typically the displayed dates are OK but certain ones are off by an hour when displayed on my jqGrid and I believe that it might be due daylight savings time being applied.

For instance, the data retrieved includes a date like so:

PromoStartDate = {10/31/1987 11:14:13 AM}

but what gets displayed on the page (jqGrid newformat= 'G:i m/d/Y') is:

12:14 10/31/1987

which is off by one hour. Looking in Firebug, I see that the PromoStartDate in the response is::

"PromoStartDate":"\/Date(562695253060)\/"

Running this through jsFiddle (http://jsfiddle.net/u9yMM/2/) I get:

Sat Oct 31 1987 12:15:13 GMT-0400 (Eastern Daylight Time)

Playing around with my machine's timezone adjusts times in the browser (e.g., setting to Atlantic Time adjusts everything +1 hour) but the above date is still wrong (meaning it is still 1 hou开发者_开发问答r off).

The JsonResult has what I expect in it (namely that the time value is 11:14:13 for that entry) so I'm a bit confused at the moment about this.

Ideas?


Here is what I found in my testing MVC3 (not really an answer). If the DateTime to be serialized is pre 2007 when the DST was changed in the US, any date serialization that is occuring on the server will be 1 hour off when dealing with DateTimes that falls in the hole where DST was changed. (http://en.wikipedia.org/wiki/DST_in_the_US). Basically it appears to be using the most recent DST rules for all dates.

Example.

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)

The last two items have failed to serialize the data correctly.

In this test case the server and the client are hosted on the same machine, and all patches have been applied.

Code fragment from the server

    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;
    }

Code from Client

<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>


I did some playing around with this..

  var date = new DateTime(1987, 10, 31, 11, 14, 13, DateTimeKind.Utc);            
  return Json(new {Date = date}, JsonRequestBehavior.AllowGet);

This returns {"Date":"\/Date(562677253000)\/"} which seems to be correct. In JavaScript, new Date(562677253000).toUTCString() evaluates to "Sat, 31 Oct 1987 11:14:13 GMT".

So it seems to me that there is something wrong with the way your dates are stored or read from the database.

new Date(..) calculates dates based on 1/1/1970 00:00:00 UTC and I would imagine that the built in JSON serializer in ASP.NET does the same when serializing them.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜