I have a TextBox in which the user can type a date. I only expect following formats:
12.12.2017
12.02.2017
12.2.2017
02.12.2017
2.12.2017
02.02.2017
2.2.2017
So there can be a leading zero or not.
I am currently parsing the DateTime with following code:
DateTime myDate = new DateTime();
bool success = DateTime.TryParseExact(TboDate.Text, "dd.MM.yyyy",
CultureInfo.CurrentUICulture, DateTimeStyles.None, out myDate);
Dates like 12.2.2017 can not be parsed successfully with that code. But I don't want to check the string everytime and parse it then with the matching format d.M.yyyy, dd.M.yyyy, d.MM.yyyy and so on. Is there an easier way to tell the method, that there can be leading zeros?
They could all be parsed without a problem with Parse/TryParse f.e. with de-DE culture:
var dates = new[] { "12.12.2017", "12.02.2017", "12.2.2017", "02.12.2017", "2.12.2017", "02.02.2017", "2.2.2017" };
foreach (var dateStr in dates)
{
DateTime dt;
if (!DateTime.TryParse(dateStr, CultureInfo.CurrentUICulture, DateTimeStyles.None, out dt))
{
Console.WriteLine("not valid: " + dateStr);
}
}
But you could also use ParseExact if you specify all allowed formats:
string[] allowedFormats = { "dd.MM.yyyy", "d.MM.yyyy", "dd.M.yyyy", "d.M.yyyy" };
foreach (var dateStr in dates)
{
DateTime dt;
if (!DateTime.TryParseExact(dateStr, allowedFormats, CultureInfo.CurrentUICulture, DateTimeStyles.None, out dt))
{
Console.WriteLine("not valid: " + dateStr);
}
}
Update
As Jon Skeet has mentioned it's not necessary to specify multiple, this handles all: "d.M.yyyy"
Related
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.
}
I have the following string
\\server\f$\direct1\205486060518032015-05-28 150931.rtf
Which contains a date in the format yyyy-MM-dd hhmmss
Now I have managed to extract that string using a Regular Expression
Regex rgx = new Regex(#"\d{4}-\d{2}-\d{2} \d{6}");
di = new DirectoryInfo(Location);
var fileList = di.GetFiles("*.*", SearchOption.TopDirectoryOnly);
foreach (FileInfo fi in fileList)
{
EngineEvent(this, new EngineEventProperties(String.Format("Filename: {0}", fi.FullName)));
DateTime fileDate = DateTime.Now;
Match mat = rgx.Match(fi.FullName);
.
.
.
}
The Match contains the expected string '2015-05-28 150931'
However when I try and use the following code to convert it to a DateTime
if (DateTime.TryParseExact(fi.FullName, "yyyy-MM-dd hhmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out fileDate))
{
Console.WriteLine("Date : {0}", fileDate);
};
It returns false, using ParseExact fails saying the string does not contain a date.
So how can I do the conversion?
use this format:
"yyyy-MM-dd HHmmss"
HH is for 24 hour time format, hh is for 12 hour format. 15 doesn't fit in a 12 hour time format, hence the failure.
Give it a shot:
DateTime temp;
if (DateTime.TryParseExact("2015-05-28 150931", "yyyy-MM-dd HHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out temp))
{
Console.WriteLine("Date : {0}", temp);
};
always good to bookmark the Custom Date and Time Format Strings page!
You're trying to parse the full name, not just the matched part. Try
Match mat = rgx.Match(fi.FullName);
if (mat.success)
{
if (DateTime.TryParseExact(mat.Value, "yyyy-MM-dd HHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out fileDate))
{
Console.WriteLine("Date : {0}", fileDate);
};
}
else
{
// no natch found...
}
Also changed the hour match to 24-hour (HH) as identified by #Jonesy
I have tried with
protected void gridCustomer_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DateTime olddate = Convert.ToDateTime(e.Row.Cells[9].Text);
// Error : String was not recognized as a valid DateTime./ 'DateTime today = DateTime.Now;'
if (olddate > today)
{
Label status = (Label) e.Row.FindControl("lblStatus");
status.Text = "AutoHold";
}
}
}
Convert.ToDateTime method uses your CurrentCulture settings by default if you don't provide any IFormatProvider as a second parameter.
That means, your CurrentCulture doesn't have yyyy-MM-dd as a standard date and time format.
In such a case, you can specify your string format with DateTime.TryParseExact or DateTime.ParseExact methods like;
DateTime olddate;
if(DateTime.TryParseExact(e.Row.Cells[9].Text, "yyyy-MM-dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None, out olddate))
{
// Your olddate will be 28/03/2015 00:00:00
}
but in old date getting '1/1/0001' where as in my grid cell i have
'4/1/2015' by above your mentioned code.
Clearly, your 4/1/2015 doesn't match with yyyy-MM-dd format, that why your olddate will be the default value of DateTime which is DateTime.MinValue (1/1/0001).
If your string can be more than one format, DateTime.TryParseExact has an overload that takes formats as a string array. With that, you can specify all possible formats your string.
For example;
string s = "4/1/2015";
DateTime dt;
var formats = new string[]{"yyyy-MM-dd", "M/d/yyyy"};
if(DateTime.TryParseExact(s, formats, CultureInfo.InvariantCulture,
DateTimeStyles.None, out dt))
{
// Your dt will be 01/04/2015 00:00:00
}
use:
CultureInfo provider = CultureInfo.InvariantCulture;
dateString = "2015-03-28";
format = "yyyy-MM-dd";
try {
result = DateTime.ParseExact(dateString, format, provider);
Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
catch (FormatException) {
Console.WriteLine("{0} is not in the correct format.", dateString);
}
MSDN
Replace this line in code
DateTime olddate = DateTime.ParseExact(e.Row.Cells[9].Text, "yyyy-MM-dd", CultureInfo.InvariantCulture);
Convert.ToDateTime will throw exception if there is a difference in current culture and the format of date time string
Use DateTime.ParseExact
string res = "2012-07-08";
DateTime d = DateTime.ParseExact(res, "yyyy-MM-dd", CultureInfo.InvariantCulture);
Console.WriteLine(d.ToString("MM/dd/yyyy")); // can set any format
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'm using a method to validate textboxes.
public bool ValidateDateTimeTextBoxes(params TextBox[] textBoxes)
{
DateTime value = DateTime.Today;
//string dateFormat = "dd/mm/yyyy";
foreach (var textBox in textBoxes)
{
if (!DateTime.TryParse(textBox.Text, out value))
{
return false;
}
}
return true;
}
I want to check the format too. It requires mm/dd/yyyy, but want it to be dd/mm/yyyy
Try DateTime.TryParseExact
DateTime dt;
DateTime.TryParseExact(textBox.Text,
"dd/MM/yyyy",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out dt);
If you want to check multiple formats as you updated in your question then you can do using another overload method of TryParseExact which takes format parameter as array of string.
string[] formats = { "dd/MM/yyyy", "MM/dd/yyyy" };
DateTime.TryParseExact(txtBox.Text,
formats,
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out value));
Please take care of format string. As you have mentioned format as dd/mm/yyyy. Here mm represents the minute not the month. Use MM for the month representation.
DateTime.TryParseExact(textBox.Text, "dd/MM/yyyy", null, System.Globalization.DateTimeStyles.None, out outDt))
public bool ValidateDateTimeTextBoxes(params TextBox[] textBoxes)
{
DateTime value = DateTime.Now;
//string dateFormat = "dd/mm/yyyy";
foreach (var textBox in textBoxes)
{
if (!DateTime.TryParse(textBox.Text,"dd/mm/yyyy",new CultureInfo("en-US"),
DateTimeStyles.None out value))
{
return false;
}
}
return true;
}
Try using TryParseExact
Converts the specified string representation of a date and time to its DateTime equivalent. The format of the string representation must match a specified format exactly. The method returns a value that indicates whether the conversion succeeded.
DateTime.TryParseExact(DateValue,
"dd/mm/yyyy",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out outDatetime);
Use TryParseExact instead which is also faster.
Example:
using System;
using System.Globalization;
class Program
{
static void Main()
{
string dateString = "27/05/2012"; // <-- Valid
string dtformat = "dd/mm/yyyy";
DateTime dateTime;
if (DateTime.TryParseExact(dateString, dtformat, CultureInfo.InvariantCulture,
DateTimeStyles.None, out dateTime))
{
Console.WriteLine(dateTime);
}
}
}