DateTime.ParseExact is failing (string not valid datetime format) - c#

I am trying to use DateTime.ParseExact on a timestamp that uses the format M/d/yyyy HH:mm:ss:fff and the compiler is telling me that this is not going to happen.
An example of my timestamp is:
3/26/2013 14:37:05:553
...and an example of my code is, where _CultureInfo is en-us.
DateTime someDateTime = DateTime.ParseExact("3/26/2013 14:37:05:553","M/d/yyyy HH:mm:ss:fff", _CultureInfo.DateTimeFormat);
See below image of what's going on... am I missing something?
New Edit
I've tried a couple more things with still no luck:
Changing :fff to .fff
Changing _CultureInfo.DateTimeFormat to System.Globalization.CultureInfo.InvariantCulture and changing the d to dd as suggested below
Below is something you can throw into a Console and run to see exactly how this is behaving on my end.
class Program
{
static void Main(string[] args)
{
CsvImporter importer = new CsvImporter();
DateTime readtime = importer.Parse(#"""3/26/2013 14:37:07:238,00:00:01.6850000,23.138,23.488,23.175""");
Console.WriteLine(readtime.ToString());
}
}
class CsvImporter
{
public Char[] _SeparatorChars = new Char[] { ',' };
public DateTime Parse(string text)
{
System.Globalization.CultureInfo _CultureInfo = System.Globalization.CultureInfo.CurrentCulture;
string txt = text.Replace('"', ' ');
string[] columns = txt.Split(_SeparatorChars);
return DateTime.ParseExact(columns[0], "M/dd/yyyy HH:mm:ss:fff", _CultureInfo.DateTimeFormat);
//return DateTime.ParseExact(columns[0], "M/dd/yyyy HH:mm:ss.fff", System.Globalization.CultureInfo.InvariantCulture);
}
}

Try this (Changed d to dd and CultureInfo.InvariantCulture )
DateTime someDateTime = DateTime.ParseExact("3/26/2013 14:37:05:553", "M/dd/yyyy HH:mm:ss:fff", CultureInfo.InvariantCulture);

The issue is with string txt = text.Replace('"', ' ');
This is turning column[0] into [space]3/26/2013 14:37:05:553 instead of 3/26/2013 14:37:05:553 like I'd expect.
Changing this line to string txt = text.Replace(#"""", ""); solves the problem.

Whenever you call ParseExact, make sure you're using an unambiguous format string. In .NET, the / character in a format string is the system date separator, not an actual slash. Same for the : character in times.
To parse a string with your structure, escape out the slashes and colons with backslashes, like:
DateTime.ParseExact(s, #"M\/d\/yyyy HH\:mm\:ss\:fff", null)
// or
DateTime.ParseExact(s, "M\\/d\\/yyyy HH\\:mm\\:ss\\:fff", null)
This will tell the parser that you specifically want the forward-slash and colon, regardless of your system preferences or current culture.

Related

C#: Is this possible to convert 24hrs format string Datetime to 12hrs AM/PM dateformat (again in string only)

I have a date/time return from a C# method is in string,
string dateTime = "2018-6-18 20:50:35"
Now I would like to convert this into another string representation like,
string convertDT = "2018-6-18 08:50:35 PM"
Is this possible?
Seems like I can do something like,
var formattedTime = dateTime.ToString("h:mm tt", CultureInfo.InvariantCulture);
but not working. Suggestion please!
Just parse the string into a new DateTime object and then call ToString() with the right formats:
string dateTime = "2018-6-18 20:50:35";
DateTime parsedDateTime;
if(DateTime.TryParse(dateTime, out parsedDateTime))
{
return parsedDateTime.ToString("yyyy-M-d hh:mm tt");
}
The benefit of my answer is that it contains validation (DateTime.TryParse()), it results in a couple extra lines of code but you can now accept all input and not worry about an exception being thrown.
Even better would be to refactor this logic into its own method that you can re-use:
public static bool TryChangeDateTimeFormat(string inputDateString, string outputFormat, out string outputDateString)
{
DateTime parsedDateTime;
if(DateTime.TryParse(inputDateString, out parsedDateTime))
{
outputDateString = parsedDateTime.ToString(outputFormat);
return true;
}
outputDateString = string.Empty;
return false;
}
This returns a bool of whether or not the conversion was successful and the out variable will be modified depending on the result.
Fiddle here
Without adding any validation,
var string24h = "2018-6-18 20:50:35";
var dateTime = DateTime.Parse(string24h);
var formattedTime = dateTime.ToString("h:mm tt", CultureInfo.InvariantCulture);
Use DateTime.ParseExact and then ToString
Sure, you can use the DateTime class to parse the original string and then output a differently formatted string for the same date:
string result = DateTime.Parse(dateTime).ToString("h:mm tt", CultureInfo.InvariantCulture);
var dateTime = "2018-6-18 20:50:35";
var dt = Convert.ToDateTime(dateTime);
var amPmDateTime = dt.ToString(#"yyyy-MM-dd hh:mm:ss tt", CultureInfo.InvariantCulture);
To give you exactly your format you would use
string convertDT = DateTime.Parse(dateTime).ToString("yyyy-MM-dd hh:mm:ss tt");
You can change the format between the quotes however you would like. For example yyyy/MM/dd or something. Just remember MM is 2 spots for months and mm is 2 spots for minutes.
So if you put
string convertDT = DateTime.Parse(dateTime).ToString("yyyy-mm-dd hh:mm:ss tt");
You are going to get year - minutes - days.

How to get a string[] array into a DateTime?

I'm new to C#.
I have different file names. for example:
C:\Test\ABCD\Warranty_2018_02_12__13_25_13.743.xml
from this name I want to get the date, like 12.02.2018 13:25:13
So the files are never the same.
My code:
public string GetCreationDate(string fileResult)
{
int index = fileResult.IndexOf("_");
if (index != -1)
{
string date = fileResult.Substring(index + 1, 20);
char[] delimiter = new char[] { '_' };
string[] dateWithoutLines = date.Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
Array.Reverse(dateWithoutLines, 0, 3);
//Here is the error
//Guess it's because of the 'ToString()'
DateTime dateTime = DateTime.ParseExact(dateWithoutLines.ToString(), "dd/MM/yyyy hh:mm:ss",
System.Globalization.CultureInfo.InvariantCulture);
return dateTime.ToString();
}
return null;
}
In the debugger I have now 6 strings in the dateWithoutLines with the right dates. like "12" "02" "2018" ...
But then it says that is it not a right DateTime Format there. Okay, but if I delete the
ToString()
It says it can't convert string[] to string. So what is wrong here?
No need to split the original string, reverse, combine and so on.
Let DateTime.TryParseExact do all the work for you:
Also, consider returning a nullable DateTime (DateTime?) instead of a string:
public DateTime? GetCreationDate(string fileResult)
{
int index = fileResult.IndexOf("_");
if (index <= 0)
return null;
// check for string length, you don't want the following call to fileResult.Substring to throw an exception
if (fileResult.Length < index+20)
return null;
string date = fileResult.Substring(index + 1, 20);
DateTime dt;
if (DateTime.TryParseExact(date, "yyyy_MM_dd__HH_mm_ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
return dt;
return null;
}
dateWithoutLines is a string[]. The ToString implementation for string[] yields "System.String[]" which is not a valid date. Furthermore DateTime.Parse does not take a string[], but only a string.
If the date format in the file name is always the same, you can use string.Format
var formattedDate = string.Format("{2}.{1}.{0} {3}:{4}:{5}", dateWithoutLines);
The numbers in the curly braces refer objects in the passed array by index, i.e. that {2} will be replaced by 12 in your example, {1} by 02 and so on. Please note that I've used the indices from the original order, not the reversed array.
Since you're parsing the date to format it, this way, no parsing is needed, since it's already formatted.
object instance dateWithoutLines is an array of strings , not a single string, thus you cant use method ToString().
So I believe you want something in the sense of :
foreach (string date in dateWithoutLines)
{
DateTime dateTime = DateTime.ParseExact(date, "dd/MM/yyyy hh:mm:ss",
System.Globalization.CultureInfo.InvariantCulture);
}
Notice, that since you have an array of strings, date is a string object so there is no need to call ToString() method for each date string instance

Parse date with any separator

I have an object that stores info about its content.
var columnType = new ColumnType
{
ColumnName = "DateTime D/M/Y",
ColType = typeof (DateTime),
Format = "ddMMyyyy HH:mm"
}
Based on that I need to parse rows before adding them to this column. The problem is that my format doesn't include separators. I want to parse the date no matter what separator.
The standard DateTime.Parse doesn't have a constructor with format, and DateTime.ParseExact expects that the specified format already has separators in it.
I need something that will parse date like that:
If my format is ddMMyyyy HH:mm, then:
05.03.2016 04:19 -> parsed
05-03-2016 04:19 -> parsed
05/03/2016 -> parsed (time should be optional)
2016/03/05 04:19 -> error
I tried to do this, but without separators in format it didn't work:
var format = "ddMMyyyy HH:mm";
DateTime.TryParseExact("05.03.2016 04:19", format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime resultValue);
DateTime.Parse works with the samples depending on the IFormatProvider:
var ci = new CultureInfo("pl");
var d1 = DateTime.Parse("05.03.2016 04:19", ci);
var d2 = DateTime.Parse("05-03-2016 04:19", ci);
var d3 = DateTime.Parse("05/03/2016" , ci);
var d4 = DateTime.Parse("2016/03/05 04:19", ci);
Something like this may work for you. This first snippet doesn't deal with optional time, see below.
char[] separators = { '/', '-', '.', '#', '#' };
string format = "dd?MM?yyyy HH:mm"; // ? replaced with each separator
// Create and populate an array of all acceptable formats
string[] formats = new string[separators.Length];
for (int i = 0; i < separators.Length; i++)
{
formats[i] = format.Replace('?', separators[i]);
}
DateTime dt;
if (DateTime.TryParseExact("05#12#2017 15:36", formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
{
// Use dt
}
else
{
// No format matched
}
This works by using DateTime.TryParseExact that accepts a string array of formats, rather than one single format. This works because:
The format of the string representation must match at least one of the specified formats exactly.
It must be noted that all the separators must be the same in the input string, no mix and match.
For optional time you could add other formats that do not include HH:mm. For example:
...
string formatWithTime = "dd?MM?yyyy HH:mm";
string formatWithoutTime = "dd?MM?yyyy";
List<string> f = new List<string>();
foreach (char c in separators)
{
f.Add(formatWithTime.Replace('?', c));
f.Add(formatWithoutTime.Replace('?', c));
}
string[] formats = f.ToArray();
...

DateTime.TryParseExact() is returning false

I have the following code
public static void Main()
{
DateTime D = new DateTime();
D = DateTime.Now;
string s1 = D.ToString("ddMMMMyyyy");
Console.WriteLine(s1);
Console.WriteLine(DateTime.TryParseExact(s1, "ddMMMyyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out D));
Console.ReadKey();
}
Could someone please help me realise the obvious mistake I am making.
I converted DateTime.Now into a string in a custom format and tried to convert it back, but TryParseExact is returning false.
Short answer: MMMM does not equal MMM.
A Sidenote: parsing such strings with CultureInfo.InvariantCulture will only recognize English names, it seems that it will fail on machines with other languages.

How to convert String "MM-DDTHH:mm" to DateTime in c#?

in my code i can get 2 types of string that represents dateTime:
1."2013-09-05T15:55"
2."09-05T19:10"
How do i convert it to a valid DateTime?
i tried the following code but it throws an exception for the second format:
String departureDateStr = "09-05T19:10";
DateTime dt = Convert.ToDateTime(departureDateStr);
how do i convert the second type of string to a valid DateTime ?
do i need some kind of string manipulation?
thx,
Amir
DateTime.TryParseExact has an overload that allows you to pass multiple formats as an array. Each date string is then compared with the various formats within the array so you don't need to know ahead of time which format to look for.
string d1 = "2013-09-05T15:55";
string d2 = "09-05T19:10";
string[] formats = new string[] { "yyyy-MM-ddTHH:mm", "MM-ddTHH:mm" };
List<string> dates = new List<string>() { d1, d2 };
foreach (string date in dates)
{
DateTime dt;
if (DateTime.TryParseExact(date, formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
{
//dt successfully parsed
}
}
TryParseExact also returns false instead of throwing an exception if none of the formats in the array matched the input.
Use DateTime.ParseExact method with custom datetime format string:
string departureDateStr = "09-05T19:10";
string departureDateStr2 = "2013-09-05T19:10";
var dt = DateTime.ParseExact(departureDateStr, "MM-ddTHH:mm", System.Globalization.CultureInfo.InvariantCulture);
var dt2 = DateTime.ParseExact(departureDateStr2, "yyyy-MM-ddTHH:mm", System.Globalization.CultureInfo.InvariantCulture);
or universal call for both formats:
var dt = DateTime.ParseExact(departureDateStr, new[] { "MM-ddTHH:mm", "yyyy-MM-ddTHH:mm" }, System.Globalization.CultureInfo.InvariantCulture);
You can use DatetIme.ParseExact() method for this. It converts the specified string representation of a date and time to its DateTime equivalent using the specified format and culture-specific format information. The format of the string representation must match the specified format exactly.
String departureDateStr = "09-05T19:10";
IFormatProvider provider = System.Globalization.CultureInfo.InvariantCulture;
string format = "MM-ddTHH:mm";
DateTime parsedDate = DateTime.ParseExact(departureDateStr, format, provider);
If you need this conversion a lot of times, then you can even make it an extension method as below:
public static class StringExtensions
{
public static DateTime ToDate(this string str)
{
IFormatProvider provider = System.Globalization.CultureInfo.InvariantCulture;
string format = "MM-ddTHH:mm";
return DateTime.ParseExact(str, format, provider);
}
}

Categories

Resources