calculating age when textbox is empty error - c#

i have 2 texboxes textbox71 in it i enter the date of birth and the program calculates the age for me and show it in textbox72 , the problem is when i don't enter something in textbox71 the program gives me an error "string was not recognized as valid datetime " and shuts down , what i want from the program is when i dont enter something in dateofbirth textbox to show me a message to enter something , so i tried to do this but it didnt work here is my code :
if (!string.IsNullOrEmpty(textBox71.Text))
{
MessageBox.Show("please enter date of birth");
}
else
{
DateTime drid2 = Convert.ToDateTime(textBox71.Text);
DateTime drid3 = DateTime.Now;
int yy1 = Math.Abs(drid3.Year - drid2.Year);
textBox72.Text = yy1.ToString();
}

Try modifing to
if (string.IsNullOrEmpty(textBox71.Text))
{
MessageBox.Show("please enter date of birth");
}
else
{
DateTime drid2 = Convert.ToDateTime(textBox71.Text);
DateTime drid3 = DateTime.Now;
int yy1 = Math.Abs(drid3.Year - drid2.Year);
textBox72.Text = yy1.ToString();
}
!string.IsNullOrEmpty returns true if the value is not empty and false if the value is empty. And you were trying to do the opposite.

This string.IsNullOrEmpty(textBox71.Text) will be true if the textBox71.Text is either null or empty. So, !string.IsNullOrEmpty(textBox71.Text) will be false if the textBox71.Text is either null or empty, because ! is the negation operator.
So when the textBox71.Text would be either null or empty, the code in the else statement will be executed and when it will reach the line
DateTime drid2 = Convert.ToDateTime(textBox71.Text);
you will get an error, because textBox71.Text would be either null or empty.
So removing the negation operator !, your logic would be correct and your code would be executed as you expect.
For more information about the logical negation operator, please have a look here.
I would suggest you use the method String.IsNullOrWhiteSpace, since it is more general:
Indicates whether a specified string is null, empty, or consists only of white-space characters.
For more information about this method, please have a look here.

Related

Check for Date overlapping where end date might be null

I am currently trying to check for date overlapping where the end date might be null. With my current code, I am able display the conflict message if scenario 1 occurs. However, I am unable to display the conflict message for scenario 2. For example,
Scenario 1: End date not null
1/7/2018 to 1/9/2018
1/6/2018 to 1/9/2018
Result: there is conflict
Scenario 2: End date is null
1/7/2018 to null
1/6/2018 to 1/9/2018
Result: There is conflict
Here are my codes:
if ((A.StartDate < B.EndDate) &&
(B.StartDate < A.EndDate)) {
Console.WriteLine("Conflict");
}
Assuming that EndDate being null is essentially "no end date", so any date is always before this.
You can make use of the null object pattern, replacing null with a suitable always matching instance (and the easiest way to do that is to use the null-coalescing operator).
var ed = A.EndDate ?? DateTime.MaxValue;
if (theDate < ed) {
// We're in range
}

Null value causing issue saving to the database

I am trying to convert a text box into a decimal when I try this method it says that inpurt string was not in correct format what is the best way around this.
_record.houseHoldArrearsAmount = Convert.ToDecimal(txtArrearsAmount.Text)
I persume it is because text is "" null and and 0.00 hence it falls over
The compiler run time is causing an exception
The input is blank if the user has not entered a value as of yet
If you know that the text is always going to be a number you can still use Convert but check that the string isn't empty first:
if (!string.IsNullOrWhitespace(txtArrearsAmount.Text))
{
_record.houseHoldArrearsAmount = Convert.ToDecimal(txtArrearsAmount.Text);
}
Obviously this won't update the houseHoldArrearsAmount if it's not a numeric value. What you do in this case depends on your business model. You might want to set it to 0 or you might want to leave it with the old value and report and error.
Alternatively, if the input could be any string, you can use Decimal.TryParse to convert the string to a number.
decimal result;
if (decimal.TryParse(txtArrearsAmount.Text, out result))
{
_record.houseHoldArrearsAmount = result;
}
You can use "TryParse" funtion.
decimal householdArrearsAmount = decimal.Zero;
decimal.TryParse(txtArrearsAmount.Text, out householdArrearsAmount);
_record.householdArrearsAmount = householdArrearsAmount;
You can't use the null coalescing operator (as your suggested in comments), as the string value of the textbox won't be null, it will be an empty string.
You could do the following:
_record.householdArrearsAmount =
(string.IsNullOrWhiteSpace(txtArrearsAmount.Text) ? 0 :
Convert.ToDecimal(txtArrearsAmount.Text));

