Just to Clarify a couple of points,
I have my fingers crossed I'm missing something obvious because this makes no sense to me. Any help you can offer would be much appreciated. I have included my code at the end of the question.
DateTime
fields which are included in a form on a page in my application: StartTime
and EndTime
.StartTime
field works perfectly, only excepting valid times as input and displaying an error for nonsensical times such as 28:30 or 17:67 until the User corrects it.EndTime
field however does not validate correctly. Bad inputs are switched back to the current Time/Date before being passed back to the controller, the controller never even sees the bad values meaning I can't catch it and return an error at that point.EndTime
validation does work, it just doesn't prevent form submission.As I have one working field I have attempted to use that to correct the error. However I hit a stumbling block in realising that there are no differences between the two. Deciding that I must have missed something I switched the variable names round so that the StartTime
would be using the EndTime
code and vice versa, I did this in each of the sections below one by one hoping to find a point where the field which was working swapped. That, however, never happened. Even once the entirety of their code was switched over it was still found to be the EndTime
variable/field which was broken and the StartTime
variable/field which was working.
Despite spending nearly a week with this bug now I have been unable to find any similar problems online and am at a complete stumbling block as to where to go or what to try now. I have tried looking for issues caused by DateTime calendar pickers as well as validation errors in general but can't find anything of use to this situation.
This is one of the last bugs to fix before the project is completed and so any help or even ideas you can offer would be amazing.
I have included everything I could think to here that interacts with the fields in question. If I have missed anything or you need more info please let me know.
I have the following two DateTime
fields in my Record
Entity
public partial class Record
{
// Other entity fields
// ....
// ...
// ..
[DisplayName("Start Time")]
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:g}", ApplyFormatInEditMode = true)]
public DateTime StartTime { get; set; }
[DisplayName("End Time")]
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:g}", ApplyFormatInEditMode = true)]
public DateTime EndTime { get; set; }
// and in the constructor
public Record()
{
// initialise the DateTime fields with the current DateTime,
// adjusted for daylight savings
BaseController b = new BaseController();
StartTime = b.TimeNow();
EndTime = b.TimeNow();
}
}
For the sake of completion this is the TimeNow()
function's code:
public DateTime TimeNow()
{
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
DateTime t = DateTime.Now;
if (tz.IsDaylightSavingTime(t))
t = t.AddHours(1);
return t;
}
The Record
entity is then included into a ViewModel as follows:
public class Home_UserAddRecord
{
[DisplayName("Record")]
public Record record { get; set; }
// Other ViewModel fields
// ....
// ...
// ..
// and the blank constructor:
public Home_UserAddRecord()
{
record = new Record();
Error = false;
ErrorMessage = string.Empty;
}
}
They are then included into a form on the page like so:
@using (Html.BeginForm())
{
<div class="form-horizontal">
<div class="form-group col-md-12">
@Html.LabelFor(model => model.record.StartTime, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-5">
@Html.EditorFor(model => model.record.StartTime, new { htmlAttributes = new { @Value = Model.record.StartTime.ToString("dd/MM/yyyy HH:mm"), @class = "form-control", @id = "StartDate" } })
@Html.ValidationMessageFor(model => model.record.StartTime, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group col-md-12">
@Html.LabelFor(model => model.record.EndTime, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-5">
@Html.EditorFor(model => model.record.EndTime, new{ htmlAttributes = new{ @Value = Model.record.EndTime.ToString("dd/MM/yyyy HH:mm"), @class = "form-control", @id = "EndDate" } })
@Html.ValidationMessageFor(model => model.record.EndTime, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
And then finally they have a script applied to them to allow the use of a calendar picker on each input. The script looks like this:
@section Scripts{
<script>
var Start = new dhtmlXCalendarObject("StartDate");
Start.setDateFormat("%d/%m/%Y %H:%i");
Start.showToday();
Start.attachEvent("onTimeChange", function (d) {
var DateText = Start.getDate(true)
document.getElementById("StartDate").value = DateText;
});
var End = new dhtmlXCalendarObject("EndDate");
End.setDateFormat("%d/%m/%Y %H:%i");
End.showToday();
End.attachEvent("onTimeChange", function (d) {
var DateText = End.getDate(true)
document.getElementById("EndDate").value = DateText;
});
</script>
}
Perhaps a suggestion is to use DateTime.TryParseExact method, which will validate the "String" representation of the date using your desired format, and will return an error when the string does not comply to your specified format. Here is code, note dateFormats are based on Australian Standard dates. You can of course add hours and minutes to this too.
Note parsedDate is a DateTime format. Usage of below is:
public void test(){
DateTime ParsedDate;
string SomeDate = "12-May-2017";
if(parseDate(SomeDate, out ParsedDate))
{
// Date was parsed successfully, you can now used ParsedDate, e.g.
Customer.Orders[0].DateRequired = ParsedDate;
}
else
{
// Throw an error
}
}
And the method declaration. Use either in static class, or directly in your class.
public static bool parseDate(string theDate, out DateTime parsedDate)
{
string[] dateFormats = { "d-M-yy", "d-MMM-yy", "d-MMM-yyyy", "d-M-yyyy", "d/M/yy", "d/M/yyyy", "yyyy-mm-dd" };
bool result = DateTime.TryParseExact(
theDate,
dateFormats,
new CultureInfo("en-AU"),
DateTimeStyles.None, out parsedDate);
return result;
} //Convert string-based date to DateTime. Uses a variety of parse templates
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With