<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Stefano Ricciardi &#187; Libraries</title>
	<atom:link href="http://stefanoricciardi.com/tag/libraries/feed/" rel="self" type="application/rss+xml" />
	<link>http://stefanoricciardi.com</link>
	<description>On Software Development and Thereabouts</description>
	<lastBuildDate>Thu, 02 Sep 2010 15:01:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Parsing Dates from CSV files with FileHelpers Library</title>
		<link>http://stefanoricciardi.com/2009/10/07/parsing-dates-from-csv-files-with-filehelpers-library/</link>
		<comments>http://stefanoricciardi.com/2009/10/07/parsing-dates-from-csv-files-with-filehelpers-library/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 20:08:37 +0000</pubDate>
		<dc:creator>stefanoricciardi</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Libraries]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://stefanoricciardi.net/?p=400</guid>
		<description><![CDATA[In my current project I have found myself needing to parse a CSV file coming from a legacy C++ application. This is a fairly common task, and in the past I have always written the parsing engine myself, especially when there was some validation related to the business logic involved. This time I have chosen [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fstefanoricciardi.com%2F2009%2F10%2F07%2Fparsing-dates-from-csv-files-with-filehelpers-library%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fstefanoricciardi.com%2F2009%2F10%2F07%2Fparsing-dates-from-csv-files-with-filehelpers-library%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>In my current project I have found myself needing to parse a CSV file coming from a legacy C++ application. This is a fairly common task, and in the past I have always written the parsing engine myself, especially when there was some validation related to the business logic involved.</p>
<p>This time I have chosen to try the reportedly excellent <a href="http://www.filehelpers.com/">FileHelpers</a> library. Why reinvent the wheel yet another time? The library is well documented and in a matter of minutes I was able to start experimenting with some test data.</p>
<p>To simplify the discussion, suppose that the CSV file has the following structure:</p>
<pre>
# City, Date, Temperature
Chicago; 20090913 07:00:00; 62.23
New York; 20090913 08:00:00; 81.3
</pre>
<p>Each row of the CSV file is mapped to the following class:</p>
<pre class="brush:csharp">
[DelimitedRecord(&quot;;&quot;)]
[IgnoreEmptyLines()]
[ConditionalRecord(RecordCondition.ExcludeIfBegins, &quot;#&quot;)]
public class CsvRecord
{
    public string City;

    [FieldConverter(ConverterKind.Date, &quot;yyyyMMdd HH:mm:ss&quot;)]
    public DateTime Date;

    [FieldConverter(ConverterKind.Double, &quot;.&quot;)]
    public double Temperature;
}
</pre>
<p>The attributes are pretty self-explanatory: they specify which is the separator value and which lines can be ignored.</p>
<p>The interesting part here is the way FileHelpers allows to specify a pattern to convert a string into a <code>DateTime</code> value. In this case, the pattern used here is <code>yyyyMMdd HH:mm:ss</code> to match the CSV file.</p>
<p>Once the mapping between the CSV and the .NET object is setup, I have created a class wrapping the FileHelpers engine (just in case some day I want to change the parsing engine), with the following (simplified) method:</p>
<pre class="brush:csharp">
public IEnumerable&lt;CsvRecord&gt; GetRecordsFromFile(Stream s)
{
   FileHelperEngine engine = new FileHelperEngine(typeof(CsvRecord));
   s.Seek(0, SeekOrigin.Begin);

   CsvRecord[] records = engine.ReadStream(new StreamReader(s)) as CsvRecord[];
   return records;
}
</pre>
<p>This was working like a charm&#8230; until I moved the code to a separate test machine. All of a sudden the parser would complain that it could not parse the dates from the file. After a lot of thought, I realized that the test machine had a different regional settings: while my machine had English formats, the test machine had Italian formats. And for some reason FileHelpers was not able to work correctly in this scenario (even though I had explicitly specified the date and time pattern in the <code>CsvRecord</code> class).</p>
<p>Luckily, FileHelpers lets you specify your own converters if the predefined ones won&#8217;t do. I therefore created my custom converter for the dates as follows:</p>
<pre class="brush:csharp">
public class CustomDateTimeConverter : ConverterBase
{
    private const string DateTimeFormat = &quot;yyyyMMdd HH:mm:ss&quot;;

    public override object StringToField(string from)
    {
        return DateTime.ParseExact(from, DateTimeFormat, CultureInfo.InvariantCulture);
    }
}
</pre>
<p>and rewritten the <code>CsvRecord</code> class as follows:</p>
<pre class="brush:csharp">
[DelimitedRecord(&quot;;&quot;)]
[IgnoreEmptyLines()]
[ConditionalRecord(RecordCondition.ExcludeIfBegins, &quot;#&quot;)]
public class CsvRecord
{
    public string City;

    [FieldConverter(typeof(CustomDateTimeConverter))]
    public DateTime Date;

    [FieldConverter(ConverterKind.Double, &quot;.&quot;)]
    public double Temperature;
}
</pre>
<p>This time it worked also with Italian locale.</p>
<p>Frankly, I don&#8217;t know why the FileHelpers class had problems with the Italian locale (possibly with locales different from English ones). Probably having a look at the source code would reveal the truth.</p>
<p>I suspect that it is parsing the dates with a given format but without specifying an invariant culture format provider. But that is just a wild guess.</p>
<p><!-- AddThis Button BEGIN --></p>
<p><a href="http://www.addthis.com/bookmark.php?v=250"><img style="border:0;" src="http://s7.addthis.com/static/btn/lg-share-en.gif" alt="Bookmark and Share" width="125" height="16" /></a></p>
<p><!-- AddThis Button END --></p>
<div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e6ceeafa-fe5c-4bd6-a48d-325da43e5abc" class="wlWriterEditableSmartContent" style="display:inline;float:none;margin:0;padding:0;">Technorati Tags: <a rel="tag" href="http://technorati.com/tags/Programming">Programming</a>, <a rel="tag" href="http://technorati.com/tags/C%23">C#</a></div>
]]></content:encoded>
			<wfw:commentRss>http://stefanoricciardi.com/2009/10/07/parsing-dates-from-csv-files-with-filehelpers-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
