如何比较数据库列和date_now中的日期,并将结果放入列中?

时间:2019-04-12 07:55:20

标签: c# database datagridview

我在SqlServer中有一个表,其中包含:(ID,项目名称,添加的日期时间)

我想创建一个C#代码,首先:在datagridview中查看(ID,item_name,date_time_added)列,然后计算(date_time_NOW-date_time_added),并在同一datagridview中的新列(名为:expire's in :)中查看结果。 ..

注意:结果将计算到期前一天的剩余时间

到目前为止我已经尝试过的:

        DataTable dt = new DataTable();
        dt.Columns.Add(new DataColumn("Expire's in:", typeof(int)));

        int countrow = dataGridView1.RowCount;

            for (int i = 0; i < countrow; i++)
            {

                string dateAsString = dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value.ToString();
                DateTime.TryParseExact(dateAsString , "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out DateTime dateAsString);

                dateTimePicker3.Text = dateAsString;
                DateTime expire_date = dateTimePicker3.Value;

                TimeSpan span = expire_date - DateTime.Now;
                int days = span.Days;
                dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[4].Value = days;

            }

注意:代码已更新... 任何帮助将不胜感激..

2 个答案:

答案 0 :(得分:0)

根据我的发现,您尝试在此处将字符串放入DateTime值:

DateTime str;
        str=dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value.ToString();

如果要将字符串解析为DateTime,代码应如下所示:

string dateAsString = dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value.ToString();
                DateTime.TryParseExact(dateAsString, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out DateTime dateAsDateTime);

然后您可以从DateTime中减去该日期。现在:

TimeSpan span =  dateAsDateTime - DateTime.Now;

最后从跨度中提取日期:

int days = span.Days;

或者只需一行完成所有操作:

int days = (DateTime.Now - dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value).Days;

答案 1 :(得分:0)

我将假定从sql查询返回的“ ExpireDate”字段是DateTime对象。如果是这种情况,那么似乎没有必要将“日期”转换为字符串。例如,给定一个“未来”日期,那么今天的日期和“未来”日期之间的差可以实现为……

TimeSpan dif = futureDate.Subtract(DateTime.Now);

使用DataTable可以使用Expression列,但是,我认为这不适用于日期和时间。幸运的是,如果网格DataSourceDataTable,则实现起来并不难。使用“类”将是另一种选择。本示例使用DataTable作为网格的DataSource

鉴于此,为了简化起见,似乎很方便的方法是从数据表中获取DataRow,并添加此TimeSpan差异。可能看起来像下面的样子……

private void SetDifCol(DataRow row) {
  TimeSpan dif = ((DateTime)row["ExpireDate"]).Subtract(DateTime.Now);
  row["TimeToExpire"] = dif.Days + " days " + dif.Hours + " hours " + dif.Minutes + " minutes";
}

鉴于DataTable已经被数据填充了,代码将不得不“添加”该差异列,然后遍历每一行并计算日期之间的差异。因此,仅添加此列的一个小方法可能如下所示……

private void AddDifferenceColumn(DataTable dt) {
  dt.Columns.Add("TimeToExpire", typeof(string));
}

下一步是遍历DataTable中所有行的循环,只需在每一行上调用SetDifCol方法。

private void CalculateDateDif(DataTable dt) {
  foreach (DataRow row in dt.Rows) {
    SetDifCol(row);
  }
}

这将在加载数据时按预期工作,但是,如果用户“更改”网格中的“ ExpireDate”值之一怎么办?在这种情况下,我们需要连接一个网格单元更改事件。特别是网格CellValueChanged事件。如果该行中的“ ExpireDate”值发生更改,则此事件将调用SetDifCol方法。

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
  if (dataGridView1.Columns[e.ColumnIndex].Name == "ExpireDate") {
    if (e.RowIndex >= 0 && dataGridView1.Rows[e.RowIndex].Cells["ExpireDate"].Value != null) {
      DataRowView row = (DataRowView)dataGridView1.Rows[e.RowIndex].DataBoundItem;
      SetDifCol(row.Row);
    }
  }
} 

