Вычислить среднюю разницу дат нескольких строк

Мне нужно рассчитать среднее значение разницы дат всех моих строк в dataGridView.

Я реализовал NodaTime (что гораздо проще, чем традиционные методы вычисления разницы в датах) и сделал это только для того, чтобы попробовать:

var date1 = new LocalDate(2013, 1, 29);
var date2 = new LocalDate(2018, 1, 23);
Period period = Period.Between(date1, date2.PlusDays(1));
label1.Text = string.Format("{0} anos, {1} meses e {2} dias", period.Years, 
period.Months, period.Days);

Теперь, что я делаю, чтобы получить обе даты dataGridView, вычислить в каждой строке разницу дат и вычислить среднее значение для всех? Я хочу, чтобы это отображалось в годах, месяцах и днях. Спасибо.


person CaldeiraG    schedule 13.03.2018    source источник
comment
Соседние строки или любые две?   -  person Fildor    schedule 13.03.2018
comment
Я имею в виду, вычислить разницу дат 2 столбцов в каждой строке   -  person CaldeiraG    schedule 13.03.2018
comment
Не стесняйтесь редактировать вопрос, если это необходимо   -  person CaldeiraG    schedule 13.03.2018
comment
@TiagoCaldeira, так что вы в основном хотите рассчитать разницу дат между двумя dateTimes?   -  person styx    schedule 13.03.2018
comment
Правильно, но тогда мне нужно среднее значение всей разницы дат   -  person CaldeiraG    schedule 13.03.2018
comment
Ну, для разнообразия я бы добавил вычисляемый столбец. Затем вы можете суммировать этот столбец (см. также непринятый ответ stackoverflow.com/a/3779835/982149) и разделить на количество строк...   -  person Fildor    schedule 13.03.2018
comment
Имеет смысл, но я понятия не имею, как это реализовать. По сути, я хочу посмотреть, сколько времени требуется, чтобы статья вышла из хранилища (например) РЕДАКТИРОВАТЬ: только что посмотрел, что вы прикрепили несколько ссылок, проверим!   -  person CaldeiraG    schedule 13.03.2018
comment
@TiagoCaldeira - Привет, я опубликовал решение .. надеюсь, оно в какой-то степени поможет!   -  person Wheels73    schedule 13.03.2018
comment
@Wheels73 см. мой комментарий в вашем ответе   -  person CaldeiraG    schedule 13.03.2018


Ответы (2)


К сожалению, нет реальной концепции среднего значения Period, так как они даже не сопоставимы напрямую. Например, «1 месяц» длиннее или короче «29 дней»? Это зависит от месяца. Переходя к среднему, каковы два периода «1 месяц» и «29 дней»? Нет ничего действительно очевидного в качестве полезного ответа на этот вопрос, ИМО.

Что вы могли бы сделать, так это получить разницу только в днях (вероятно, используя Period.Between и указав PeriodUnits.Days), а затем найти среднее количество дней. Это логично, и его гораздо проще определить, чем среднее число лет/месяцев/дней.

person Jon Skeet    schedule 13.03.2018

Мне пришлось решать аналогичную проблему для одного из наших проектов. Я нашел приведенный ниже фрагмент кода, который, кажется, работает.

Предположим, что у вас есть сетка на форме для целей этого теста.

Добавьте даты в столбцы сетки. Я использую столбцы 0 и 1 для двух дат.

private void Form1_Load(object sender, EventArgs e)
{
        dgGridView.Rows.Add(new DataGridViewRow());
        dgGridView.Rows.Add(new DataGridViewRow());
        dgGridView.Rows.Add(new DataGridViewRow());

        dgGridView.Rows[0].Cells[0].Value = "Feb 01 2018 00:00:00";
        dgGridView.Rows[0].Cells[1].Value = "Feb 03 2018 06:00:45";
        dgGridView.Rows[1].Cells[0].Value = "Feb 02 2018 17:00:00";
        dgGridView.Rows[1].Cells[1].Value = "Feb 03 2018 21:54:21";
        dgGridView.Rows[2].Cells[0].Value = "Feb 04 2017 10:00:00";
        dgGridView.Rows[2].Cells[1].Value = "Feb 07 2018 08:23:26";
}

Под нажатием кнопки или любым другим механизмом, который вы выберете, рассчитайте средние значения. Это делается путем подсчета секунд, прошедших между каждым диапазоном дат, а затем деления его на количество строк.

var totalSeconds = 0.0;

 foreach (DataGridViewRow row in dgGridView.Rows)
 {
    var date1 = Convert.ToDateTime(row.Cells[0].Value);
    var date2 = Convert.ToDateTime(row.Cells[1].Value);
    var diff = (date2 - date1).TotalSeconds;

    row.Cells[2].Value = diff;
    totalSeconds += diff;
}

var totalRows = 3;
var aveSeconds = totalSeconds / totalRows;

TimeSpan aveTime = TimeSpan.FromSeconds(aveSeconds);

var totDays = aveTime.Days;
var totHours = aveTime.Hours;
var totMins = aveTime.Minutes;
var totSeconds = aveTime.Seconds;

var ave = $"Days:{totDays} Hours:{totHours} Mins:{totMins} Seconds:{totSeconds}";

Затем вы можете получить объект TimeSpan из этих полных секунд и извлечь количество дней, часов, минут и секунд для среднего значения.

Я думаю, это работает. Заранее извиняюсь, если какой-то зоркий человек заметит недостаток, но я надеюсь, что это поможет вам на вашем пути.

Спасибо

person Wheels73    schedule 13.03.2018
comment
Это выглядит многообещающе и на самом деле может работать, но я хотел в годах, месяцах и днях, часы не важны. - person CaldeiraG; 13.03.2018
comment
@TiagoCaldeira - Ну, если количество дней ›= 365, то, я думаю, вы можете интерпретировать годы? - person Wheels73; 13.03.2018
comment
Это частично работает, да, но я хотел бы получить точные результаты, а не просто делить на 365. - person CaldeiraG; 13.03.2018