In my XML I have a date value as shown below:
[CDATA[07/07/1980]]
I do the following to retrieve the date:
public static DateTime? GetDateTimeValue(string dateTimeString)
{
DateTime i;
if ((dataTimeString != null) && (dataTimeString.Value.Trim() != ""))
if (DateTime.TryParse(dateTimeString, out i))
return i;
return null;
}
The value I get is 07/07/1980 12:00:00 AM.
I can do the following:
DatdTime.TryParse(dateTimeString.ToShortDateString())
But I don't want to manipulate the data in any way. I want to get the date as is.
Any help will be greatly appreciated.
Here is a method I use, but I do not use a nullable DateTime.
private static DateTime nodate = new DateTime(1900, 1, 1);
public static DateTime NODATE { get { return nodate; } }
public static DateTime GetDate(object obj) {
if ((obj != null) && (obj != DBNull.Value)) { // Databases return DBNull.Value
try {
return Convert.ToDateTime(obj);
} catch (Exception) { }
try {
return DateTime.Parse(obj.ToString());
} catch (Exception) { }
}
return NODATE;
}
I can't always use TryParse because a lot of my code has to be Compact Framework safe.
If anything goes wrong, I will see my NODATE value (January 1, 1900) in my date fields. It is pretty safe to guess that most of my database programs have no date if they try to display something indicating they were input on January 1st of 1900. After all: Everyone has New Year's off, right? :)
Related
I was reading about the IFormatProvider.GetFormat(Type) method on Microsoft.com, and decided to run the example code provided on the page.
Instead of this output:
On Monday, the balance of account 10425-456-7890 was $16.34.
On Tuesday, the balance of account 104254567890 was $16.34.
... the program prints out this:
On Monday, the balance of account 10425-456-7890 was 16,34 ?.
On Tuesday, the balance of account 104254567890 was 16,34 ?.
Why are there question marks at the end of each line?
I just copied the code into Visual Studio, I did not change anything.
Any hints on how such cases can be debugged? I'm self-studying C# and I don't know much.
The code is:
using System;
using System.Globalization;
namespace ConsoleApp4
{
public enum DaysOfWeek { Monday = 1, Tuesday = 2 };
public class AcctNumberFormat : IFormatProvider, ICustomFormatter
{
private const int ACCT_LENGTH = 12;
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
else
return null;
}
public string Format(string fmt, object arg, IFormatProvider formatProvider)
{
// Provide default formatting if arg is not an Int64.
if (arg.GetType() != typeof(Int64))
try
{
return HandleOtherFormats(fmt, arg);
}
catch (FormatException e)
{
throw new FormatException(String.Format("The format of '{0}' is invalid.", fmt), e);
}
// Provide default formatting for unsupported format strings.
string ufmt = fmt.ToUpper(CultureInfo.InvariantCulture);
if (!(ufmt == "H" || ufmt == "I"))
try
{
return HandleOtherFormats(fmt, arg);
}
catch (FormatException e)
{
throw new FormatException(String.Format("The format of '{0}' is invalid.", fmt), e);
}
// Convert argument to a string.
string result = arg.ToString();
// If account number is less than 12 characters, pad with leading zeroes.
if (result.Length < ACCT_LENGTH)
result = result.PadLeft(ACCT_LENGTH, '0');
// If account number is more than 12 characters, truncate to 12 characters.
if (result.Length > ACCT_LENGTH)
result = result.Substring(0, ACCT_LENGTH);
if (ufmt == "I") // Integer-only format.
return result;
// Add hyphens for H format specifier.
else // Hyphenated format.
return result.Substring(0, 5) + "-" + result.Substring(5, 3) + "-" + result.Substring(8);
}
private string HandleOtherFormats(string format, object arg)
{
if (arg is IFormattable)
return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
else if (arg != null)
return arg.ToString();
else
return String.Empty;
}
}
public class TestFormatting
{
public static void Main()
{
long acctNumber;
double balance;
DaysOfWeek wday;
string output;
acctNumber = 104254567890;
balance = 16.34;
wday = DaysOfWeek.Monday;
output = String.Format(new AcctNumberFormat(),
"On {2}, the balance of account {0:H} was {1:C2}.",
acctNumber, balance, wday);
Console.WriteLine(output);
wday = DaysOfWeek.Tuesday;
output = String.Format(new AcctNumberFormat(),
"On {2}, the balance of account {0:I} was {1:C2}.",
acctNumber, balance, wday);
Console.WriteLine(output);
}
}
// The example displays the following output:
// On Monday, the balance of account 10425-456-7890 was $16.34.
// On Tuesday, the balance of account 104254567890 was $16.34.
}
Is there a way to combine these 2 methods for DateTime (ignore the ticks while comparing datetimes) and TimeSpan comparisons with generic parameter types and consolidating the logic?
private bool AreDateTimesEqual(DateTime? firstDateTime, DateTime? seconDateTime)
{
bool compareResult = false;
if (firstDateTime.HasValue && seconDateTime.HasValue)
{
firstDateTime = firstDateTime.Value.AddTicks(-firstDateTime.Value.Ticks);
seconDateTime = seconDateTime.Value.AddTicks(-seconDateTime.Value.Ticks);
compareResult = DateTime.Compare(firstDateTime.GetValueOrDefault(), seconDateTime.GetValueOrDefault()) == 0;
}
else if (!firstDateTime.HasValue && !seconDateTime.HasValue)
{
compareResult = true;
}
return compareResult;
}
private bool AreTimeSpansEqual(TimeSpan? firstTimeSpan, TimeSpan? secondTimeSpan)
{
bool compareResult = false;
if (firstTimeSpan.HasValue && secondTimeSpan.HasValue)
{
compareResult = TimeSpan.Compare(firstTimeSpan.GetValueOrDefault(), secondTimeSpan.GetValueOrDefault()) == 0;
}
else if (!firstTimeSpan.HasValue && !secondTimeSpan.HasValue)
{
compareResult = true;
}
return compareResult;
}
It sounds as if you're looking to compare two DateTime objects without the time part.
Keep in mind that both DateTime and TimeSpan implement the IEquatable interface which allows you to call Compare(...) on an instance of either.
To compare dates without time:
DateTime date1 = DateTime.Now;
DateTime date2 = DateTime.Now.AddHours(5);
return date1.Date.Compare(date2.Date) == 0;
For a DateTime variable, the .Date property will return the date without the time.
To compare TimeSpans, you would also use .Compare and check that the result is 0 (for equality).
How to compare only Date without Time in DateTime types in C#.One of the date will be nullable.How can i do that??
DateTime val1;
DateTime? val2;
if (!val2.HasValue)
return false;
return val1.Date == val2.Value.Date;
You can use the Date property of DateTime object
Datetime x;
Datetime? y;
if (y != null && y.HasValue && x.Date == y.Value.Date)
{
//DoSomething
}
This uses short-circuit to avoid comparisons if nullable date is null, then uses the DateTime.Date property to determine equivalency.
bool Comparison(DateTime? nullableDate, DateTime aDate) {
if(nullableDate != null && aDate.Date == nullableDate.Value.Date) {
return true;
}
return false;
}
bool DatesMatch(DateTime referenceDate, DateTime? nullableDate)
{
return (nullableDate.HasValue) ?
referenceDate.Date == nullableDate.Value.Date :
false;
}
If you want a true comparison, you can use:
Datetime dateTime1
Datetime? dateTime2
if(dateTime2.Date != null)
dateTime1.Date.CompareTo(dateTime2.Date);
Hope it helps...
The only challenging aspect here is the fact that you want something which is both DateTime and nullable.
Here is the solution for standard DateTime: How to compare only Date without Time in DateTime types in C#?
if(dtOne.Date == dtTwo.Date)
For nullable, it's just a matter of choice. I would choose an extension method.
class Program
{
static void Main(string[] args)
{
var d1 = new DateTime(2000, 01, 01, 12, 24, 48);
DateTime? d2 = new DateTime(2000, 01, 01, 07, 29, 31);
Console.WriteLine((d1.Date == ((DateTime)d2).Date));
Console.WriteLine((d1.CompareDate(d2)));
Console.WriteLine((d1.CompareDate(null)));
Console.WriteLine("Press enter to continue...");
Console.ReadLine();
}
}
static class DateCompare
{
public static bool CompareDate(this DateTime dtOne, DateTime? dtTwo)
{
if (dtTwo == null) return false;
return (dtOne.Date == ((DateTime)dtTwo).Date);
}
}
You could create a method like the one below, following the similar return values as the .net framework comparisons, giving -1 when the left side is smallest, 0 for equal dates, and +1 for right side smallest:
private static int Compare(DateTime? firstDate, DateTime? secondDate)
{
if(!firstDate.HasValue && !secondDate.HasValue)
return 0;
if (!firstDate.HasValue)
return -1;
if (!secondDate.HasValue)
return 1;
else
return DateTime.Compare(firstDate.Value.Date, secondDate.Value.Date);
}
Of Course a nicer implementation would be to create an extension method for this.
I provided record containing column with integer type, instead of reporting errors (as documented here) got InvalidCastException in method below (for filling records in storage):
protected void FillRecordOrder(object rec, object[] fields)
{
OrdersVerticalBar record = (OrdersVerticalBar) rec;
record.OrderDate = (DateTime) fields[0];
}
How to handle errors using SqlStorage in Filehelpers library?
What are the contents of fields[0]? Are you saying it contains an integer? Then you need to convert it somehow to a DateTime. Something like:
protected void FillRecordOrder(object rec, object[] fields)
{
OrdersVerticalBar record = (OrdersVerticalBar) rec;
if (fields[0] == null)
record.OrderDate = DateTime.MinValue;
else if (fields[0] is DateTime)
record.OrderDate = (DateTime)fields[0];
else if (fields[0] is int)
{
DateTime baseDate = new DateTime(1900, 1, 1);
DateTime newDate = baseDate.AddDays((int)fields[0]);
record.OrderDate = newDate;
}
}
I doubt I am the only one who has come up with this solution, but if you have a better one please post it here. I simply want to leave this question here so I and others can search it later.
I needed to tell whether a valid date had been entered into a text box and this is the code that I came up with. I fire this when focus leaves the text box.
try
{
DateTime.Parse(startDateTextBox.Text);
}
catch
{
startDateTextBox.Text = DateTime.Today.ToShortDateString();
}
DateTime.TryParse
This I believe is faster and it means you dont have to use ugly try/catches :)
e.g
DateTime temp;
if(DateTime.TryParse(startDateTextBox.Text, out temp))
{
// Yay :)
}
else
{
// Aww.. :(
}
Don't use exceptions for flow control. Use DateTime.TryParse and DateTime.TryParseExact. Personally I prefer TryParseExact with a specific format, but I guess there are times when TryParse is better. Example use based on your original code:
DateTime value;
if (!DateTime.TryParse(startDateTextBox.Text, out value))
{
startDateTextox.Text = DateTime.Today.ToShortDateString();
}
Reasons for preferring this approach:
Clearer code (it says what it wants to do)
Better performance than catching and swallowing exceptions
This doesn't catch exceptions inappropriately - e.g. OutOfMemoryException, ThreadInterruptedException. (Your current code could be fixed to avoid this by just catching the relevant exception, but using TryParse would still be better.)
Here's another variation of the solution that returns true if the string can be converted to a DateTime type, and false otherwise.
public static bool IsDateTime(string txtDate)
{
DateTime tempDate;
return DateTime.TryParse(txtDate, out tempDate);
}
All the Answers are Quite great but if you want to use a single function ,this may work.
It will work with other date format but wont work with this date eg:05/06/202 it will consider it as valid date but it isnt.
private bool validateTime(string dateInString)
{
DateTime temp;
if (DateTime.TryParse(dateInString, out temp))
{
return true;
}
return false;
}
I would use the DateTime.TryParse() method: http://msdn.microsoft.com/en-us/library/system.datetime.tryparse.aspx
What about using TryParse?
A problem with using DateTime.TryParse is that it doesn't support the very common data-entry use case of dates entered without separators, e.g. 011508.
Here's an example of how to support this. (This is from a framework I'm building, so its signature is a little weird, but the core logic should be usable):
private static readonly Regex ShortDate = new Regex(#"^\d{6}$");
private static readonly Regex LongDate = new Regex(#"^\d{8}$");
public object Parse(object value, out string message)
{
msg = null;
string s = value.ToString().Trim();
if (s.Trim() == "")
{
return null;
}
else
{
if (ShortDate.Match(s).Success)
{
s = s.Substring(0, 2) + "/" + s.Substring(2, 2) + "/" + s.Substring(4, 2);
}
if (LongDate.Match(s).Success)
{
s = s.Substring(0, 2) + "/" + s.Substring(2, 2) + "/" + s.Substring(4, 4);
}
DateTime d = DateTime.MinValue;
if (DateTime.TryParse(s, out d))
{
return d;
}
else
{
message = String.Format("\"{0}\" is not a valid date.", s);
return null;
}
}
}
One liner:
if (DateTime.TryParse(value, out _)) {//dostuff}
protected bool ValidateBirthday(String date)
{
DateTime Temp;
if (DateTime.TryParse(date, out Temp) == true &&
Temp.Hour == 0 &&
Temp.Minute == 0 &&
Temp.Second == 0 &&
Temp.Millisecond == 0 &&
Temp > DateTime.MinValue)
return true;
else
return false;
}
//suppose that input string is short date format.
e.g. "2013/7/5" returns true or
"2013/2/31" returns false.
http://forums.asp.net/t/1250332.aspx/1
//bool booleanValue = ValidateBirthday("12:55"); returns false
private void btnEnter_Click(object sender, EventArgs e)
{
maskedTextBox1.Mask = "00/00/0000";
maskedTextBox1.ValidatingType = typeof(System.DateTime);
//if (!IsValidDOB(maskedTextBox1.Text))
if (!ValidateBirthday(maskedTextBox1.Text))
MessageBox.Show(" Not Valid");
else
MessageBox.Show("Valid");
}
// check date format dd/mm/yyyy. but not if year < 1 or > 2013.
public static bool IsValidDOB(string dob)
{
DateTime temp;
if (DateTime.TryParse(dob, out temp))
return (true);
else
return (false);
}
// checks date format dd/mm/yyyy and year > 1900!.
protected bool ValidateBirthday(String date)
{
DateTime Temp;
if (DateTime.TryParse(date, out Temp) == true &&
Temp.Year > 1900 &&
// Temp.Hour == 0 && Temp.Minute == 0 &&
//Temp.Second == 0 && Temp.Millisecond == 0 &&
Temp > DateTime.MinValue)
return (true);
else
return (false);
}
You can also define the DateTime format for a specific CultureInfo
public static bool IsDateTime(string tempDate)
{
DateTime fromDateValue;
var formats = new[] { "MM/dd/yyyy", "dd/MM/yyyy h:mm:ss", "MM/dd/yyyy hh:mm tt", "yyyy'-'MM'-'dd'T'HH':'mm':'ss" };
return DateTime.TryParseExact(tempDate, formats, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out fromDateValue);
}
DateTime temp;
try
{
temp = Convert.ToDateTime(grd.Rows[e.RowIndex].Cells["dateg"].Value);
grd.Rows[e.RowIndex].Cells["dateg"].Value = temp.ToString("yyyy/MM/dd");
}
catch
{
MessageBox.Show("Sorry The date not valid", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop,MessageBoxDefaultButton.Button1,MessageBoxOptions .RightAlign);
grd.Rows[e.RowIndex].Cells["dateg"].Value = null;
}
DateTime temp;
try
{
temp = Convert.ToDateTime(date);
date = temp.ToString("yyyy/MM/dd");
}
catch
{
MessageBox.Show("Sorry The date not valid", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop,MessageBoxDefaultButton.Button1,MessageBoxOptions .RightAlign);
date = null;
}
protected static bool CheckDate(DateTime date)
{
if(new DateTime() == date)
return false;
else
return true;
}