how to handle format exception for different textboxes with a custom message

I am inserting data in my database with a sqlcommand and parameters.All that is in my try {} part..after that I have a catch{} that gets exceptions.
My problem is that I have a date text boxes,and I have a integer texboxes.
How can I have for my date field
`catch{FormatException)
{
messagebox.show("Your date field must be dd/mm/yyy");
}
and how can I have for my integer field
`catch{FormatException)
{
messagebox.show("That field must be integer");
}
How can I separate those two format exceptions?
For date input rather than using textbox, use DatePicker. It will exclude the need to check for the format.
<DatePicker name="datePicker"></DatePicker>
And to get the value picked by date in behind code,
datePicker.SelectedDate
Now you only have to check for integer.
int parsedValue;
if(int.TryParse(convertToInt, out parsedValue)){
// All Ok
}
else {
messageError = "That field must be integer";
// Display error contained witin messageError
}
No need to put try catch as well.
Both FormatExceptions give different values for the exc.Message (where exc is the exception variable). For an int, it's "Input string was not in a correct format." and for a DateTime it's "String was not recognized as a valid DateTime.".
So you could just use a single try-catch and check for this string at the end, but that could create problems later on (code becomes hard to maintain). It's better to use separate try-catch blocks.
string messageError = null;
string convertTodate = "34/";
string convertToInt = "3.5";
try
{
int newInt = Convert.ToInt32(convertToInt);
}
catch(FormatException)
{
messageError = "That field must be integer";
}
try
{
DateTime newDate = Convert.ToDateTime(convertTodate);
}
catch(FormatException)
{
messageError = "Your date field must be dd/mm/yyy";
}
if(string.IsNullOrEmpty(messageError))
{
// All Ok
}
else
{
// Display error contained witin messageError
}

How can I show a string representation of a nullable DateTime type?

