Как сравнить дату в столбце базы данных и date_now, и положить результат в столбце? - PullRequest
0 голосов
/ 12 апреля 2019

У меня есть таблица в SqlServer, которая содержит: (ID, item_name, date_time_added)

я хочу сначала создать код C #: просмотреть (ID, item_name, date_time_added) столбец в datagridview, а затем рассчитать (date_time_NOW- date_time_added) и просмотреть результат в новом столбце (с именем: 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 голосов
/ 13 апреля 2019

Я предполагаю, что поле «ExpireDate», возвращаемое из запроса sql, является объектом DateTime.Если это так, то может показаться, что преобразование «даты» в строку не требуется.Например, учитывая «будущую» дату, тогда разница между сегодняшней датой и «будущей» датой может быть получена как…

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

Использование DataTable дает возможность использовать столбец ExpressionОднако я не думаю, что это будет работать с датами и временем.К счастью, это не должно быть сложно реализовать, если сетка DataSource является DataTable.Использование «Класса» было бы другим вариантом.Этот пример использует 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 событие.Это событие вызовет метод SetDifCol, если значение «ExpireDate» изменится в этой строке…

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. Мой ответ «добавляет» столбец diffence к 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;
  }
}

Эти два изменения должны отсортировать столбец численно, как и ожидалось.

Наконец, должно быть ясно, что ЕСЛИ вы хотите, чтобы этот столбец «различий» был отражен в базе данных… тогда вам нужно будет добавить столбец различий в таблицу базы данных, ТО, вам нужно будет выполнитькоманда обновления таблицы базы данных.

0 голосов
/ 12 апреля 2019

Из того, что я вижу, вы пытаетесь вставить строку в значение 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.Now:

TimeSpan span =  dateAsDateTime - DateTime.Now;

И, наконец, извлечь дни из диапазона:

int days = span.Days;

ИЛИ просто сделать все это в одной строке:

int days = (DateTime.Now - dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value).Days;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...