如何在CSV文件中重新重新格式化日期值?

发布于 2025-01-21 06:05:13 字数 1641 浏览 3 评论 0原文

我有一个CSV文件,其中包含(除其他字段)(无效)DateTime值,其格式为“ 2021-11-20 14:16:16:52.255421”,我想摆脱毫秒或其他。

我尝试过这样的尝试,但是日期格式保持不变:

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

我在做什么错?我真的不明白CSVWriter甚至如何了解输入格式...

I have a CSV file that contains (among other fields) (nullable) DateTime values that are formatted like "2021-11-20 14:16:52.255421" I want to get rid of the milliseconds or whatever that is.

I have tried like this, but somehow the date format remains the same:

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

What am I doing wrong? I really don't understand how the CsvWriter would even know about the input format...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我要还你自由 2025-01-28 06:05:13

您的问题是,由于您的属性是类型dateTime?,您必须明确注册dateTime的类型转换器?以及dateTime

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

演示小提琴#1 在这里

创建扩展方法:

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

so

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

如果经常出现这种情况,您可以为typeconverteroptionscache nofollow noreferrer“>在这里。

Your problem is that, since your properties are of type DateTime?, you must explicitly register a type converter for DateTime? as well as DateTime:

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

Demo fiddle #1 here.

If this situation arises often, you could create an extension method for TypeConverterOptionsCache like so:

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

And then do:

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

Demo fiddle #2 here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文