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();
...
Related
I would like to format a string based on a list of possible input formats. So for the string "2010/02/20" I would expect it to pass the first format in arr which is yyyy/MM/dd and be formatted using the first format in arr.
When I pass "20/02/2010" as strDate , it should be formatted using the second format in arr. But I got string was not recognized as valid date time.
string strDate = "2010/02/20";
//string strDate = "20/02/2010";
string[] arr = { "yyyy/MM/dd, dd/MM/yyyy"};
DateTime dt = DateTime.ParseExact(strDate, arr, new CultureInfo("en-US"),
DateTimeStyles.None);
You are defining your arr wrong. Currently, you only have one valid format which is
yyyy/MM/dd, dd/MM/yyyy
So a valid date must literally have the following format (all 22 characters of it)
"2020/02/20, 02/20/2020"
To have two values in your array, define it as follows
var arr = new string[]{"yyyy/MM/dd", "dd/MM/yyyy"};
Current culture of my application is set to Spanish but i need to convert my date to English in order to perform database operations.
currently date is coming in this format: "Dic 13, 2017"
I need to convert this to : "Dec 13, 2017"
what i have tried until now
var input = objDMSampleA.RequestDateFrom;
var format = "MMM dd, yyyy";
var dt = DateTime.ParseExact(input, format, new CultureInfo("es-ES"));
var result = dt.ToString(format, new CultureInfo("en-US"));
but the ParseExact gives error that
String was not recognized as a valid DateTime.
"Short" month names for given culture are stored in CultureInfo.DateTimeFormat.AbbreviatedMonthNames. For es-ES culture those names might have dot in the end (for example: "dic." instead of "dic"). For that reason, parsing your string fails - "Dic" doesn't have that dot.
To fix this, one way is to modify those names:
var esCulture = new CultureInfo("es-ES");
var monthNames = esCulture.DateTimeFormat.AbbreviatedMonthNames;
for (int i = 0; i < monthNames.Length; i++) {
monthNames[i] = monthNames[i].TrimEnd('.');
}
esCulture.DateTimeFormat.AbbreviatedMonthNames = monthNames;
monthNames = esCulture.DateTimeFormat.AbbreviatedMonthGenitiveNames;
for (int i = 0; i < monthNames.Length; i++)
{
monthNames[i] = monthNames[i].TrimEnd('.');
}
esCulture.DateTimeFormat.AbbreviatedMonthGenitiveNames = monthNames;
Then your code will work as expected:
var input = "Dic 13, 2017";
var format = "MMM dd, yyyy";
var dt = DateTime.ParseExact(input, format, esCulture);
var result = dt.ToString(format, new CultureInfo("en-US"));
It's better to store modified culture in some static field and reuse it, instead of creating it and changing every time.
If you want to modify current culture for all threads, use
CultureInfo.DefaultThreadCurrentCulture = esCulture;
though I won't recommend doing that.
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
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);
}
}
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.