【问题标题】:Format time in DataGridView to local timezone将 DataGridView 中的时间格式化为本地时区
【发布时间】:2013-03-06 01:26:39
【问题描述】:

我有一个在设置为东部时间的 SQL 服务器上运行的进程,当它完成时,我们用完成时间填充一个表。我有一个当前被多个应用程序使用的视图,它在不同的列中显示进程的日期/时间,因为其他应用程序正在使用它,我无法更改视图。

我用来返回我的流程数据的查询如下,日期/时间正在服务器端转换为 varchar - 所以它不会作为日期/时间进入 UI。

 SELECT CONVERT(VARCHAR(10), A2.TaskDateTime, 101) AS TaskDate,
        CONVERT(VARCHAR(5),  A2.TaskDateTime, 108) AS TaskTime
 FROM Task  AS T2
 JOIN Application_Task AS A2    
  ON A2.TaskID = T2.TaskID

这些数据随后通过数据网格视图显示在 UI 中。我正在尝试将 DataGridView 中的时间列格式化为我的本地时区,因为用户将位于不同的时区。

我查看了 DataGridViewCellStyle.Format 并搜索 SO 并找到 this on converting to local time 但这是解析一个字符串。我似乎无法弄清楚如何将其应用于整个数据列。

我将不胜感激任何有关从哪里开始的帮助和/或指导。

【问题讨论】:

    标签: c# winforms datagridview


    【解决方案1】:

    我在 CellFormatting 事件中处理这个:

        private void OnCellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (e.RowIndex < 0 || e.ColumnIndex < 0) return;
            DataGridView dgView = (DataGridView)(sender);
            // no need to add TaskTime...
            if (e.ColumnIndex != dgView.Columns["TaskDate"].Index) return;
            string cellValue = e.Value + " " + dgView.CurrentRow.Cells[dgView.Columns["TaskTime"].Value);
            DateTime dtValue;
            DateTime.TryParse(cellValue, out dtValue);
            DateTime dtValueUTC = TimezoneInfo.ConvertTimeToUtc(dtValue, "Eastern Time Zone");
            e.Value = dtValueUTC.Value.ToLocalTime();
        }
    

    【讨论】:

    • 我在其中提取的数据是时间的字符串版本。我正在使用的视图将时间作为 varchar 返回,因此它不知道该列是 DateTime 字段。
    • 能否按原样返回日期时间字段(即日期时间)。之后,在您拥有 gridview 的客户端,您可以使用 Format 属性设置为“mm/dd/yyyy”到“hh:mm:ss t”。这确实可以帮助您处理边界之间发生的日期时间值 - 例如,太平洋时间 8 月 26 日下午 5:00 实际上是 8 月 27 日通用。
    • 我不能像我在原始问题中所说的那样,我正在使用一个已开始被多个应用程序使用的视图,因此我无法更改它。
    • 我已经更改了 sn-p 以满足您的需要。你可以改进它。您可能希望 (1) 在末尾添加一行代码以使用更改的值更新时间单元格 (2) 将格式添加到 DataGridView "TaskDate" ("mm/dd/yyy") 和 "TaskTime" (" hh:mm:ss t") 列 - 您可以在绑定 DataGridView 的初始化部分执行此操作。
    • 另外,在初始化部分,您可能至少需要设置TaskDate 和TaskTime DataGridViewColumns 的名称。喜欢 - .Name = yourDataGridViewColumnObject.DataPropertyName = "TaskDate";
    【解决方案2】:

    确保数据库中的所有数据都是 UTC。这几乎是在数据库中存储日期/时间的标准方式。我很难学到这一点。

    将此代码转储到您的 CellFormatting 事件中

    private void dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (e.Value is DateTime)
            {
                DateTime value = (DateTime)e.Value;
                switch (value.Kind)
                {
                    case DateTimeKind.Local:
                        break;
                    case DateTimeKind.Unspecified:
                        e.Value = DateTime.SpecifyKind(value, DateTimeKind.Utc).ToLocalTime();
                        break;
                    case DateTimeKind.Utc:
                        e.Value = value.ToLocalTime();
                        break;
                }
            }
        }
    

    编辑:我刚刚注意到您正在从 EST 迁移到 Local,并且注意到您无法更改数据库。由于这是一个受欢迎的搜索结果,因此我将保留顶部功能。

    所以将这些行添加到上面函数的顶部

    if (e.ColumnIndex == 0) //change this to your column
    {
        String sqlFormat = "MM/dd/yyyy"; //change this to the sql format
        DateTime parsedDateTime = DateTime.ParseExact(e.Value, sqlFormat, null);
        TimeZoneInfo tziEastern = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
        e.Value = TimeZoneInfo.ConvertTimeToUtc(parseDateTime, tziEastern);
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-14
      • 1970-01-01
      • 2018-10-29
      • 2020-08-15
      相关资源
      最近更新 更多