C# device input on date format - c#

I am reading an input from a device on a comm port, that is a date in the following format "dd/MM/yyyy hh:mm" to a string value. I am trying to format the date to show "ddMMyyyy hh:mm:ss". I have tried the following but get the error below code:
(input value is "31/08/2018 02:32")
public string ParseLine(string Line)
{
var input = Line.Split(',');
var dateTime = DateTime.Parse (input[0]);
var Action = input[1] == "1" ? "ONL" : "OFL";
var readerAddr = input[1] == "1" ? "S" : "T";
var TagType = input[2];
var TagNum = input[3].Substring(TagType.Length);
return $"{Action},{TagNum},{readerAddr},{dateTime:ddMMyyyy hh:mm:ss}";
}
Any advise will be appreciated?

Use DateTime.TryParseExact to check if 'input[0]' has a valid datetime value. Example:
public string ParseLine(string Line)
{
...
if(!DateTime.TryParseExact(input[0], "ddMMyyyy hh:mm:ss", CultureInfo.CurrentCulture, DateTimeStyles.None, out var result))
{
//Is not a valid date :C
}
Console.WriteLine("Valid date: " + result);
}

In case date time would be in some weird format, you will need to use DateTime.ParseExact(..) method like this:
var dateTime = DateTime.ParseExact(input[0], "dd/MM/yyyy hh:mm");
However, your format is one of the accepted ISO formats, so it should work like you wrote down. The best reason why is does not work is that the value of input[0] is not what you expect, so at first check what this variable actually contains.

