【问题标题】:Kendo Grid Automatically changing TimezoneKendo Grid 自动更改时区
【发布时间】:2013-09-23 08:51:57
【问题描述】:

在我的 Kendo Grid 上,我从服务器接收日期时间。在客户端,此时间更改为客户端的时区并显示。如何从服务器到客户端显示相同的时间。

以下是我绑定日期时间的剑道代码。

columns.Bound(p => p.CreateDate).Format("{0:dd/MM/yyyy hh:mm:ss}").Sortable(true).Width(180);

【问题讨论】:

    标签: asp.net-mvc datetime kendo-grid kendo-asp.net-mvc


    【解决方案1】:

    由于日期是在服务器返回响应时在客户端创建的 - 日期总是根据浏览器的时区创建并带有偏移量

    这将对您有所帮助:

    http://www.kendoui.com/code-library/mvc/grid/using-utc-time-on-both-client-and-server-sides.aspx

    【讨论】:

    • 这在这种情况下很好,但不是适用于所有情况的正确解决方案,假设我有一个假设的出生日期字段 1/1/1970 或 12/31/1970 当您将其更改为 UTC存储它将更改日期,并且在 UTC 中再次检索也将不起作用。想知道剑道是否对此没有修复/解决方法。
    【解决方案2】:

    例如,您的客户端计算机在悉尼,而您的代码部署在印度。

    将日期时间保存到数据库:

    在将日期时间从客户端 (JavaScript) 传递到服务器 (.NET) 时,将其作为字符串传递,以便在保存到数据库时不会转换为服务器时间 (UK)。

    如果您的日期时间字段不可编辑,请遵循解决方案 1,否则解决方案 2 将是正确的选择。

    从数据库中检索

    解决方案 1:

    客户端代码

    cols.Bound(c => c.ExamDate)
        .ClientTemplate(("#= ExamDateString #"))
        .Hidden(false)
        .Filterable(x => x
            .Cell(cell => cell
                .ShowOperators(false)
                .Operator(StringOperator.eq.ToString())
            )
        );
    

    服务器端代码:

    格式的服务器模型属性:

    public string ExamDateString 
    { 
        get 
        { 
            return ExamDate.HasValue 
                ? ExamDate.Value.ToString("dd/MM/yyyy hh:mm:ss") 
                : string.Empty; 
        } 
    }
    

    解决方案 2:

    从数据库中检索:

    客户端代码:

    $.ajax({ 
        type: "POST", 
        url: '@Url.Action("Controller action method name", "Controller name")', 
        data: { 
            "clientMachineTimeZoneOffsetInMinutes ": (new Date()).getTimezoneOffset() 
        }, 
        success: function (data) { 
    
        } 
     });
    

    服务器端代码:

    //Server Timezone(India) Offset minutes : 330 
    
    //Client Timezone(Sydney) Offset minutes :  -600 
    
    //Difference between Client and Server timezone offset minutes =  -270 
    
    var serverTimeZoneOffsetInMinutes = DateTimeOffset.Now.Offset.TotalMinutes;
    var serverAndClientMachineTimeZoneDifferenceInMinutes = clientMachineTimeZoneOffsetInMinutes + serverTimeZoneOffsetInMinutes; 
    
    //Update your date time field with this offset minutes
    ExamDate = ExamDate.Value.AddMinutes(serverAndClientMachineTimeZoneDifferenceInMinutes);
    

    解决方案 3:
    解决方案 2 不会处理夏令时场景,这将是处理所有场景的理想解决方案。

    在将控制器动作方法的DataSource结果返回给剑道网格之前,请执行以下操作以停止转换:

    var response = new ContentResult
    {
        Content = JsonConvert.SerializeObject(value, new JsonSerializerSettings
        {
            DateTimeZoneHandling = DateTimeZoneHandling.Local,
            DateFormatString = "yyyy-MM-ddTHH:mm:ss"
        }),
        ContentType = "application/json"
    };
    
    return response;
    

    【讨论】:

      【解决方案3】:

      这是我的解决方案。

      在控制器中我这样做了:

      DateTime time = DateTime.Now();
      
      string x = time.ToString("MM/dd/yyyy hh:mm:ss tt");
      

      在视图中:

      columns.Bound(p => p.x);
      

      它也是可排序的。

      【讨论】:

      • 请记住,在这种情况下,使用日期选择器控件进行过滤将不起作用。
      • 你的意思是columns.Bound(p => p.x);
      • 使用这种方法也不能编辑该字段
      【解决方案4】:

      另一种选择是使用自定义JsonResult 并将日期转换为ISO 格式。

      public class IsoDateJsonResult : JsonResult
      {
          public override void ExecuteResult(ControllerContext context)
          {
              if (context == null)
              {
                  throw new ArgumentNullException("context");
              }
      
              HttpResponseBase response = context.HttpContext.Response;
      
              if (!String.IsNullOrEmpty(ContentType))
              {
                  response.ContentType = ContentType;
              }
              else
              {
                  response.ContentType = "application/json";
              }
              if (ContentEncoding != null)
              {
                  response.ContentEncoding = ContentEncoding;
              }
              if (Data != null)
              {
                  var isoConvert = new IsoDateTimeConverter();
                  response.Write(JsonConvert.SerializeObject(Data, isoConvert));
              }
          }
      

      然后将您的Controller 方法更改为返回IsoDateJsonResult 而不是ActionResult/JsonResult

      【讨论】:

        【解决方案5】:

        解决方案 2 在我的上述答案中,如果您不在夏令时但您尝试访问处于夏令时的日期,则会添加夏令时,重写解决方案 2 以支持夏令时

        更新时区名称的客户端代码:

            $.ajax({
                    type: "POST",
                    url: '@Url.Action("Controller action method name", "Controller name")',
                    data: { "timeZoneName": Intl.DateTimeFormat().resolvedOptions().timeZone },
                    success: function (data) {
                            }
                    });
        

        在会话中更新时区的控制器方法名称:

           public ActionResult actionMethod(string timeZoneName)
            {
                Session["timeZoneName"] = Convert.ToString(timeZoneName);
                return Json(new { success = true });
            }
        

        App config 应用设置条目:

        <add key ="Europe/London"  value ="GMT Standard Time" />
        

        这里的关键是浏览器返回的客户端时区名称,并在此处的会话中维护,我们必须为所有时区添加条目

        将以下代码放在控制器操作方法中以获取考试日期:

        var clientMachineTimeZoneName = Convert.ToString(Session["timeZoneName"]);
        
        Get the sever timezone id from config for the corresponding time zone which we got from client side
        var timeZoneId = ConfigurationManager.AppSettings[clientMachineTimeZoneName];
        
        TimeZoneInfo clientTimezoneDetails = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
        
        var clientTimeZoneOffsetMinutes = clientTimezoneDetails.GetUtcOffset(x.ExamDate.Value).TotalMinutes * -1;
        var serverAndClientMachineTimeZoneDifferenceInMinutes = clientTimeZoneOffsetMinutes + TimeZoneInfo.Local.GetUtcOffset(x.ExamDate.Value).TotalMinutes;
        
        //Update your date time field with this offset minutes
        ExamDate = ExamDate.Value.AddMinutes(serverAndClientMachineTimeZoneDifferenceInMinutes);
        

        【讨论】:

          【解决方案6】:

          在我的情况下,服务器在 CST,而我在 MST。我需要将我的 SQL Server 数据保存到浏览器中,并且在我的 Kendo Grid 上将 02/08/18 23:57 变为 02/08/18 22:57。所以我做了这个,希望它有帮助:

          检查用户/浏览器的时区偏移

          获取与服务器时区偏移量的小时差

          查看 Kendo Grid 上具有 .dbDate 类的列

          从数据对象中获取该单元格中的日期(displayedTime)

          使用 Moment.js 根据我们传递的小时数差异 (diff) 来转换 (convertedTime)。

          将时间转换为所需格式,即 02/08/18 23:57

          将 1 加到 i 以便调整对象中的下一个日期

          将更新的日期和时间传回网格。

          必须在页面/网格加载/更新时最后运行。

          function getDateOffset() {
              var date = new Date();
              var offset;
              var diff;
              offset = date.getTimezoneOffset()
              if (offset > 360) { //360 = CST
                  diff = +(offset - 360) / 60
              } else if (offset < 360) {
                  diff = -(360 - offset) / 60
              } else {
                  diff = 0
              }
          
              $(".dbDate").each(function (i) {
          
                  var grid = $('#Grid').data('kendoGrid');
                  var displayedTime = grid.dataSource.data()[i].TicketDateTime
                  var convertedTime = new moment(displayedTime).add(diff, 'hours').toDate();
                  var originalTime = moment(convertedTime).format("MM/DD/YY HH:mm");
          
                  i + 1
                  $(this).html(originalTime)
              })
          }
          

          【讨论】:

            猜你喜欢
            • 2017-10-26
            • 2015-07-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-02-26
            • 1970-01-01
            • 2013-08-22
            • 1970-01-01
            相关资源
            最近更新 更多