Save an object that uses a Nodatime LocalDateTime to csv using csvhelper

153 views Asked by At

I am trying to save a list of objects into a csv using the csvhelper library. The object looks like this:

public class AccountDTO {
    public string? Name { get; set; }
    public LocalDateTime CreatedDate { get; set; }
}

The LocalDateTime field is a NodaTime.LocalDateTime. I save the list using this method:

public void SaveAsCSV<T>(List<T> records, string path) {
    using var writer = new StreamWriter(path);
    using var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
    csv.WriteRecords(records);
}

For some reason it saves the rows with columns of all the metadata in the LocalDateTime field instead of just saving the string version.

So instead of appearing as:

| Name     | CreatedDate|
| -------- | -----———-- |
| Name 1   | 2008-10-31T17:04:32|
| Name 2   | 2008-10-32T17:04:32|

It gets saved as: csv view or with columns:csv columns

I am not too familiar with csvhelper and nodatime so any help would be greatly appreciated.

I have tried a couple of csvhelper type converter solutions such as

public class LocalDateTimeConverter : ValueConverter<LocalDateTime, DateTime>
{
    public LocalDateTimeConverter() : base(
        localDateTime => localDateTime.ToDateTimeUnspecified(),
        dateTime => LocalDateTime.FromDateTime(dateTime))
    { }
}

and others but nothing has worked so far.

1

There are 1 answers

1
David Specht On BEST ANSWER

LocalDateTime is a class object and CsvHelper is writing out all of the properties of that object. You can use Convert in a ClassMap to only output the ToString() value of the LocalDateTime object.

void Main()
{
    var records = new List<AccountDTO>() {
        new AccountDTO {
            Name = "Name 1",
            CreatedDate = new LocalDateTime(2008,10,30,17,4,32)
        },
        new AccountDTO {
            Name = "Name 2",
            CreatedDate = new LocalDateTime(2008,10,31,17,4,32)
        }
    };

    using var csv = new CsvWriter(Console.Out, CultureInfo.InvariantCulture);

    csv.Context.RegisterClassMap<AccountDTOMap>();
    csv.WriteRecords(records);
}

public class AccountDTOMap : ClassMap<AccountDTO>
{
    public AccountDTOMap() 
    {
        Map(x => x.Name);
        Map(x => x.CreatedDate).Convert(args => args.Value.CreatedDate.ToString());
    }
}

public class AccountDTO
{
    public string? Name { get; set; }
    public LocalDateTime CreatedDate { get; set; }
}