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();                 
}
Chandan Kumar
  • 4,570
  • 4
  • 42
  • 62
A.Dal
  • 83
  • 7
  • is the date format always the same dd/mm/yyy ? or does it differ between the entries in the array? – Mong Zhu May 19 '17 at 09:13
  • Possible duplicate of [Writing data into CSV file](http://stackoverflow.com/questions/18757097/writing-data-into-csv-file) – benbants May 19 '17 at 09:22

3 Answers3

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);
    }
}
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.

Community
  • 1
  • 1
Matt
  • 25,467
  • 18
  • 120
  • 187
  • Thanks for that Matt. but toDate cannot be resolved. the static class your using – A.Dal May 19 '17 at 11:18
  • @A.Dal: Please read the beginning of my answer - **[click here](http://stackoverflow.com/questions/5366285/parse-string-to-datetime-in-c-sharp/18465222#18465222)** and then copy it. This static class was written by me. – Matt May 19 '17 at 11:21
  • @A.Dal - with the hints I gave, could you fix it? – Matt May 19 '17 at 13:03
  • @A.Dal -You're welcome, glad to hear it is working! :-) – Matt May 19 '17 at 13:22
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] + ",");
Arion
  • 31,011
  • 10
  • 70
  • 88