I need parse datetimeoffsets from strings of multiple formats. One of the strings that fail is:
08/12/1992 07.00.00 -05:00
Now when I try to parse this, I use:
DateTimeOffset.ParseExact("08/12/1992 07.00.00 -05:00", "dd/MM/yyyy HH:mm:ss zzz", CultureInfo.InvariantCulture)
Which gives a FormatException:
"String was not recognized as a valid DateTime."
I can also try to add delimiters in the separators:
DateTimeOffset.ParseExact("08/12/1992 07.00.00 -05:00", "dd'/'MM'/'yyyy HH':'mm':'ss zzz", CultureInfo.InvariantCulture)
...or other permutations of small/capital letter or separators, but I get the same error.
Can anyone tell me why the ParseExact lines above do not work, and how to correct them?
EDIT: I tried using a LINQ query to replace the colon with dots (: -> .). Apparently that did not work correctly - thanks for the replies.
Your actual date (actually time) string delimits the hours from the minutes from the seconds with a dot ., so your format must do the same:
DateTimeOffset.ParseExact("08/12/1992 07.00.00 -05:00",
"dd/MM/yyyy HH.mm.ss zzz", CultureInfo.InvariantCulture)
// ^ ^
// | |
If you have multiple string formats in your data, you can do something like this:
public static DateTimeOffset Parse(string str)
{
string[] formats =
{
"dd/MM/yyyy HH.mm.ss zzz",
"dd/MM/yyyy HH:mm:ss zzz"
// ... possibly more ...
};
var dto = new DateTimeOffset();
if (!formats.Any(f => DateTimeOffset.TryParseExact(str, f, CultureInfo.InvariantCulture, DateTimeStyles.None, out dto)))
{
throw new ArgumentException("Unrecognized date format");
}
return dto;
}
In the statement
DateTimeOffset.ParseExact("08/12/1992 07.00.00 -05:00",
"dd/MM/yyyy HH:mm:ss zzz",
CultureInfo.InvariantCulture)
the format string uses : as separator for the time parts, but the data argument uses . as separator.
Related
I have a list of DateTime as strings: dd.MM.yyyy H:mm:ss (The time is 24 hours format but the hour is single digit: 6 instead of 06)
14.12.2016 6:20:21
15.12.2016 8:30:00
16.12.2016 12:30:00
17.12.2016 14:33:00
18.12.2016 18:10:00
I am trying to parse exact the string values as a DateTime object like this:
DateTime.ParseExact(dt, "dd.MM.yyyy H:mm:ss", CultureInfo.InvariantCulture) (dt is the string value from the list)
The problem is I get an error saying the string is not a valid DateTime ...
With the current format, the first and second values in the list work fine, when it get's to the third 'boooom' I get the error.
Am I missing something in my format?
Use the overload of DateTime.ParseExact that accepts an array of valid formats:
string[] formats = { "dd.MM.yyyy H:mm:ss", "dd.MM.yyyy HH:mm:ss" };
var result = DateTime.ParseExact(dt, formats, CultureInfo.InvariantCulture, 0);
UPDATE: As others have noted, H should match both one-digit and two-digit hours, so something else is going on. The following code runs successfully on my system (.NET 4.5.2):
string dt = "16.12.2016 12:30:00";
var result = DateTime.ParseExact(dt, "dd.MM.yyyy H:mm:ss", CultureInfo.InvariantCulture);
I had to parse exact the using Hour, Minute, and Second then use the ToString method to convert to a Month, day, and year format
$myStringDate=[Datetime]::ParseExact($item.myDateObject,'MM/dd/yyyy H:mm:ss',$null).ToString('MM/dd/yyyy')
I have following strings in different formats:
16/05/2014
21-Jun-2014
2014-05-16
16-05-2014
5/19/2014
14 May 2014
I need to convert all the above strings into mm/dd/yyyy format in c#.
I have tried used DateTime.ParseExact as DateTime dt = DateTime.ParseExact("16-05-2014", "mm/dd/yyyy hh:mm:ss tt", CultureInfo.InvariantCulture) in C# but i am getting the exception as "String was not recognized as a valid DateTime".
I have also tried to use to Convert.ToDateTime() but it is also not working.
Is there any method or function that we can write/available in C# that would convert the above string formats into a single date format i.e into "mm/dd/yyyy" format ??
Any help on this would be greatly appreciated.
It fails on the very first term of your format string, which is telling the function to treat the "16" as minutes and to look for hours, minutes, and seconds that don't exist in the input.
You have several different date formats, and so need the ParseExact() overload that accepts several different format strings:
string[] formats= {"dd/MM/yyyy", "dd-MMM-yyyy", "yyyy-MM-dd",
"dd-MM-yyyy", "M/d/yyyy", "dd MMM yyyy"};
string converted = DateTime.ParseExact("16-05-2014", formats, CultureInfo.InvariantCulture, DateTimeStyles.None).ToString("MM/dd/yyyy");
Also remember that lower case "m"s are for minutes. If you want months, you need an upper case "M". Full documentation on format strings is here:
http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
Finally, I suspect you are getting ahead of yourself on formatting the output as a string. Keep these values as DateTime objects for as long as possible, and only format to a string at the last possible moment before showing them to the user. If you really do want a string, at least stick with the ISO 8601 standard format.
Your main problem is that your format string is wrong. A small m is for minute, a big M is for month.
Try to pass all your formats in an array. For example like this
DateTime.ParseExact("16-05-2014",
new[] {"dd/MM/yyyy", "dd-MMM-yyyy", "yyyy-MM-dd",
"dd-MM-yyyy", "M/d/yyyy", "dd MMM yyyy"},
CultureInfo.InvariantCulture, DateTimeStyles.None);
With this you can parse all your formats at once.
For more information about the format settings, see the official docs.
Few things:
Your input date 16/05/2014 doesn't match your format Month/Day/Year - how can there be a 16th month?
Secondly, you're using mm which represents Minutes, not Months. You should use MM.
Finally, your sample string 16-05-2014 doesn't match the format provided, you've used hyphens - instead of forward slashes /
Supply a collection of different formats matching your input:
string[] formats = new [] { "MM/dd/yyyy", "dd-MMM-yyyy",
"yyyy-MM-dd", "dd-MM-yyyy", "dd MMM yyyy" };
DateTime dt = DateTime.ParseExact("05-16-2014", formats, CultureInfo.InvariantCulture, DateTimeStyles.None);
You might find the following method useful to accept whatever date format you want and convert it to DateTime:
public DateTime? DTNullable(string DateTimestring, string CurrDateTimeFormat)
{
if (string.IsNullOrEmpty(DateTimestring)) return null;
else
{
DateTime datetimeNotNull;
DateTime.TryParseExact(DateTimestring, CurrDateTimeFormat, null, System.Globalization.DateTimeStyles.None, out datetimeNotNull);
return datetimeNotNull;
}
}
Pass in your desired string to be converted to DateTime along with it's current date time format and this would return you a nullable DateTime. If you're certain that whatever string you're passing in won't be null then you can remove that bit. The reason for it being there is that you can't convert a null to DateTime. In my case I couldn't be certain if it would be or not so I needed the ability to capture nulls as well.
You can use it like this:
DateTime? MyDateTime = DTNullable(MyStartDate, "dd/MM/yyyy");
If you wanted you could alter the method to accept an array of strings and simply iterate through each and return them all in a list if they were of the same format.
As others have pointed out, months are MM not mm (minutes).
On a DateTime object you can call .ToString("MM/dd/yyyy"). Given the strings you have, you can first create new DateTime objects for each string and then call .ToString("MM/dd/yyyy"). For example:
var dateAsMmDdYyyy = DateTime.Now.ToString("MM/dd/yyyy");
How can I convert this datetime format from a webservice? The datetime value is: "timestamp": "2014-04-18T14:45:00+02:00"
I wan't to convert it to: dd.mm.YYYY hh.mm.ss
You need to use "yyyy-MM-dd'T'HH:mm:ssK" format with InvariantCulture using DateTime.ParseExact method like;
string s = "2014-04-18T14:45:00+02:00";
var date = DateTime.ParseExact(s, "yyyy-MM-dd'T'HH:mm:ssK",
CultureInfo.InvariantCulture);
Take a look at The "K" Custom Format Specifier
Then you can get string representation of your DateTime with DateTime.ToString() method. DateTime has no inherent format, it has just a value. You can get string representation for formatting.
date.ToString("dd.MM.yyyy HH.mm.ss", CultureInfo.InvariantCulture);
//18.04.2014 03.45.00
Here a demonstration.
Remember, mm is for minutes, MM for months. And hh is for 12-hour clock which is 01 to 12. But HH is 24-hour clock which is 00 to 23.
That's why you can't parse 14 with hh specifier. I assume your real representation format is dd.MM.yyyy HH.mm.ss
EDIT: After your comment, you can use "MM/dd/yyyy HH:mm:ss" format like;
string s = "04/18/2014 14:45:00";
var date = DateTime.ParseExact(s, "MM/dd/yyyy HH:mm:ss",
CultureInfo.InvariantCulture);
Console.WriteLine(date); // 18/04/2014 14:45:00
Use DateTime.ParseExact(string, string, IFormatProvider) or DateTime.TryParseExact(string, string, IFormatProvider, DateTimeStyles, out DateTime).
DateTime.ParseExact()
DateTime.TryParseExact()
With a regex you can do the following:
string resultString = null;
try {
resultString = Regex.Replace(subjectString, #"(\d{4})-(\d{2})-(\d{2})\w{1}(\d{2}):(\d{2}):(\d{2})\+\d{2}:\d{2}", "$3.$2.$1 $4.$5.$6", RegexOptions.IgnoreCase);
} catch (ArgumentException ex) {
// Syntax error in the regular expression
}
//18.04.2014 14.45.00
string date = "2014-04-18T14:45:00+02:00";
var results = DateTime.ParseExact(s, "yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
Given the following 2 strings notice the ".185" and ",185"
2011-09-15 17:05:37,185
2011-09-15 17:05:37.185
Reading from a file (not in my control) and I can see they have dates in both formats. I need to create a function that cater for both scenarios.
Is the '.' and ',' a culture specific?
Any suggestion for such a function?
This below is not working as I don't get a date.
class Program
{
static void Main(string[] args)
{
string date1="2011-09-15 17:05:37.185";
string date2="2011-09-15 17:05:37,185";
const string format1 = "dd/MM/yyyy HH:mm:ss.ff";
const string format2 = "dd/MM/yyyy HH:mm:ss,ff";
DateTime resultDate1;
DateTime resultDate2;
DateTime.TryParseExact(date1, format1, CultureInfo.InvariantCulture, DateTimeStyles.None, out resultDate1);
DateTime.TryParseExact(date2, format2, CultureInfo.InvariantCulture, DateTimeStyles.None, out resultDate2);
Console.WriteLine(resultDate1.ToString());
Console.WriteLine(resultDate2.ToString());
Console.Read();
}
}
Is the . and , a culture specific?
Yes. In Europe, a comma is often used instead of a period as the decimal separator.
Any suggestion for a solution?
Yes. My first thought is that the DateTime.ParseExact()/DateTime.TryParseExact() functions have an overload that allows an array of formats to test. You could include both the en-US variant and the en-GB variant. Except that I don't think this will work, as you still only get to include a single culture specifier. So instead, I recommend calling .Replace() before passing the string to ParseExact function to change any commas that might be in the string to periods.
In your updated example code, your format string just doesn't match your example dates. You should use this:
yyyy-MM-dd HH:mm:ss.fff
You should use DateTime.ParseExact or .TryParseExact as suggested in Hans Passant's comment.
DateTime d1;
string[] formats = new [] { "yyyy-MM-dd HH:mm:ss.fff", "yyyy-MM-dd HH:mm:ss,fff" };
DateTime.TryParseExact(s1, formats, CultureInfo.InvariantCulture,
DateTimeStyles.None, out d1);
You should also specify CultureInfo.InvariantCulture, as otherwise the ParseExact method may use a culture-specific date separator (in place of /, e.g. "." in Germany) or time separator (in place of ":").
I want to parse the date from the string where date formate can be any of different format.
Now to match date we can use DateTime.TryParseExact and we can define format as we needed and date will be matched for any different format.
string[] formats = {"MMM dd yyyy"};
DateTime dateValue;
string dateString = "May 26 2008";
if (DateTime.TryParseExact(dateString, formats,
new CultureInfo("en-US"),
DateTimeStyles.None,
out dateValue))
MessageBox.Show(dateValue.ToString());
This matches with date.But this is not working for parse the date from the string that is it does not matched with the date which is in some string.
Like
if the date is "May 26 2008" then we can define format "MMM dd yyyy" and date will be matched.
But if date is in some string like "Abc May 26 2008" then date will not be matched.So for that can we use regular expression here ? If yes how ?
The string from I want to parse the date, is parsed from the html page and the string can be any different.
EDIT : I want to write the format like which matches any string in which there is a date using regex.
You could do a regular expression match on something like #"[A-Za-z]{3} \d{2} \d{4}" and feed whatever matches into DateTime.TryParseExact. It might break for alternate cultures however, I'm not sure if there are languages around that have month names only 2 letters short or something :)
Alternatively, you could extract the month names from cultureInfo.DateTimeFormat.AbbreviatedMonthNames and use that to build a slightly better targeted regular expression. It should also work for other cultures.
Edit - here's an example:
string text = "Apr 03 2010 foo May 27 2008 bar";
CultureInfo ci = new CultureInfo("en-US");
Regex regex = new Regex(#"(?<date>(" + String.Join("|",
ci.DateTimeFormat.AbbreviatedMonthNames, 0, 12) + #") \d{2} \d{4})");
// Builds this regex:
// (?<date>(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{2} \d{4})
var matches = regex.Matches(text);
foreach (Match match in matches)
{
string capturedText = match.Groups["date"].Value;
DateTime dt;
if (DateTime.TryParseExact(capturedText, "MMM dd yyyy", ci,
DateTimeStyles.None, out dt))
{
Console.WriteLine(capturedText + ": " + dt.ToLongDateString());
}
}
// Prints two parsed dates in long format
If it's English only and the format is "MMM dd yyyy" you can search where your string is [January|February|...|December] day year.
But you should first ask yourself why you're parsing any string. Can you not force the user to use a predefined format and validate that input?
You can customize the format according to your needs:
private const string DateTimeFormat = "dd-MMM-yy hh.mm.ss.ffffff tt";
public static bool TryParseToDateTime(this string stringValue, out DateTime result)
{
if (String.IsNullOrEmpty(stringValue))
{
result = DateTime.MinValue;
return false;
}
return DateTime.TryParseExact(stringValue, DateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out result);
}
UPDATE:
You probably should use regular expressions to find strings that match date in text. You have to decide what date format you expect and write (or choose) an appropriate regular expression. For example, for "dd MMM yyyy" format you can use the following regular expressions:
^\d{2}\s{1}(Jan|Feb|Mar|Apr|May|Jun|Jul|Apr|Sep|Oct|Nov|Dec)\s{1}\d{4}$
by Stephen Lam from http://regexlib.com/REDetails.aspx?regexp_id=325
Alternatively you can browse this site to find appropriate expression.
If you know your date will start with a month then you can use substring to get that part. (Find occurence of Jan/Feb/ etc)
I think something like \w{3,8} \d\d \d\d\d\d[\s$] would work most of the time if it's in US format, but I wouldn't trust it too much if the text you're parsing could be just anything.
Here is the link to parse the date from the string which is very good.There is set of regex to parse the date from the string.
http://www.codeproject.com/KB/datetime/date_time_parser_cs.aspx