如何重新格式化 CSV 文件中的 DateTime 值?
How to reformat DateTime values in CSV file?
我有一个 CSV 文件,其中包含(在其他字段中)(可为空)格式类似于“2021-11-20 14:16:52.255421”的 DateTime 值我想去掉毫秒或其他任何格式那就是。
我试过这样,但不知何故日期格式保持不变:
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 怎么会知道输入格式...
你的问题是,由于你的属性是 DateTime?
类型,你必须显式地为 DateTime?
和 DateTime
:
注册一个类型转换器
csv.Context.TypeConverterOptionsCache.AddOptions<DateTime?>(options);
csv.Context.TypeConverterOptionsCache.AddOptions<DateTime>(options);
演示 fiddle #1 here.
如果这种情况经常出现,您可以为 TypeConverterOptionsCache
创建一个扩展方法,如下所示:
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);
}
然后做:
csv.Context.TypeConverterOptionsCache.AddOptionsForTypeAndNullable<DateTime>(options);
演示 fiddle #2 here.
我有一个 CSV 文件,其中包含(在其他字段中)(可为空)格式类似于“2021-11-20 14:16:52.255421”的 DateTime 值我想去掉毫秒或其他任何格式那就是。
我试过这样,但不知何故日期格式保持不变:
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 怎么会知道输入格式...
你的问题是,由于你的属性是 DateTime?
类型,你必须显式地为 DateTime?
和 DateTime
:
csv.Context.TypeConverterOptionsCache.AddOptions<DateTime?>(options);
csv.Context.TypeConverterOptionsCache.AddOptions<DateTime>(options);
演示 fiddle #1 here.
如果这种情况经常出现,您可以为 TypeConverterOptionsCache
创建一个扩展方法,如下所示:
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);
}
然后做:
csv.Context.TypeConverterOptionsCache.AddOptionsForTypeAndNullable<DateTime>(options);
演示 fiddle #2 here.