Comparing adjacent time stamps I have this code which compares two adjacent time stamps. If they are less than 15 min apart, it adds a new time stamp (row) in between with the new time stamp equal to the previous time + 15 min and value equal to the previous time stamp. If there is more than one-time stamp missing (more than 15 min interval), it adds a number of time stamps with + 15 min interval each. Sample value equal to last recorded value.

CSV file looks something like this: 


"Time stamp","Value","Events","Comment","User"
"5/07/2016 7:07:54 PM","7.00","","",""
"5/07/2016 6:37:52 PM","14.00","","",""
"5/07/2016 6:22:51 PM","26.00","","",""
"5/07/2016 6:07:50 PM","9.00","","",""
"5/07/2016 7:22:06 AM","0.00","","",""
"5/07/2016 7:07:05 AM","16.00","","",""
"5/07/2016 6:52:04 AM","25.00","","",""



At the moment it is doing what it suppose to do but in wrong direction, because the .csv file was created from bottom up.

for (var currentRow = 0; currentRow &lt; dgvValues.Rows.Count; currentRow++)
    {
        for (var cellIndex = 0; cellIndex &lt; dgvValues.Rows[currentRow].Cells.Count; cellIndex++)
        {
            if (cellIndex &gt; 0 &amp;&amp; cellIndex &lt; dgvValues.Rows[currentRow].Cells.Count)
            {
                buffer += ",";
            }
            buffer += dgvValues.Rows[currentRow].Cells[cellIndex].Value.ToString();
        }
        buffer += "\n";

        pleasewait.LabelText = (currentRow.ToString() + " of " + numRows + " rows processed");
        Application.DoEvents();

        if (currentRow + 1 &gt;= dgvValues.Rows.Count) continue;
        {
            var firstDate = Parse(dgvValues.Rows[currentRow].Cells[0].Value.ToString());
            var secondDate = Parse(dgvValues.Rows[currentRow + 1].Cells[0].Value.ToString());

            var timespan = firstDate - secondDate;
            double min = -15;
            firstDate = firstDate.AddMinutes(min);

            if (timespan.TotalMinutes &gt; 15)
            {
                if (firstDate == secondDate)
                    @equals = true;
                while (timespan.TotalMinutes &gt; 15 &amp;&amp; !@equals)
                {
                    timespan = firstDate - secondDate;
                    for (var cellIndex = 0;
                        cellIndex &lt; dgvValues.Rows[currentRow].Cells.Count;
                        cellIndex++)
                    {
                        if (cellIndex &gt; 0 &amp;&amp; cellIndex &lt; dgvValues.Rows[currentRow].Cells.Count)
                        {
                            buffer += ",";
                        }
                        if (cellIndex != 0)
                        {
                            buffer += dgvValues.Rows[currentRow].Cells[cellIndex].Value.ToString();
                        }
                        else
                            buffer += Parse(firstDate.ToString(CultureInfo.CurrentCulture));
                    }
                    buffer += "\n";
                    min = -15;
                    firstDate = firstDate.AddMinutes(min);
                }
            }
        }
    }
The code is way too "linear", too deep, too hard to follow with all the indexing and generic column-cell referencing.


I prefer foreach over for.  Simpler, cleaner, easier to read. 
For each row, you can reference the DataGridViewCellCollection property by column name-value: theRow.Cells['theColumnName'].Value 
Create a method that takes a DataGridViewRow parameter and simply copies its column values into a "CSVrow" object - a class you create.


override ToString and build the CSV string there.

Create a "CSVrowCollection" class to hold the CSV objects.


Its main purpose is to build the CSV file. Do this in a ToString override



.

class CSV {
    public CSV (DataGridViewRow timeStampRow) {  }

    public override string ToString() {
        // note the single quote characters wrapping the complete string
        return string.Format('"{0}","{1}","{2}","{3}","{4}","{5}"', 
                            Timestamp, Value, Events, Comment, User);
    }
}

class CSVcollection {
    protected List&lt;CSV&gt; CsvList { get; set; }

    public void Add(CSV aCsvObject) { }

    public override string ToString() {
        // building the value names string not shown.
        StringBuilder me = new StringBuilder();  //System.Text

        foreach (var record in CsvList)
           me.AppendLine(record);  //implicit ToString call

        return me.ToString();
    }
}