I have the following code which takes the element in the lines array and checks if it matches the datetime format. This check only runs on elements 37, 38, 40, 41. Given the following code and debugging print outs I can see that the output does match the parsing. Why does it return false then?
Possible Inputs:
05/03/2005 23:59:59.999
05/3/2005 23:59:59.999
5/03/2005 23:59:59.999
5/3/2005 23:59:59.999
etc...
Code:
lines[i] = lines[i] + " 23:59:59.999"; //YYYY-MM-DDThh:mm:ss[.mmm]
DateTime datetest;
if (DateTime.TryParseExact(lines[i], "MM/dd/yyyy HH:mm:ss.mmm", new CultureInfo("en-US"), DateTimeStyles.None, out datetest))
{
}
else
{
//Log and Drop
logfile.WriteLine(System.DateTime.Now.ToString("yyyy.MM.dd.HH.mm.ss") + ": Row #" + row + ", Column #" + (i) + " was not a date in the right format, dropping line. ");
logfile.WriteLine("Original: " + lines[i]);
Console.WriteLine("Date Wrong");
Console.WriteLine("Date: " + lines[i]);
string input = Console.ReadLine();
continue;
}
Console Output:
Date Wrong
Date: 5/23/2004 23:59:59.999
UPDATE:
I tried changing the parse to look for M/dd/yyyy instead. However I now get this output instead.
Date Wrong
Date: 05/23/2005 23:59:59.999
UPDATE 2:
Ok I tried changing the parse to look for "M/d/yyyy HH:mm:ss.fff" as many suggested. The output I get now is:
Date Wrong
Date: 23.59.59.999
UPDATE 3:
Ok I have now tried "M/d/y H:m:s.fff" as suggested and I am still getting output as:
Date Wrong
Date: 05/23/2005 23:59:59.999
Note: Answer based on original revision of the question before it started morphing.
Why does it return false then?
The MM format requires two digits for the month. Your date string only has one digit. Use the M month format. The milliseconds format string should be fff rather than mmm.
The following format string will parse your input
M/dd/yyyy HH:mm:ss.fff
To demonstrate:
DateTime datetest;
Console.WriteLine(DateTime.TryParseExact("5/23/2004 23:59:59.999",
"M/dd/yyyy HH:mm:ss.fff", new CultureInfo("en-US"), DateTimeStyles.None,
out datetest));
which outputs
True
If you wish to allow for single digit months then you need d instead of dd. In order for you to proceed much further, you will need to work out exactly what format of dates you wish to support.
You have the wrong datetime format that you try to parse to. Change it to: "M/dd/yyyy HH:mm:ss.fff"
In response to the comment:
DateTime datetest;
var dateTimes = new [] { "05/03/2005 23:59:59.999", "05/3/2005 23:59:59.999", "5/03/2005 23:59:59.999", "5/3/2005 23:59:59.999" };
foreach(var dateTimeToParse in dateTimes)
if (DateTime.TryParse("5/3/2005 23:59:59.999", new CultureInfo("en-US"), DateTimeStyles.None, out datetest))
Console.WriteLine(dateTimeToParse + " parses to: " + datetest);
else
Console.WriteLine("FAIL!");
Works on my machine:
05/03/2005 23:59:59.999 parses to: 2005-05-03 23:59:59
05/3/2005 23:59:59.999 parses to: 2005-05-03 23:59:59
5/03/2005 23:59:59.999 parses to: 2005-05-03 23:59:59
5/3/2005 23:59:59.999 parses to: 2005-05-03 23:59:59
I can't see the contents of lines[I], but the mismatch between the format described in the comment and the format used in the TryParse may just be your issue:
lines[i] = lines[i] + " 23:59:59.999"; //YYYY-MM-DDThh:mm:ss[.mmm]
...
if (DateTime.TryParseExact(lines[i], "MM/dd/yyyy HH:mm:ss.mmm",
Using this (like already suggested Hans and David):
class Program
{
static void Main(string[] args)
{
List<String> datetimeList = new List<string>();
datetimeList.Add("05/03/2005 23:59:59.999");
datetimeList.Add("05/3/2005 23:59:59.999");
datetimeList.Add("5/03/2005 23:59:59.999");
datetimeList.Add("5/3/2005 23:59:59.999");
DateTime datetest;
foreach (string s in datetimeList)
{
if (!DateTime.TryParseExact(s, "M/d/yyyy HH:mm:ss.fff", new CultureInfo("en-US"), DateTimeStyles.None, out datetest))
{
Console.WriteLine("Error");
}
else
{
Console.WriteLine("Success");
}
}
Console.Read();
}
}
prints 4 times "Success" .
This only a proof of concept, i don't want any upvotes.
Related
I have this date: " 1 21998", which is Feb, 1st 1998. It's a little bit malformed as there should be zeros instead of spaces, but it's in some text files I have to process. I don't know how to parse it with C#. Could anyone give me a clue?
I've tried the following but get no result:
DateTime date;
string input = " 1 21998";
if (DateTime.TryParseExact(input, "ddMMyyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out date))
{
Console.WriteLine("1: " + date);
}
else if (DateTime.TryParseExact(input, "ddMMyyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out date))
{
Console.WriteLine("2: " + date);
}
else if (DateTime.TryParseExact(input, "dMyyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out date))
{
Console.WriteLine("3: " + date);
}
else if (DateTime.TryParseExact(input, "dMyyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out date))
{
Console.WriteLine("4: " + date);
}
else if (DateTime.TryParseExact(input, " d Myyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out date))
{
Console.WriteLine("5: " + date);
}
else if (DateTime.TryParseExact(input, " d Myyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out date))
{
Console.WriteLine("6: " + date);
}
if (DateTime.TryParse(input, out date))
{
Console.WriteLine("7: " + date);
}
else if (DateTime.TryParse(input, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out date))
{
Console.WriteLine("8: " + date);
}
The pattern " d Myyyy" is correct for the input " 1 21998"; it's just that the parser throws its hands in the air for a variable-length concatenation.
I haven't looked at the source, but I guess the parser first tries to break up the string into individual components matching the pattern, before trying to parse the actual values.
So the parser wouldn't know whether the first one or the first two digits of your five-digit string "21998" belong to the month, even though there is no 21st month and you specified that the year will have four digits.
It works if you prepend a zero or one to the month:
" 1 021998" -> 02/01/1998
" 1 121998" -> 12/01/1998
The docs say, under "Remarks":
If format is a custom format pattern that does not include date or time separators (such as "yyyyMMddHHmm"), use the invariant culture for the provider parameter and the widest form of each custom format specifier. For example, if you want to specify hours in the format pattern, specify the wider form, "HH", instead of the narrower form, "H".
Not sure what that is about, but " dd MMyyyy" nor "ddMMyyyy" work for the original input. I guess they meant that you should write dates using their widest forms when not writing separators.
The problem isn't the spaces; it's lack thereof. These work:
"dMyyyy", " 1 2 1998" (with DateTimeStyles.AllowWhiteSpaces)
"ddMMyyyy", "01021998" (with DateTimeStyles.None)
" dd MM yyyy", " 01 02 1998" (with DateTimeStyles.None)
Given your input is fixed-length, the pattern will break again if the month is > 9 (" 1102021" won't parse either for the same reasons as before).
The easiest solution would be to parse it manually by breaking up the strings, parsing them as ints and passing them to a new DateTime(year, month, day).
var day = int.Parse(input[0..2], NumberStyles.AllowLeadingWhite);
var month = int.Parse(input[2..4], NumberStyles.AllowLeadingWhite);
var year = int.Parse(input[4..8], NumberStyles.AllowLeadingWhite);
var date = new DateTime(year, month, day);
Can you not turn all the spaces in the input into 0's and then it should be a valid date format?
input.Replace(" ", "0");
Might also want to put /'s after the 2nd and 4th index too.
input.Insert(2, "/");
I am getting my date time in a format like "20170317 630"
which means 17 March 2017 6:30 am
Here is the code block I am trying, but it is failing.
var str = "20170317 0630";
var formatedTime = "yyyyMMdd Hmm";
DateTime etaDate;
if (!DateTime.TryParseExact(str,formatedTime, CultureInfo.InvariantCulture, DateTimeStyles.None, out etaDate)) //formatedTime, CultureInfo.InvariantCulture, DateTimeStyles.None
{
Console.WriteLine("Date conversion failed " + etaDate);
}
Console.WriteLine("Date conversion passed "+etaDate);
Passing for: 20170317 0630
Failing for: 20170317 630
Please help me with this.
I'm not entirely surprised it's failing to parse that - I suspect it's greedily parsing the "63" and deeming that to be an invalid hour number.
We have exactly the same problem in Noda Time - and I don't intend to fix it. Making this work would be a huge amount of effort, and quite possibly reduce the performance for more sensible formats.
I would strongly suggest moving to a more sensible format, e.g. one of
H:mm to remove the pseudo-ambiguity
HHmm to make it all clearer
HH:mm even better, IMO - preferrably with hyphens for date parts, so yyyy-MM-dd HH:mm
You can convert from one format to another by simply detecting the length of the string, as every other part of it is a fixed length. For example, to just move to using HHmm you can do:
if (str.Length == "yyyyMMdd Hmm".Length)
{
str = str.Insert("yyyyMMdd ".Length, "0");
}
Then parse with yyyyMMdd HHmm format. If the length isn't right for either valid width, then it will fail to parse later anyway.
//split str in to strDate and strTime by using space
var strDate = "20170317"; //Date part
var strTime ="630"; //Time part
if(strTime.Length ==3) //check lenght of time part
{
strTime = "0" + strTime; //Add extra zero
}
var formatedTime = "yyyyMMdd HHmm";
DateTime etaDate;
if (!DateTime.TryParseExact(strDate + strTime,formatedTime, CultureInfo.InvariantCulture, DateTimeStyles.None, out etaDate)) //formatedTime, CultureInfo.InvariantCulture, DateTimeStyles.None
{
Console.WriteLine("Date conversion failed " + etaDate);
}
Console.WriteLine("Date conversion passed "+etaDate);
I am trying to convert string to DateTime. Code look as follows:
DateTime.Parse("20131101T210705.282Z").ToShortTimeString()
I am getting format exception.
I tried providing following format "yyyyMMddTssmmhh.fffz" but received same exception. Code looked as follows
DateTime dt;
if (DateTime.TryParseExact("20131101T210705.282Z",
"yyyyMMddTssmmhh.fffz",
new CultureInfo("en-US"),
DateTimeStyles.None,
out dt))
return dt.ToShortTimeString();
In this case code doesn't parse the string.
Try this :
DateTime dt;
if (DateTime.TryParseExact("20131101T210705.282Z",
"yyyyMMddTssmmhh.fffZ",
new CultureInfo("en-US"),
DateTimeStyles.None,
out dt))
return dt.ToShortDateString() + " " + dt.ToShortTimeString();
This might be one way to parse.
var timeStamp = "20131101T210705.282Z";
var datetime = timeStamp.Split(new[] { 'T' ,'.'});
DateTime dt1;
if (DateTime.TryParseExact(datetime[0],
new string[] { "yyyyMMdd" },
new CultureInfo("en-US"),
DateTimeStyles.None,
out dt1))
{
Console.WriteLine(dt1.ToShortDateString());
}
DateTime dt2;
if (DateTime.TryParseExact(datetime[1],
new string[] { "ssmmhh" },
new CultureInfo("en-US"),
DateTimeStyles.None,
out dt2))
{
Console.WriteLine(dt2.ToShortTimeString());
}
Console.WriteLine(dt1.ToShortDateString() + " " + dt2.ToShortTimeString());
Console.ReadLine();
The format was simply incorrect. The timestamp value given doesn't clearly indicate where the hours are since all values (hours, minutes, and seconds) are less than 24. The following code works correctly.
DateTime.TryParseExact(value,
"yyyyMMddTHHmmss.fffZ",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out dt)
Given this proprietary format, the hours are in 24 hour format and come first. A test from this morning yielded the following value: 20131106T162733.032Z. I am able to test this proprietary format because we work for the same company. :)
Im Getting System.datetime.now from different Machine .Each system having different datetime format as a mension below
16-Oct-12 7:25:22 PM
16/10/2012 7:10:47 PM [DD/MM/YYYY]
10/16/2012 7:10:51 PM [MM/DD/YYYY]
How To convert Different format of DateTime to specific String format ?
string sDateTime = DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt");
First result of Google search: Custom datetime format strings from MSDN
You have to use the line of code you provided explicitly on the other machines when returning the datetime:
string sDateTime = DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt");]
This is however not aware of time zones! If your application spans several time zones, you should take that into count too!
Or, even better, you could return the Unix time (milliseconds from 1970-01-01) as a long, and of course the timezone info too, if that is different across the machines... (Beware, .NET expoch time is from 0001-01-01 though!)
Returning Epoch time
I would recommend against using tryParse: You can not reliably determine if a date is in [DD/MM/YYYY] or [MM/DD/YYYY], only when the month of day is greater than 12... And this would lead to mysterious errors. Believe me, been there, done that (the debugging part)...
try the TryParse methode of the Datetime class
Examples from the link:
string[] dateStrings = {"05/01/2009 14:57:32.8", "2009-05-01 14:57:32.8",
"2009-05-01T14:57:32.8375298-04:00",
"5/01/2008 14:57:32.80 -07:00",
"1 May 2008 2:57:32.8 PM", "16-05-2009 1:00:32 PM",
"Fri, 15 May 2009 20:10:57 GMT" };
DateTime dateValue;
Console.WriteLine("Attempting to parse strings using {0} culture.",
CultureInfo.CurrentCulture.Name);
foreach (string dateString in dateStrings)
{
if (DateTime.TryParse(dateString, out dateValue))
Console.WriteLine(" Converted '{0}' to {1} ({2}).", dateString,
dateValue, dateValue.Kind);
else
Console.WriteLine(" Unable to parse '{0}'.", dateString);
}
Notice that in the example its not working for all given strings dates
The problem of your example is the last two formats 16/10/2012 7:10:47 PM [DD/MM/YYYY] and 10/16/2012 7:10:51 PM [MM/DD/YYYY]. If the value is 10/11/2012 7:20:10 PM how can you know that it is Oct 11, 2012 or Nov 10, 2012?
var input = new string []{ "16-Oct-12 7:25:22 PM",
"16/10/2012 7:10:47 PM",
"10/16/2012 7:10:51 PM"};
foreach (var date in input)
{
var result = DateTime.MinValue;
if (DateTime.TryParse(date, out result))
{
Console.WriteLine("Date value: {0}", result);
}
else
{
Console.WriteLine("Cannot parse value {0}", date);
}
}
As you can see, "16/10/2012 7:10:47 PM" could not be parse.
if (DateTime.TryParse(DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss tt"), out result))
sDateTime = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss tt");
else
{
if (System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern.Equals("dd-MMM-yy")) sDateTime = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss tt");
else sDateTime = DateTime.Now.Month +"/" + DateTime.Now.Day+ "/" + DateTime.Now.Year + " " + DateTime.Now.ToString("hh:mm:ss tt");
}
I have a custom DateTime format string: "M/d/yyyy h:m:ss tt".
For example, with the date 'September 18th, 2012 # noon', I expect the output of this to be something like "9/18/2012 12:0:00 PM".
The time seems to be formatting properly, but the date portion is getting messed up. I am seeing the dates formatted as "MM-dd-yyyy" and I can't figure out why.
Here is some sample code to reproduce the problem:
var datetime = DateTime.Now;
Console.WriteLine("Date: " + datetime.ToString("MMMM d, yyyy")); // Date: October 11, 2012 --> correct
Console.WriteLine("Date: " + datetime.ToString("M/d/yyyy h:m:ss tt")); // Date: 10-11-2012 4:34:17 PM --> wrong
Here is the MSDN doc for custom DateTime format strings.
Any ideas on what am I doing wrong? How can I achieve my desired result?
Edit:
The thing that is incorrect in the last line of sample code is that there is hyphens instead of slashes and I don't know why.
Also, my computer's language is set to English (Canada). But neither my "short" nor "long" date format look like M-d-yyyy so I have no idea where that is coming from.
/ is the date separator, that is culture-dependant - in your current culture it is defined as -. If you want always a / use:
Console.WriteLine("Date: " + datetime.ToString("M\"/\"d\"/\"yyyy h:m:ss tt"));
or
Console.WriteLine("Date: " + datetime.ToString("M'/'d'/'yyyy h:m:ss tt"));
i.e. put the parts that you want to be output 'as is' inside quotes.
Try:
datetime.ToString("M/d/yyyy h:m:ss tt", CultureInfo.InvariantCulture);
Your culture might be overriding your date separator.
This article explains how the current culture can change the output of DateTime.ToString(string). Read the section that contains this text:
This method uses formatting information derived from the current
culture
This article explains how to get/set the culture so that you can test this possibility.
This article explains how you can explicitly provide DateTime.ToString with a culture to use.
Try the adding the invariant culture, Using the InvariantCulture Property
Console.WriteLine("Date: " + datetime.ToString("M/d/yyyy h:m:ss tt", CultureInfo.InvariantCulture));
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
var datetime = DateTime.Now;
Console.WriteLine("Date: " + datetime.ToString("MMMM d, yyyy"));
// Date: October 11, 2012 --> correct
Console.WriteLine("Date: " + datetime.ToString("M/d/yyyy h:m:ss tt"));