1

This is going to be one of those "I can't believe I didn't think of that" questions, but it's been vexing me for going on two days.

I've got bunch of date strings (and many more columns of data) coming out of a .csv file that are in this format: 8/8/2017 8:57

I've read through the SO questions here and here as well as the documentation on MSDN from here and here.

Here are a couple of things I've tried in C# statements in LINQPad, adapted from the MSDN examples:

string[] data = { "8/8/2017 8:57,-1.220135,-1.239456,-3.20E-08,-4.47E-09,-1.202865"};
Console.WriteLine(data);

string dateValue = "8/8/2017 8:57";
string[] patterns = {"M/d/yyyy H:mm", "MM/dd/yyyy H:mm"};

DateTime parsedDate;

if (DateTime.TryParseExact(data[0].ToString(), patterns,
       System.Globalization.CultureInfo.CurrentCulture,
       System.Globalization.DateTimeStyles.None,
       out parsedDate))
{
    Console.WriteLine("Converted '{0}' to {1}.",
    dateValue,
    parsedDate);
}
else
{
    Console.WriteLine("Unable to convert '{0}' to a date and time.",
    dateValue);
}

if (DateTime.TryParseExact(data[0].ToString(),
    patterns,
    null,
    System.Globalization.DateTimeStyles.None,
    out parsedDate))
{
    Console.WriteLine("Converted '{0}' to {1}.",
    dateValue, 
    parsedDate);
}
else
{
    Console.WriteLine("Unable to convert '{0}' to a date and time.",
    dateValue);
}

Both result in:

Unable to convert '8/8/2017 8:57' to a date and time.

Unable to convert '8/8/2017 8:57' to a date and time.

I've tried several variants in the string[] patterns... declaration to no avail.

What am I missing? I suspect the problem lies in my patterns array, but maybe not? This seems like it should be easy.

I'm not married to DateTime.TryParseExact(), so long as I get a valid DateTime out of the conversion.

Edit: After some of the comments, I've checked my CultureInfo.CurrentCulture, and it is en-US, which should be fine, or at least I think so.

Edit1: As pointed out by most, I was using an entire string instead of the date value, although I still get an error using the single string. Here's the first if() modified as suggested by Joel below:

string[] data = "8/8/2017 8:57,-1.220135,-1.239456,-3.20E-08,-4.47E-09,".Split(',');
string dateValue = "8/8/2017 8:57";
string[] patterns = {"M/d/yyyy H:mm"};

DateTime parsedDate;

if (DateTime.TryParseExact(data[0], patterns,
       System.Globalization.CultureInfo.CurrentCulture,
       System.Globalization.DateTimeStyles.None,
       out parsedDate))
{
    Console.WriteLine("Converted '{0}' to {1}.",
    dateValue,
    parsedDate);
}
else
{
    Console.WriteLine("Unable to convert '{0}' to a date and time.",
    dateValue);
}

I've managed to incorporate a version of this into my production code that's working as expected. Thanks for the help.

delliottg
  • 3,950
  • 3
  • 38
  • 52
  • My guess: you are using CultureInfo.InvariantCulture, but dates of types '8/8/2017' are American culture "en-US" – JRB Jan 24 '18 at 17:16
  • Just tried your code and it worked perfectly: `Converted '8/8/2017 8:57' to 08/08/2017 08:57:00.` – SBFrancies Jan 24 '18 at 17:18
  • 1
    Executing your code in ConsoleApplication1 yields: `Converted '8/8/2017 8:57' to 08.08.2017 08:57:00.`. So it has to be something with your computer or settings... – nvoigt Jan 24 '18 at 17:18
  • Hmm, I thought that I should be using InvarientCulture since it was coming from a file judging from the advice on this [SO question](https://stackoverflow.com/questions/9760237/what-does-cultureinfo-invariantculture-mean). Do you guys have any suggestions for what I could change in my code to get what I want? And yes I am in the US. – delliottg Jan 24 '18 at 17:23
  • 1
    It would be a lot easier to read your code if you would put line a line break between the condition of your `if` statement and the body - personally I'd encourage you to use braces too. – Jon Skeet Jan 24 '18 at 17:38
  • 1
    Next, I'm not surprised that the first conversion fails - the string "8/8/2017 8:57,-1.220135,-1.239456,-3.20E-08,-4.47E-09," isn't a date, because it's got all the rest of the data after it. Concentrate on converting just the valid date string. – Jon Skeet Jan 24 '18 at 17:39
  • @JonSkeet, edited per your request. I copy and pasted from the MSDN example, I'd normally use braces as well. Regarding your second comment, I'm using the first element of the array (data[0]), but swapping that for the string `dateValue` nets me the same error. – delliottg Jan 24 '18 at 17:45
  • 2
    @delliottg `string[] data = { "8/8/2017 8:57,-1.220135,-1.239456,-3.20E-08,-4.47E-09,-1.202865"};` is a single element in the array. – tRuEsAtM Jan 24 '18 at 17:49
  • 1
    You need to use `string[] data = { "8/8/2017 8:57","-1.220135","-1.239456","-3.20E-08","-4.47E-09","-1.202865"};` for multiple elements in the array. – tRuEsAtM Jan 24 '18 at 17:50
  • Hah, now I see what you guys meant, the code here is a subset of my actual code which does a split on the string array on the commas, I'll edit the question appropriately, sorry for the confusion. – delliottg Jan 24 '18 at 17:52
  • The last comment was hidden and I didn't see it when I first wrote my answer... but I stand by my last paragraph still. – Joel Coehoorn Jan 24 '18 at 18:06
  • 1
    One reason may be that the current culture uses a different date separator than `/` or a different time separator than `:`. You should escape/protected the special characters `/` and `:` if you want a literal slash or colon. For example like this: `string[] patterns = { "M'/'d'/'yyyy H':'mm", "MM'/'dd'/'yyyy H':'mm" };` – Jeppe Stig Nielsen Jan 24 '18 at 19:17

1 Answers1

2

Look carefully at your data:

string[] data = { "8/8/2017 8:57,-1.220135,-1.239456,-3.20E-08,-4.47E-09,-1.202865"};

This array has only one element, where the value of that element is all of the text. It seems different in the console messages because you put the 8/8/2017 8:57 value into a separate variable, rather than using the array.

Did you perhaps want this instead?

string[] data={"8/8/2017 8:57","-1.22013","-1.239456","-3.20E-08","-4.47E-09","-1.202865"};

Or maybe you wanted this:

var data = "8/8/2017 8:57,-1.220135,-1.239456,-3.20E-08,-4.47E-09,-1.202865".Split(',');

**Note I don't generally condone using .Split() as a csv parser, but for this simple example it gets the point across.

Whatever you do, I'd make sure your Console messages accurately reflect what you tried to do (use data[0] as the first substitution), so you can be sure the TryParseExact() method is looking at the string you think it is.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • I've been able to get my production code working, however, how would you recommend splitting a .csv file? The actual data files are enormously larger than the single truncated example here (roughly a 20k rows x 33 columns per file). If there's a better way to parse through it, I'm all ears. – delliottg Jan 24 '18 at 18:23
  • Pull in a csv library from nuget. CsvHelper seems popular recently. I'm partial to EasyCSV (but I'm biased). You should get a nice performance boost as a bonus, as Split() isn't exactly fast, either. – Joel Coehoorn Jan 24 '18 at 18:24