Thanks to everyone's comments and advise I managed to get it right by using these two methods:
var dateTime = DateTime.ParseExact(input[0], "dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture);
and
return $"{Action},{TagNum},{readerAddr},{dateTime:ddMMyyyy HH:mm:ss}";

Related

Use DateTime.TryParseExact to format date string and ignore time

I want to parse string date to DateTime but ignoring time.
My expected date format is M/d/yyyy which is 3/29/2018 (without leading zero).
The thing is string can be with or without time part and time can have different formats that I will not predict.
var inputDateString = "12/31/2017 12:00:00 AM" // false, but I want to parse
var inputDateString = "12/31/2017" // true
DateTime.TryParseExact(inputDateString, "M/d/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out var parsedDate);
Is there any way to parse date string having only specific date format and ignore time?
There is an overload to TryParseExact that allows you to pass in multiple formats. If you know in advance which formats to expect, you can use this overload:
void Main()
{
string[] validFormats = {"M/d/yyyy", "M/d/yyyy hh:mm:ss tt"};
var inputDateString1 = "12/31/2017 12:00:00 AM"; // false, but I want to parse
var inputDateString2 = "12/31/2017"; // true
DateTime.TryParseExact(inputDateString1, validFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dt1);
DateTime.TryParseExact(inputDateString2, validFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dt2);
}
You can then get only the date portion using the Date property.
You could strip the time part from the input string, or parse the full input, using only the .Datepart.
var parsedDate = DateTime.MinValue;
var inputDateString = "12/31/2017 12:00:00 AM"; // false, but I want to parse
// option 1: use only the date part
if (DateTime.TryParseExact((inputDateString ?? "").Split(' ')[0] , "M/d/yyyy",
CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate))
Console.WriteLine(parsedDate);
// option 2: use the full input, but ignore the time
if (DateTime.TryParseExact(inputDateString, "M/d/yyyy hh:mm:ss tt",
CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate))
Console.WriteLine(parsedDate.Date);
Personally, I would go with the first option.
If you always want to only parse the Date portion that can be done by explicitly ensuring the string is only 10 characters in length. This is a somewhat convoluted example but you can strip out what you don't need, you'll get the idea:
var inputDateString = "12/31/2017 12:00:00 AM";
string datePortion = string.Empty;
DateTime dt;
if (inputDateString.Length>10)
{
// take first 10 characters of inputDateString
datePortion = inputDateString.Substring(0, Math.Min(inputDateString.Length, 10));
}
else if (inputDateString.Length==10)
{
// inputDateString is already 10 characters
datePortion = inputDateString;
}
else
{
// inputDateString is less than 10 characters, no date found, do nothing.
}
if(!DateTime.TryParse(datePortion, out dt))
{
// handle error that occurred,
}
else
{
// parse was successful, carry on.
}

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 parse date with minutes contains value 60?

I am getting exception when the minute contains value 60
var date = "30/10/14 08:60";
var result = DateTime.ParseExact(date, "dd/MM/yy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None);
How do i parse it correctly??
Either pass a correct value(>=0 || <=59) or use this:
var date = "30/10/14 08:60";
DateTime dateResult;
bool canParse = DateTime.TryParseExact(date, "dd/MM/yy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateResult);
if (!canParse)
{
string datePart = date.Split().First();
DateTime dtOnly;
if (DateTime.TryParseExact(datePart, "dd/MM/yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dtOnly))
{
string timePart = date.Split().Last();
string hourPart = timePart.Split(':')[0];
string minutePart = timePart.Split(':').Last();
int hour, minute;
if (int.TryParse(hourPart, out hour) && int.TryParse(minutePart, out minute))
{
TimeSpan timeOfDay = TimeSpan.FromHours(hour) + TimeSpan.FromMinutes(minute);
dateResult = dtOnly + timeOfDay; // 10/30/2014 09:00:00
}
}
}
First of all, the data is invalid, and this is why an exception is raised.
So, basically there are 2 resolutions:
If the data is from the 3rd party, my suggestion is that after consulting with your boss or company's lawyers you/your company asks the 3rd party to provide valid data, since you don't have legal obligation to fix/tolerate the invalid data for the 3rd party. IMO, you shouldn't.
If the data is from your legacy internal systems, you/company should fix the bugs that may produce 60. If for some reasons the bugs can't be fixed shortly, you may write a parser for example using regular expression to parse the data and tolerate 60.
So the 2nd resolution with regular expression is to answer your question directly. However, please be mindful that "30/10/14 08:60" is invalid, and must be fixed sooner or later in the data source.
BTW, here's the link with some regular expressions you may try.
For international convention are 60 minutes in an hour.
The sixtieth minute would be 59, in fact if you count from 0 to 59 find that they are 60 numbers. The date you write 8:60 does not exist, the value of them is 9:00.
Try this(Obviously only date1 raises an exception):
var date = "30/10/14 8:59";
var date1 = "30/10/14 9:00";
var result = DateTime.ParseExact(date, "dd/MM/yy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None);
var result1 = DateTime.ParseExact(date1, "dd/MM/yy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None);
In addition at this you can use this for controlling a data and receiving a message true/false
var date = "30/10/14 08:60";
DateTime outData;
Boolean flagCorrectData = DateTime.TryParseExact(date, "dd/MM/yy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None, out outData);
if (flagCorrectData)
{
MessageBox.Show("Date correct");
}
else
{
MessageBox.Show("Date error");
}
If you always know if the time portion of your date string is of the format HH:mm, you can do this to get the right DateTime date:
string dateString = "30/10/14 08:60";
string[] dateParts = dateString.Split(' ');
DateTime date = DateTime.ParseExact(dateParts[0],"dd/MM/yy",CultureInfo.InvariantCulture);
string[] timeParts = dateParts[1].Split(':');
date=date.AddMinutes(double.Parse(timeParts[0])*60+double.Parse(timeParts[1]));
If you only care precisely about the special case of :60, you can use 60 in ParseExact explicitly:
string date = "30/10/14 08:60";
DateTime result;
if(DateTime.TryParseExact(date, "dd/MM/yy HH:mm",
CultureInfo.InvariantCulture, DateTimeStyles.None,out result))
{
return result;
}
//Handle weird :60
if(DateTime.TryParseExact(date, "dd/MM/yy HH:60",
CultureInfo.InvariantCulture, DateTimeStyles.None,out result))
{
return result.AddMinutes(60);
}
throw new ArgumentException("date");

I am getting Error as String was not recognized as a valid DateTime

private string format = "dd/MM/yyyy HH:mm:ss";
DateTime fromdate = DateTime.ParseExact(GetFromScanDateTextBox.Text, format, CultureInfo.InvariantCulture);
I am getting error when executing this line string was not recognized as a Valid Date Time.
I have tried this also but it not works
DateTime fromdate = DateTime.ParseExact(GetFromScanDateTextBox.Text, format,null);
Your format string must be "d/M/yyyy", take a look at this.
Basically
MM : The month, from 01 through 12.
while
M : The month, from 1 through 12.
The same for the day part.
You are telling DateTime.ParseExact that you are expecting a string with format dd/MM/yyyy HH:mm:ss but you are giving it a string with format d/M/yyyy.
You need to change your format to just d/M/yyyy.
Also I suggest using DateTime.TryParseExact to verify the validity of your string instead of using exceptions.
var okay = DateTime.TryParseExact(
input,
new[] { "dd/MM/yyyy HH:mm:ss", "d/M/yyyy" },
new CultureInfo("en-GB"),
DateTimeStyles.None,
out dateTime);
If your input string is liable to change, TryParseExact allows you to define multiple formats as shown above, or alternatively, if it is always going to be with your current culture, just do DateTime.TryParse and do away with defining the format.
var okay = DateTime.TryParse(input, out dateTime);
If your format is always month/date/year and particularly in this case(if your date is 3rd Sept 2013) you can use:
string format = "MM/dd/yyyy";
string dateTime = "9/3/2013";
dateTime = (dateTime.Split('/')[0].Length == 1 ? "0" + dateTime.Split('/')[0] : dateTime.Split('/')[0]) + "/" + (dateTime.Split('/')[1].Length == 1 ? "0" + dateTime.Split('/')[1] : dateTime.Split('/')[1]) + "/" + dateTime.Split('/')[2];
DateTime fromdate = DateTime.ParseExact(dateTime, format, CultureInfo.InvariantCulture);
Do not provide the HH:MM:SS part in the format part
string format = "dd/MM/yyyy";
DateTime fromdate = DateTime.ParseExact(test.Text, format, CultureInfo.InvariantCulture);

C# string to SqlDateTime: how to set format for recognition?

I need to use
SqlDateTime.Parse(val)
where val is a string such as " 23.3.1992 00:00:00 ".
The string is in European format, that is, day precedes month. However Parse wants "American" format. How I can tell it to use particular datetime format / locale?
Thanks in advance!
Try this:
string val = "23.12.1992 00:00:00";
// Parse exactly from your input string to the native date format.
DateTime dt = DateTime.ParseExact(val, "dd.M.yyyy hh:mm:ss", null);
// Part to SqlDateTime then
System.Data.SqlTypes.SqlDateTime dtSql = System.Data.SqlTypes.SqlDateTime.Parse(dt.ToString("yyyy/MM/dd"));
This could be done in one statement, but just separated for illustration.
Have you tried DateTime instead of SQLDateTime
DateTime d = DateTime.Parse(val);
String s = d.ToString(CultureInfo.CreateSpecificCulture("en-US"));
Can you try this ?
string valInEuropean = "23.3.1992 00:00:00";
DateTime dateInEuropean = DateTime.Parse(valInEuropean);
string valInAmerican = dateInEuropean.ToString("yyyy-MM-dd HH:mm:ww");
For converting a string to datetime object when the format is known(in this case )
use
DateTime dwweek = DateTime.ParseExact("23.3.1992 00:00:00", "dd.MM.yyyy hh:mm:ss", System.Globalization.CultureInfo.InvariantCulture);

Categories

Resources