zoukankan      html  css  js  c++  java
  • 【经验分享】为什么后台取到的时间和前台差8个小时?

    发现问题

    单元格编辑时,你可能会遇到前台传入的时间,后台通过C#获取时差8个小时,这是怎么回事呢?

    这个问题可能会困扰一些同学,我也不止一次的收到这样的问题,这个是昨天一个网友的提问:

    之前还有网友在发表类似的问题:

    为了演示这一过程,我通过一个简单的例子来说明问题,首先新建一个页面:

    @(F.DatePicker().DateFormatString("yyyy-MM-dd HH:mm:ss").Label("开始日期").ID("DatePicker1").ShowTime(true).SelectedDate(DateTime.Now))
    @(F.Button().ID("btnSubmit").Text("提交表单").OnClick(Url.Action("btnSubmit_Click"), "DatePicker1"))
    
    @(F.Label().ID("labResult"))

    后台代码:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult btnSubmit_Click(FormCollection values)
    {
        UIHelper.Label("labResult").Text("开始日期:" + values["DatePicker1"]);
    
        return UIHelper.Result();
    }

    因为后台直接从请求表单中读取的字符串,所以没有问题,前台参数传入:

    DatePicker1: 2019-03-21 14:48:55

    页面上显示:

    开始日期:2019-03-21 14:48:55


    现在前台新增一个按钮,并通过自定义回发的形式传入后台:

    @(F.Button().ID("btnSubmit2").Text("自定义回发").OnClientClick("btnSubmit2Click();"))
    
    function btnSubmit2Click() {
        F.doPostBack('@Url.Action("btnSubmit2_Click")', {
            values: F.toJSON({
            DatePicker1: F.ui.DatePicker1.getValue()
            })
        });
    }

    后台直接从JSON对象中读取数据,并显示:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult btnSubmit2_Click(JObject values)
    {
        UIHelper.Label("labResult").Text("开始日期:" + values["DatePicker1"].ToString());
    
        return UIHelper.Result();
    }

    此时再看回发后的前台显示:

    开始日期:2019/3/21 6:45:44

    好嘛!刚好差8个小时,逮个正着!

    分析问题

    可能有人会说了,是不是前台传入的数据有误?其实不是的,打开浏览器调试工具,看下传入的参数:

    values: {"DatePicker1":"2019-03-21T06:48:55.000Z"}

    可以发现,前台 F.toJSON 之后,原来的字符串 2019-03-21 14:48:55 被转化为标准时间:2019-03-21T06:48:55.000Z

    这个转化是没问题的,因为它(2019-03-21T06:48:55.000Z)描述的是标准零时区的时间,和我们的本地时间(北京时间,东八区)刚好差了8个小时。

    问题出在后台JSON格式转化,JSON.NET会识别含有类似 2019-03-21T06:48:55.000Z 的字符串,并将之转化为时间格式!!

    在VS中调试,可以看到 values["DatePicker1"] 其实是 Date 类型,并非我们所期望的 string 类型:

    解决问题

    其实这个时间对象也没问题,只不过它表示的是标准零时区时间,我们只需将其转化为本地时间就可以了,所以正确的代码应该是这样的:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult btnSubmit2_Click(JObject values)
    {
        UIHelper.Label("labResult").Text("开始日期:" + values.Value<DateTime>("DatePicker1").ToLocalTime().ToString());
    
        return UIHelper.Result();
    }

    现在前台显示:

    开始日期:2019/3/21 14:48:55


    还可以将字符串格式化为需要的格式:

    UIHelper.Label("labResult").Text("开始日期:" + values.Value<DateTime>("DatePicker1").ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss"));


    此时前台显示:

    开始日期:2019-03-21 14:48:55

    深入问题

    还有观众说了,JSON.NET的这个自动转化我不需要,能不能直接拿到这个字符串,然后我自己通过 DateTime.Parse 来转换呢?

    我在网上搜索了一下,发现如下两个解决办法,供参考:

    办法一:

    JsonReader reader = new JsonTextReader(new StringReader(values.ToString()));
    reader.DateParseHandling = DateParseHandling.None;
    JObject o = JObject.Load(reader);
    // 2019/3/21 14:48:55
    var result1 = DateTime.Parse(o.Value<string>("DatePicker1")).ToString();

    办法二:

    JsonSerializerSettings settings = new JsonSerializerSettings()
    {
        DateParseHandling = DateParseHandling.None
    };
    JObject j2 = JsonConvert.DeserializeObject<JObject>(values.ToString(), settings);

    说白了就是告诉 JSON.NET,不要自作主张的帮我把字符串转换为日期对象(DateParseHandling.None),我要取得原始的字符串。

    并且由于上面需要把 values 先转换为字符串,既然如此,还不如直接使用 string 来接受参数(少了一次参数自动类型转换和一次强制类型转换):

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult btnSubmit2_Click(string values)
    {
        JsonSerializerSettings settings = new JsonSerializerSettings()
        {
            DateParseHandling = DateParseHandling.None
        };
        JObject j2 = JsonConvert.DeserializeObject<JObject>(values, settings);
    
        return UIHelper.Result();
    }

    只不过这个路子绕的有点远。

  • 相关阅读:
    HDU1029 Ignatius and the Princess IV
    UVA11039 Building designing【排序】
    UVA11039 Building designing【排序】
    POJ3278 HDU2717 Catch That Cow
    POJ3278 HDU2717 Catch That Cow
    POJ1338 Ugly Numbers(解法二)
    POJ1338 Ugly Numbers(解法二)
    UVA532 Dungeon Master
    UVA532 Dungeon Master
    POJ1915 Knight Moves
  • 原文地址:https://www.cnblogs.com/sanshi/p/10572060.html
Copyright © 2011-2022 走看看