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
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 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"
I want to convert a string to a DateTime object. My string will be in this format- "18th Jul 2016" (the date can change). Obviously, .Net does not take this as a valid date format. Is there any easy way to convert this without using any third party library?
I wouldn't use String.Replace since it could be a problem is the current culture's month-name contains the strings you're going to replace.
Instead you could remove this part from the string:
string input = "18th Jul 2016";
string[] token = input.Split(); // split by space, result is a string[] with three tokens
token[0] = new string(token[0].TakeWhile(char.IsDigit).ToArray());
input = String.Join(" ", token);
DateTime dt;
if(DateTime.TryParseExact(input, "dd MMM yyyy", null, DateTimeStyles.None, out dt))
{
Console.WriteLine("Date is: " + dt.ToLongDateString());
}
If you pass null as IFormatProvider to TryParseExact the current culture's datetimeformat is used. If you want to force english names you can pass CultureInfo.InvariantCulture.
Workaround:
string dateStr = "18th Jul 2016";
dateStr = dateStr.Replace("th", "").Replace("st", "").Replace("rd", "").Replace("nd", "");
DateTime date;
if (DateTime.TryParseExact(dateStr, "dd MMM yyyy", CultureInfo.CurrentCulture,
DateTimeStyles.AssumeLocal, out date))
{
}
else
{
// error
}
Its a bit of a fudge but
string result = System.Text.RegularExpressions.Regex.Replace(dt, "[st|th|nd|rd]{2} ", " ", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
DateTime d = DateTime.Parse(result);
I included the space so it doesnt try editing the months.. I did start out with [0-9]{1,2} and replacing it with the number, but that seemed overkill
string dateString = "18th Jul 2016";
dateString = Regex.Replace(dateString, #"^(\d{2})(st|nd|rd|th)", "$1");
var result = DateTime.ParseExact(dateString, "dd MMM yyyy", CultureInfo.InvariantCulture);
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 trying to convert "1/7/2014 1:37 PM" (which is a string) to "01/07/2014 13:37" (DateTime format). What would be the best way to do this?
This is what I've got
string dateString = "1/27/2014 1:37 PM";
string format = "MM/dd/yyyy HH:mm";
DateTime dt;
bool temp = DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);
Console.WriteLine("bool = {0}, dt ={1}", temp, dt);
And my output is
bool = False, dt =1/1/0001 12:00:00 AM
Much thanks.
EDIT:
It's not just for the string I specified. Adding a few more cases - The LHS should get parsed exactly to the RHS
1/7/2014 1:37 PM -> 01/07/2014 13:37
11/27/2014 1:40 AM -> 11/27/2014 01:40
1/12/2014 2:05 PM -> 01/12/2014 14:05
Essentially, the input string does not have leading zeros and time is in 12 hour format and the output should have leading zeros where needed and should display the time in 24 hour format
I've tried giving
string format = "MM/dd/yyyy HH:mm tt";
but that also gives the same wrong output
bool = False, dt =1/1/0001 12:00:00 AM
Four things to change:
You need lowercase h for hours if you use the am/pm designator
You need a single h if the hour can be 1
You need to add tt for the am/pm designator
You need a single M for the month since it's 1
string dateString = "1/27/2014 1:37 PM";
string format = "M/dd/yyyy h:mm tt";
DateTime dt;
bool temp = DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);
Console.Write("temp: {0} date:{1}", temp, dt); // temp: True date:1/27/2014 1:37:00 PM
See: The "tt" Custom Format Specifier
Update: acccording to your edit:
I also need to convert it back to string in a specific format. It should have leading zeros and time is in 12 hour format and the output should have leading zeros where needed and should display the time in 24 hour format
1/7/2014 1:37 PM -> 01/07/2014 13:37
11/27/2014 1:40 AM -> 11/27/2014 01:40
1/12/2014 2:05 PM -> 01/12/2014 14:05
Then you can use this format string: MM/dd/yyyy HH:mm in DateTime.ToString with CultureInfo.InvariantCulture. Note that i've used uppercase HH for 24h hour format:
string output = dt.ToString("MM/dd/yyyy HH:mm", CultureInfo.InvariantCulture);
You need InvariantCulture, otherwise / will be replaced with the actual date-separator of your current culture (f.e. . in germany).
See: The "/" Custom Format Specifier
Maybe you can try like this
DateTime dt = new DateTime(2008, 3, 9, 16, 5, 7, 123);
Console.WriteLine(String.Format("{0:MM/dd/yyyy}", dt));
You should be using
lowercase h rather than H as the time is in 12-, not 24-hour
one h rather than two as you don't have a leading zero on the hour
one M rather than two as you don't have a leading zero on the month
tt to match AM or PM.
Custom Date and Time Format Strings
You can use
Datetime dtDate = DateTime.PareExact(dt,"DateFormat of dt",cultureInfo.InavriantCulture);
Try This...
static void Main(string[] args)
{
string dateString = "1/27/2014 1:37 PM";
string format = "MM/dd/yyyy HH:mm";
DateTime dt2 = Convert.ToDateTime(dateString);
Console.WriteLine(dt2.ToString(format));
Console.ReadLine();
}
This may help:-
DateTime txtmyDate = DateTime.ParseExact(dateString "MM/dd/yyyy hh:mm",
CultureInfo.InvariantCulture);
From DateTime.TryParseExact method
Converts the specified string representation of a date and time to its
DateTime equivalent using the specified format, culture-specific
format information, and style. The format of the string representation
must match the specified format exactly.
In your case, it is not.
MM format is for 01 to 12, use M format which is 1 to 12.
HH format is for 00 to 23, use h format instead which is 1 to 12.
Also you are missing tt format which is for AM/PM designator.
string str = "1/27/2014 1:37 PM";
string format = "M/dd/yyyy h:mm tt";
DateTime dt;
bool result = DateTime.TryParseExact(str,
format,
CultureInfo.InvariantCulture,
DateTimeStyles.None, out dt);
Console.WriteLine(result);
Output will be
True
Here a demonstration.
Your format is wrong. You are missing the AM/PM:
string format = "M/dd/yyyy h:mm tt";
Notice the tt part which is required in order to be able to properly parse the date. Also I would recommend you adding error checking:
string dateString = "1/27/2014 1:37 PM";
string format = "M/dd/yyyy h:mm tt";
DateTime dt;
bool temp = DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);
if (temp)
{
Console.WriteLine("bool = {0}, dt = {1:M/dd/yyyy h:mm}", temp, dt);
}
else
{
Console.WriteLine("Unable to parse date: {0}", dateString);
}