GOOGLE ADS

Freitag, 15. April 2022

Wie formatiere ich DateTime-Werte in einer CSV-Datei neu?

Ich habe eine CSV-Datei, die (neben anderen Feldern) (nullable) DateTime-Werte enthält, die wie „2021-11-20 14:16:52.255421" formatiert sind. Ich möchte die Millisekunden oder was auch immer loswerden.

Ich habe es so versucht, aber irgendwie bleibt das Datumsformat gleich:

 var csvConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture);
csvConfiguration.HasHeaderRecord = true;
csvConfiguration.Delimiter = ";";
csvConfiguration.TrimOptions = TrimOptions.Trim;

Record[] records;
using (var reader = new StreamReader(CsvPath, Encoding.UTF8))
using (var csv = new CsvReader(reader, csvConfiguration))
{
records = csv.GetRecords<Record>().ToArray();
}
using (var writer = new StreamWriter($@"reformatted.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.CurrentCulture))
{
//I have also tried with these options, but it doesn't help either
//var options = new TypeConverterOptions { Formats = new[] { "yyyy-MM-dd HH:mm:ss" } };
//csv.Context.TypeConverterOptionsCache.AddOptions<DateTime>(options);
csv.WriteRecords(records.Where(x => x.Memo!= null));
}
// "mbox_id";"email_address";"created";"updated";"created_by";"memo";
class Record
{
[Name("mbox_id")]
public string MailboxId { get; set; }

[Name("email_address")]
public string EmailAddress { get; set;}

[Name("created")]
public DateTime? Created { get; set; }

[Name("updated")]
public DateTime? Updated { get; set; }

[Name("created_by")]
public string CreatedBy { get; set;}

[Name("memo")]
public string Memo { get; set; }
}

Was mache ich falsch? Ich verstehe wirklich nicht, wie der CsvWriter überhaupt über das Eingabeformat Bescheid wissen sollte...


Lösung des Problems

Ihr Problem ist, dass Sie, da Ihre Eigenschaften vom Typ DateTime?sind, explizit einen Typkonverter für DateTime?sowie registrieren müssen DateTime:

csv.Context.TypeConverterOptionsCache.AddOptions<DateTime?>(options);
csv.Context.TypeConverterOptionsCache.AddOptions<DateTime>(options);

Demo-Geige Nr. 1 hier.

Wenn diese Situation häufig auftritt, können Sie eine Erweiterungsmethode TypeConverterOptionsCachewie folgt erstellen:

public static class TypeConverterOptionsCacheExtensions
{
public static void AddOptionsForTypeAndNullable(this TypeConverterOptionsCache cache, Type type, TypeConverterOptions options)
{
if (type == null || cache == null)
throw new ArgumentNullException();
if (!type.IsValueType)
{
cache.AddOptions(type, options);
}
else
{
var underlying = Nullable.GetUnderlyingType(type)?? type;
var nullable = typeof(Nullable<>).MakeGenericType(underlying);
cache.AddOptions(underlying, options);
cache.AddOptions(nullable, options);
}
}
public static void AddOptionsForTypeAndNullable<T>(this TypeConverterOptionsCache cache, TypeConverterOptions options) where T: struct
=> cache.AddOptionsForTypeAndNullable(typeof(T), options);
}

Und dann mach:

csv.Context.TypeConverterOptionsCache.AddOptionsForTypeAndNullable<DateTime>(options);

Demo-Geige Nr. 2 hier.

Keine Kommentare:

Kommentar veröffentlichen

Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...