我想以毫秒为单位将带有DateTime字段的对象序列化为csv。我怎样才能做到这一点?
我正在通过以下代码编写csv:
using (var writer = new StreamWriter(_checksumsFilePath))
using (var csv = new CsvWriter(writer))
{
csv.WriteRecords(_checksums.Values.ToList());
}
而_checksums是此类的字典:
public class SomeClass
{
public string Name { get; set; }
public string val{ get; set; }
public DateTime lastTime{ get; set; }
}
当我写的时候,我从调试器看到-在DateTime中有几毫秒,但是对csv文件只写:
Name;val;lastTime
someName;49BC20DF15E412A64472421E13FE86FF1C5165E18B2AFCCF160D4DC19FE68A14;29.05.2019 16:13:08
答案 0 :(得分:1)
我通过使用基类的功能对您的答案进行了改进。
假设您只编写 csv 文件,这应该可以解决问题。
类 DefaultTypeConverter
(GitHub) 从 memberMapData.TypeConverterOptions.Formats
中获取所需的格式。
由于此参数是为类 CsvWriter
中的所有转换器设置的,您可能不希望这样,您可以按照我的方式编辑此函数,以使用自定义格式。
此函数现在不使用类 CsvWriter
中设置的格式,而是使用您自己的格式。
public class DateConverter : DateTimeConverter
{
private readonly string dateFormat;
/// <summary>
/// Initializes a new instance of the <see cref="DateConverter"/> class.
/// </summary>
/// <param name="dateFormat">Format in which the data should be formatted.</param>
public DateConverter(string dateFormat)
: base()
{
this.dateFormat = dateFormat;
}
/// <inheritdoc/>
public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
if (value == null)
{
if (memberMapData.TypeConverterOptions.NullValues.Count > 0)
{
return memberMapData.TypeConverterOptions.NullValues.First();
}
return string.Empty;
}
if (value is IFormattable formattable)
{
var format = this.dateFormat;
return formattable.ToString(format, memberMapData.TypeConverterOptions.CultureInfo);
}
return value.ToString();
}
}
答案 1 :(得分:0)
如果您正在使用此CsvHelper
,似乎可以通过ClassMap
对其进行配置:
https://joshclose.github.io/CsvHelper/api/CsvHelper.Configuration
答案 2 :(得分:0)
谢谢,但是我根据这个主题CsvHelper set default custom TypeConverter
创建了自己的转换器我做了一些小改动
public class DateConverter : ITypeConverter
{
private readonly string _dateFormat;
public DateConverter(string dateFormat)
{
_dateFormat = dateFormat;
}
public object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
if (!string.IsNullOrEmpty(text))
{
DateTime dt;
DateTime.TryParseExact(text, _dateFormat,
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out dt);
if (IsValidSqlDateTime(dt))
{
return dt;
}
}
return null;
}
public string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
return ObjectToDateString(value, _dateFormat);
}
public string ObjectToDateString(object o, string dateFormat)
{
if (o == null) return string.Empty;
DateTime dt;
if (o is DateTime)
{
dt = (DateTime)o;
return dt.ToString(dateFormat);
}
else
return string.Empty;
}
public bool IsValidSqlDateTime(DateTime? dateTime)
{
if (dateTime == null) return true;
DateTime minValue = DateTime.Parse(System.Data.SqlTypes.SqlDateTime.MinValue.ToString());
DateTime maxValue = DateTime.Parse(System.Data.SqlTypes.SqlDateTime.MaxValue.ToString());
if (minValue > dateTime.Value || maxValue < dateTime.Value)
return false;
return true;
}
}
并使用:
using (var writer = new StreamWriter(_checksumsFilePath))
using (var csv = new CsvWriter(writer))
{
csv.Configuration.TypeConverterCache.RemoveConverter<DateTime>();
csv.Configuration.TypeConverterCache.RemoveConverter<DateTime?>();
csv.Configuration.TypeConverterCache.AddConverter<DateTime?>(new DateConverter("MM/dd/yyyy hh:mm:ss.fff"));
csv.Configuration.TypeConverterCache.AddConverter<DateTime>(new DateConverter("MM/dd/yyyy hh:mm:ss.fff"));
csv.WriteRecords(_checksums.Values.ToList());
}