44

I am using CsvHelper to write some CSV files and want to change the format of my dates and times to something specific. Following the advice from https://stackoverflow.com/a/31817621/223742 I can successfully create maps for each of my classes.

However it has the distinct disadvantage that I now need to create custom maps for all the classes that I want to export. As I always want all the fields exported this becomes a maintenance nightmare as I have to amend maps each time.

So is there any simple way to tell CsvHelper to write all dates and times using a specific format?

Community
  • 1
  • 1
TheEdge
  • 9,291
  • 15
  • 67
  • 135

3 Answers3

70

With newer version (12.1.2) of CsvHelper, it can be achieved by using TypeConverterOptionsCache

var options = new TypeConverterOptions { Formats = new[] { "MM/dd/yyyy" } };
csvWriter.Context.TypeConverterOptionsCache.AddOptions<DateTime>(options);

Output date

08/24/1991

Version 20 moved TypeConverterOptionsCache from Configuration to Context. So the above becomes

var options = new TypeConverterOptions { Formats = new[] { "MM/dd/yyyy" } };
csvWriter.Context.TypeConverterOptionsCache.AddOptions<DateTime>(options);
csvWriter.Context.TypeConverterOptionsCache.AddOptions<DateTime?>(options);
Ivan-Mark Debono
  • 15,500
  • 29
  • 132
  • 263
Pylyp Lebediev
  • 1,991
  • 4
  • 26
  • 44
  • 18
    and if you've got a mix of `DateTime` and `DateTime?`, don't forget to register both types! – djeikyb Oct 09 '19 at 22:58
  • Getting `error CS1545: Property, indexer, or event 'CsvContext.TypeConverterOptionsCache' is not supported by the language; try directly calling accessor methods 'CsvContext.get_TypeConverterOptionsCache()' or 'CsvContext.set_TypeConverterOptionsCache(?)' ` on Linux. – devlord Feb 05 '21 at 20:07
  • 1
    For CsvHelper 26.0.1 this is the correct answer. – Snympi Mar 05 '21 at 00:00
25

For me it was easier to use CsvHelper attributes on class.

[Format("yyyy-MM-dd")] did the job for datetime formatting.

namespace BarNamespace
{
    using System;
    using CsvHelper.Configuration.Attributes;

    public class Foo
    {
        [Name("ColumnName1")]
        [Format("yyyy-MM-dd")]
        public DateTime Date { get; set; }

        [Name("ColumnName2")]
        public string Col2{ get; set; }

        [Name("ColumnName3")]
        public long Col3{ get; set; }
    }
}

Rapolas
  • 283
  • 3
  • 6
12

You can set it globally per type using TypeConverterOptionsFactory.

void Main()
{
    using (var stream = new MemoryStream())
    using (var reader = new StreamReader(stream))
    using (var writer = new StreamWriter(stream))
    using (var csv = new CsvWriter(writer))
    {
        var options = new TypeConverterOptions
        {
            Format = "o"
        };
        TypeConverterOptionsFactory.AddOptions<DateTime>(options);

        csv.WriteField(DateTime.Now);
        csv.NextRecord();
        writer.Flush();
        stream.Position = 0;

        reader.ReadToEnd().Dump();
    }
}

Output:

2016-09-19T11:01:41.5507054-05:00
Josh Close
  • 22,935
  • 13
  • 92
  • 140