I have run into an issue. I\'m obtaining a date time string from the database and and some of these date time strings does not contain time. But as for the new requirement every
Date and time are always separated by a space bar. The easiest way would be:
if (timestamp_string.Split(' ').Length == 2)
{
// timestamp_string has both date and time
}
else
{
// timestamp_string only has the date
}
This code assumes the date always exists.
If you want take it further (in case the date does not exist), you can do:
if (timestamp_string.Split(' ')
.Select(item => item.Split(':').Length > 1)
.Any(item => item))
{
// this would work for any string format that contains date, for example:
// 2012/APRIL/03 12:00:05 -> this would work
// 2013/04/05 09:00:01 -> this would work
// 08:50:45 2013/01/01 -> this would also work
// 08:50:50 -> this would also work
}
else
{
// no date in the timestamp_string at all
}
Hope this helps!
Here's what I'm going with for now. It may not be perfect, but likely better than considering any 12am datetime as not having a time. The premise is that if I tack a full time specification on the end it will parse if it's just a date but fail if it already has a time component.
I had to make the assumption that there's not some valid, date/time that has 7 non-white-space characters or less. It appears that "1980/10" parses, but not "1980/10 01:01:01.001".
I've included various test cases. Feel free to add your own and let me know if they fail.
public static bool IsValidDateTime(this string dateString, bool requireTime = false)
{
DateTime outDate;
if(!DateTime.TryParse(dateString, out outDate)) return false;
if (!requireTime) return true;
else
{
return Regex.Replace(dateString, @"\s", "").Length > 7
&& !DateTime.TryParse(dateString + " 01:01:01.001", out outDate);
}
}
public void DateTest()
{
var withTimes = new[]{
"1980/10/11 01:01:01.001",
"02/01/1980 01:01:01.001",
"1980-01-01 01:01:01.001",
"1980/10/11 00:00",
"1980/10/11 1pm",
"1980-01-01 00:00:00"};
//Make sure our ones with time pass both tests
foreach(var date in withTimes){
Assert.IsTrue(date.IsValidDateTime(), String.Format("date: {0} isn't valid.", date));
Assert.IsTrue(date.IsValidDateTime(true), String.Format("date: {0} does have time.", date));
}
var withoutTimes = new[]{
"1980/10/11",
"1980/10",
"1980/10 ",
"10/1980",
"1980 01",
"1980/10/11 ",
"02/01/1980",
"1980-01-01"};
//Make sure our ones without time pass the first and fail the second
foreach (var date in withoutTimes)
{
Assert.IsTrue(date.IsValidDateTime(), String.Format("date: {0} isn't valid.", date));
Assert.IsFalse(date.IsValidDateTime(true), String.Format("date: {0} doesn't have time.", date) );
}
var bogusTimes = new[]{
"1980",
"1980 01:01",
"80 01:01",
"1980T01",
"80T01:01",
"1980-01-01T01",
};
//Make sure our ones without time pass the first and fail the second
foreach (var date in bogusTimes)
{
DateTime parsedDate;
DateTime.TryParse(date, out parsedDate);
Assert.IsFalse(date.IsValidDateTime(), String.Format("date: {0} is valid. {1}", date, parsedDate));
Assert.IsFalse(date.IsValidDateTime(true), String.Format("date: {0} is valid. {1}", date, parsedDate));
}
}
The date time components TimeOfDay is what you need.
MSDN says "Unlike the Date property, which returns a DateTime value that represents a date without its time component, the TimeOfDay property returns a TimeSpan value that represents a DateTime value's time component."
Here is an example with consideration of all your scenarios.
Since you are sure of the format you can use DateTime.Parse
else please use DateTime.TryParse
var dateTime1 = System.DateTime.Parse("1980/10/11 12:00:00");
var dateTime2 = System.DateTime.Parse("2010/APRIL/02 17:10:00");
var dateTime3 = System.DateTime.Parse("10/02/10 03:30:34");
var dateTime4 = System.DateTime.Parse("02/20/10");
if (dateTime1.TimeOfDay.TotalSeconds == 0) {
Console.WriteLine("1980/10/11 12:00:00 - does not have Time");
} else {
Console.WriteLine("1980/10/11 12:00:00 - has Time");
}
if (dateTime2.TimeOfDay.TotalSeconds == 0) {
Console.WriteLine("2010/APRIL/02 17:10:00 - does not have Time");
} else {
Console.WriteLine("2010/APRIL/02 17:10:00 - Has Time");
}
if (dateTime3.TimeOfDay.TotalSeconds == 0) {
Console.WriteLine("10/02/10 03:30:34 - does not have Time");
} else {
Console.WriteLine("10/02/10 03:30:34 - Has Time");
}
if (dateTime4.TimeOfDay.TotalSeconds == 0) {
Console.WriteLine("02/20/10 - does not have Time");
} else {
Console.WriteLine("02/20/10 - Has Time");
}
Try this,
DateTime myDate;
if (DateTime.TryParseExact(inputString, "dd-MM-yyyy hh:mm:ss",
CultureInfo.InvariantCulture, DateTimeStyles.None, out myDate))
{
//String has Date and Time
}
else
{
//String has only Date Portion
}
You can try using other format specifiers as listed here, http://msdn.microsoft.com/en-us/library/8kb3ffffd4.aspx
Combining the answers of Guru Kara and Patipol Paripoonnanonda with the .net globalisation API results in:
bool HasExplicitTime(DateTime parsedTimestamp, string str_timestamp)
{
string[] dateTimeSeparators = { "T", " ", "@" };
string[] timeSeparators = {
CultureInfo.CurrentUICulture.DateTimeFormat.TimeSeparator,
CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator,
":"};
if (parsedTimestamp.TimeOfDay.TotalSeconds != 0)
return true;
string[] dateOrTimeParts = str_timestamp.Split(
dateTimeSeparators,
StringSplitOptions.RemoveEmptyEntries);
bool hasTimePart = dateOrTimeParts.Any(part =>
part.Split(
timeSeparators,
StringSplitOptions.RemoveEmptyEntries).Length > 1);
return hasTimePart;
}
This approach:
TimeOfDay
indicates midnight or no explicit time; andLimitations: