0

I want to dynamically format any column's date to yyyy-MM-dd. I know i can conditionally set a specific column to this date format, but is there any way to do it dynamically for all columns that have dates. Currently I am using a try catch here which works for all dates, but the problem is that any columns that aren't dates i.e. a value of 3.8707 will become 01/03/8707 on the csv output

foreach (var array in from DataRow myrow in dt.Rows select row.ItemArray)
{
    for (i = 0; i < array.Length; i++)
    {
        try
        {
             DateTime date = DateTime.Parse(array[i].ToString());
             swOut.Write(date.Year + '-' + date.Month + '-' + date.Day + ",");
        }
        catch (Exception)
        {
             swOut.Write(array[i] + ",");
        }
     }
     swOut.WriteLine();                 
}
2
  • is the date format always the same dd/mm/yyy ? or does it differ between the entries in the array? Commented May 19, 2017 at 9:13
  • Possible duplicate of Writing data into CSV file Commented May 19, 2017 at 9:22

3 Answers 3

1

Click here and copy the static class Extensions with the extension method toDate(...) I have written (don't forget to add using System.Globalization;). If you're using it, you can do it simply like this, without having to catch an exception:

var arrayItems = from DataRow myrow in dt.Rows select row.ItemArray;
foreach (var array in arrayItems)
{
    for (var i = 0; i < array.Length; i++)
    {           
        var strItem = (array[i] ?? "").ToString();
        var date=strItem.toDate("yyyy-MM-dd");
        if (!date.HasValue) {
            swOut.Write(strItem + ",");
        }
        else
        {
            swOut.Write(date.Value.Year + '-' + 
                            date.Value.Month + '-' + date.Value.Day + ",");
        }
    }
    swOut.WriteLine();
}

Note that if you have to match a different data format, just change the parameter in the funtion .toDate("yyyy-MM-dd"). You can even specify multiple data formats which are accepted, like so:

string[] dateFmt = {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt", 
                 "MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss", 
                 "M/d/yyyy hh:mm tt", "M/d/yyyy hh tt", 
                 "M/d/yyyy h:mm", "M/d/yyyy h:mm", 
                 "MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm"};

then inside the loop you can use it:

var date=strItem.toDate(dateFmt);

That way, they will be interpreted and parsed and then they will be converted into YYYY-MM-dd and written into the .csv file, as you have specified it in the Write statement of your for loop.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for that Matt. but toDate cannot be resolved. the static class your using
@A.Dal: Please read the beginning of my answer - click here and then copy it. This static class was written by me.
@A.Dal - with the hints I gave, could you fix it?
@A.Dal -You're welcome, glad to hear it is working! :-)
1

Instead of making your own datetime format parser, you should use the one already available for you. DateTime.TryParseExact is your tool to convert a string in a date when you know the exact format. If you know in which format the date is present in the CSV, then Converting back the date, in the string format that you like, is another task easily solved by the override of ToString() specific for a datetime.

In your code, you are using try catch that will decrease the performance.

string[] values = lines1[i].Split(',');
if (values.Length >= 3)
{
    DateTime dt;
    if (DateTime.TryParseExact(values[0], "d-MMM-yyyy", 
        System.Globalization.CultureInfo.CurrentCulture, 
        System.Globalization.DateTimeStyles.None, out dt))
    {
        values[0] = dt.ToString("yyyy-MM-dd");
        lines1[i] = String.Join(",", values);
    }
}

Comments

0

You could check the type of the column. Like this:

if(array[i] is DateTime)
{
    var date=(DateTime)array[i];
    swOut.Write(date.Year + '-' + date.Month + '-' + date.Day + ",");
}
else
    swOut.Write(array[i] + ",");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.