将所有内容放在一起可能如下所示……

enter image description here

DataTable GridTable;

public Form1() {
  InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e) {
  GridTable = GetTable();
  FillTable(GridTable);
  AddDifferenceColumn(GridTable);
  CalculateDateDif(GridTable);
  dataGridView1.DataSource = GridTable;
  dataGridView1.Columns[3].Width = 180;
}


private DataTable GetTable() {
  DataTable dt = new DataTable();
  dt.Columns.Add("ID", typeof(string));
  dt.Columns.Add("Name", typeof(string));
  dt.Columns.Add("ExpireDate", typeof(DateTime));
  return dt;
}
private void AddDifferenceColumn(DataTable dt) {
  dt.Columns.Add("TimeToExpire", typeof(string));
}

private void FillTable(DataTable dt) {
  dt.Rows.Add("ID1", "Name1", new DateTime(2019, 12, 31));
  dt.Rows.Add("ID2", "Name2", new DateTime(2019, 8, 31));
  dt.Rows.Add("ID3", "Name3", new DateTime(2019, 4, 30));
  dt.Rows.Add("ID4", "Name4", new DateTime(2019, 1, 31));
  dt.Rows.Add("ID5", "Name5", new DateTime(2019, 4, 12, 21, 38, 00));
}

private void CalculateDateDif(DataTable dt) {
  foreach (DataRow row in dt.Rows) {
    SetDifCol(row);
  }
}

private void SetDifCol(DataRow row) {
  TimeSpan dif = ((DateTime)row["ExpireDate"]).Subtract(DateTime.Now);
  row["TimeToExpire"] = dif.Days + " days " + dif.Hours + " hours " + dif.Minutes + " minutes";
}

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
  if (dataGridView1.Columns[e.ColumnIndex].Name == "ExpireDate") {
    if (e.RowIndex >= 0 && dataGridView1.Rows[e.RowIndex].Cells["ExpireDate"].Value != null) {
      DataRowView row = (DataRowView)dataGridView1.Rows[e.RowIndex].DataBoundItem;
      SetDifCol(row.Row);
    }
  }
}

我希望这会有所帮助。

编辑:  将列类型从string更改为int以进行数字排序。

关于您发布的其他问题,您评论说“我想根据我的数据库表中的内容进行计算” …此问题中没有任何代码或显示的其他问题一个数据库。您如何开始获取数据?

在此问题中似乎出现了一个新的DataTable dt,并向其中添加了一个列,但是从未使用过它。代码中的循环只是将差异列添加到“ GRID”而不是DataTable.我的答案是将差异列添加到DataTable(您应该这样做)。我建议您说明如何从数据库中获取数据。

关于对列进行排序,您已经注意到string个数字不能正确地按数字排序。这是因为它们是字符串...解决方案...使它们为ints。使用我的答案,对此需要两个更改。首先,列的创建需要为int类型…

private void AddDifferenceColumn(DataTable dt) {
  dt.Columns.Add("TimeToExpire", typeof(int));
}

第二个SetDifCol方法需要更改。由于您只希望日差,并且任何小于零的值都应显示为零(0),因此以下更改应符合此要求。

private void SetDifCol(DataRow row) {
  TimeSpan dif = ((DateTime)row["ExpireDate"]).Subtract(DateTime.Now);
  if (dif.Days >= 0) {
    row["TimeToExpire"] = dif.Days;
  }
  else {
    row["TimeToExpire"] = 0;
  }
}

这两个更改应按预期对列进行数字排序。

最后,应该清楚的是,如果您希望此“差异”列反映在数据库中……那么您将不得不将差异列添加到数据库表中,然后,您将需要发出更新命令到数据库表。