The user supplies "from" and "to" months for a report to be generated (e.g., from 1 month back to 13 months back; if they choose this on 2/15/2016, the return values are 1/1/2015 and 1/1/2016).
I want to allow the user to select either the furthest back or the nearest month from either the "from" or the "to" combobox. I just want to use the furthest back in time as the "from" and the closest in time as the "to" to avoid confusion on their part (they can do whatever seems natural to them).
So I start off with this code:
int fromMonths = Convert.ToInt32(comboBoxProduceUsageFrom.Text);
DateTime RptParamsNominalFromDate = ReportSchedulerConstsAndUtils.SubtractMonthsFrom(fromMonths, nextGenerateAndSendDate);
int toMonths = Convert.ToInt32(comboBoxProduceUsageTo.Text);
DateTime RptParamsNominalToDate = ReportSchedulerConstsAndUtils.SubtractMonthsFrom(toMonths, nextGenerateAndSendDate);
..and then I want to set the "from" date to the furthest back in time and the "to" to the nearer in time. I first tried this:
DateTime RptParamsFromDate;
DateTime RptParamsToDate;
if (RptParamsNominalFromDate > RptParamsNominalToDate)
{
RptParamsFromDate = RptParamsNominalToDate;
RptParamsToDate = RptParamsNominalFromDate;
}
else if (RptParamsNominalToDate > RptParamsNominalFromDate)
{
RptParamsFromDate = RptParamsNominalFromDate;
RptParamsToDate = RptParamsNominalToDate;
}
...but that fails with, "Use of unassigned local variable 'RptParamsFromDate'" (and the same error for "RptParamsToDate").
So I tried giving the DateTimes a value/nonvalue like so:
DateTime RptParamsFromDate = null;
DateTime RptParamsToDate = null;
...but that gives me, "Cannot convert null to 'System.DateTime' because it is a non-nullable value type"
So I set my fingers in motion again and tried nullablizing the DateTimes:
DateTime? RptParamsFromDate = null;
DateTime? RptParamsToDate = null;
...but then I get, "'System.Nullable' does not contain a definition for 'ToLongDateString' and no extension method 'ToLongDateString' accepting a first argument of type 'System.Nullable' could be found (are you missing a using directive or an assembly reference?)"
This is due to this code:
RptParamsFromDate.ToLongDateString()
in this block:
MessageBox.Show(string.Format(
"Using the current configuration, the Produce Usage report would next be sent on {0} and emailed to {1}; the report would cover data from {2} to {3}",
nextGenerateAndSendDate.ToLongDateString(),
emailRecipients,
RptParamsFromDate.ToLongDateString(),
RptParamsToDate.ToLongDateString()));
So what can I do to show the DateTime value and still appease the cantankerous beast?
UPDATE
Incorporating info from both SLaks and crashmstr, I ended up with the following working method:
private void buttonTestProdUsageSettings_Click(object sender, EventArgs e)
{
// Show example of when the report will run, and using which parameters,
// using the current configuration
DateTime nextGenerateAndSendDate = GetNextProduceUsageGenerateAndSendDate();
string emailRecipients = string.Join(",", emailAddresses.ToArray());
int fromMonths = Convert.ToInt32(comboBoxProduceUsageFrom.Text);
DateTime RptParamsNominalFromDate = ReportSchedulerConstsAndUtils.SubtractMonthsFrom(fromMonths, nextGenerateAndSendDate);
int toMonths = Convert.ToInt32(comboBoxProduceUsageTo.Text);
DateTime RptParamsNominalToDate = ReportSchedulerConstsAndUtils.SubtractMonthsFrom(toMonths, nextGenerateAndSendDate);
if (RptParamsNominalFromDate.Equals(RptParamsNominalToDate))
{
MessageBox.Show("The \"from\" and \"to\" values must differ; please try again.");
return;
}
// Allow user to enter either the nearest or furthest value in either the "from" or the "to":
DateTime? RptParamsFromDate = null;
DateTime? RptParamsToDate = null;
if (RptParamsNominalFromDate > RptParamsNominalToDate)
{
RptParamsFromDate = RptParamsNominalToDate;
RptParamsToDate = RptParamsNominalFromDate;
}
else if (RptParamsNominalToDate > RptParamsNominalFromDate)
{
RptParamsFromDate = RptParamsNominalFromDate;
RptParamsToDate = RptParamsNominalToDate;
}
MessageBox.Show(string.Format(
"Using the current configuration, the Produce Usage report would next be sent on {0} and emailed to {1}; the report would cover data from {2} to {3}",
nextGenerateAndSendDate.ToLongDateString(),
emailRecipients,
RptParamsFromDate.HasValue ? RptParamsFromDate.Value.ToLongDateString() : "No \"from\" Date",
RptParamsToDate.HasValue ? RptParamsToDate.Value.ToLongDateString() : "No \"to\" Date"));
}
You're trying to use the value of a nullable type.
To do that, you need to access its .Value property, which returns a regular DateTime value.
Beware that that will throw an exception if it is in fact null.
To add on to Slaks's original answer, the reason you were getting the first answer was because you must be trying to reference RptParamsFromDate or its kin, later in the code. The problem is because of this:
You've done:
Create Variable
Is something true? No? ...okay
Is something else true? No? ...okay
Variable has still not been set to anything. (Because RptParamsNominalFromDate == RptParamsNominalToDate)
(Assumption) You've tried to access the variable.
Use of unassigned local variable 'RptParamsFromDate'" (and the same error for "RptParamsToDate
Setting it to a DateTime? will get past that, somewhat, but you need to look into the logic issue, first. Make sure you're checking that this is null, before you try to use it, later.

Unhandled exception input string was not in a correct format

I would like to add exception handling in my program to display in a message box to the user. "Incorrect format entered please enter a numeric value" for my product price value. Currently when i enter a wrong format such as a string value i get an error message stating Unhandled exception input string was not in a correct format. Instead of this i want a message box to appear. can anyone point me in the right direction. Thanks. Code below i have used in my program.
if (result == System.Windows.Forms.DialogResult.Yes)
{
// update the employee record
((Employee)o).ProductName = this.textProdName.Text;
((Employee)o).ProductPrice = Convert.ToDouble(this.textProdPrice.Text);
((Employee)o).ProductId = this.textProdID.Text;
((Employee)o).ProductQuantity = Convert.ToInt32(this.textProdQuantity.Text);
MessageBox.Show(((Employee)o).ProdName + " record has been updated with new details, except the ID.");
Use TryParse instead of doing a blind Convert assuming that the value might work. Then you don't need to worry about an exception being thrown you can just display your alert if the operation returned false.
Here's an example from MSDN
double number;
value = Double.MinValue.ToString();
if (Double.TryParse(value, out number))
Console.WriteLine(number);
If the operation is successful TryParse returns true and the value of number will be updated with the double that was extracted.

Categories