Преобразование содержимого текстового элемента управления ASP.NET.text в формат даты / времени
Я пытаюсь вставить в базу данных - различные детали о событии. В текстовом поле asp.net используется Calendar Extender (поэтому всплывает маленький календарь и заполняет текстовое поле правильно отформатированной датой). Поле EventDate в моей базе данных Access имеет тип Дата / Время. Мне нужно преобразовать текст / строку в формат даты / времени
Я пробовал это до сих пор:
VB:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim oleDbConn As New OleDb.OleDbConnection(ConfigurationManager.ConnectionStrings("BookMeetConnString").ConnectionString) Dim SqlString As String = "Insert into Events(EventTitle,EventDescription,EventDate,EventCategory) Values (@f1,@f2,@f3,@f4)" Dim cmd As OleDbCommand = New OleDbCommand(SqlString, oleDbConn) Dim strDate As String = tb_eventdate.Text Dim dtfi As New System.Globalization.DateTimeFormatInfo dtfi.ShortDatePattern = "dd/MM/yyyy" dtfi.DateSeparator = "/" Dim objDate As DateTime = Convert.ToDateTime(strDate, dtfi) cmd.CommandType = CommandType.Text cmd.Parameters.AddWithValue("@f1", tb_eventtitle.Text) cmd.Parameters.AddWithValue("@f2", tb_eventdescription.Text) cmd.Parameters.AddWithValue("@f3", tb_eventdate.Text) cmd.Parameters.AddWithValue("@f4", dd_eventcategory.Text) oleDbConn.Open() cmd.ExecuteNonQuery() System.Threading.Thread.Sleep("2000") Response.Redirect("~/calendar.aspx") End Sub
Вот мой клиентский код только для справки:
<h1>Add An Event!<ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server"> </ajaxToolkit:ToolkitScriptManager> </h1> <p>Title of Event: <asp:TextBox ID="tb_eventtitle" runat="server"></asp:TextBox> </p> <p>Event Description: <asp:TextBox ID="tb_eventdescription" runat="server"></asp:TextBox> </p> <p>Event Date: <asp:TextBox ID="tb_eventdate" runat="server"></asp:TextBox> <ajaxToolkit:CalendarExtender ID="tb_eventdate_CalendarExtender" runat="server" TargetControlID="tb_eventdate"> </ajaxToolkit:CalendarExtender> </p> <p>Event Category: <asp:DropDownList ID="dd_eventcategory" runat="server" DataSourceID="SqlDataSource1" DataTextField="CategoryTitle" DataValueField="CategoryTitle"> </asp:DropDownList> </p> <p> <asp:Button ID="Button1" runat="server" Text="Submit" /> </p>
Когда я пытаюсь заполнить форму, я получаю эту ошибку:
Мои два вопроса:
- Что не так с приведенным выше кодом, и как мне успешно использовать класс DateTimeFormatInfo для преобразования строки в дату / время?
- В дополнение к этому, Calendar Extender вводит дату в текстовое поле в американском формате времени (MM/DD/YYYY), как я могу изменить это на британский (DD/MM/YYYY) формат (я не вижу очевидного свойства в диалоге свойств сделать это?)
Заранее спасибо за ваши ответы!
Адам
РЕДАКТИРОВАТЬ: обновленный код ниже:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim oleDbConn As New OleDb.OleDbConnection(ConfigurationManager.ConnectionStrings("BookMeetConnString").ConnectionString) Dim SqlString As String = "Insert into Events(EventTitle,EventDescription,EventDate,EventCategory) Values (@f1,@f2,@f3,@f4)" Dim cmd As OleDbCommand = New OleDbCommand(SqlString, oleDbConn) cmd.CommandType = CommandType.Text cmd.Parameters.AddWithValue("@f1", tb_eventtitle.Text) cmd.Parameters.AddWithValue("@f2", tb_eventdescription.Text) cmd.Parameters.AddWithValue("@f3", DateTime.ParseExact(tb_eventdate.Text, "dd/MM/yyyy", CultureInfo.InvariantCulture)) cmd.Parameters.AddWithValue("@f4", dd_eventcategory.Text) oleDbConn.Open() cmd.ExecuteNonQuery() System.Threading.Thread.Sleep("2000") Response.Redirect("~/calendar.aspx") End Sub
2 ответа
Я бы порекомендовал вам использовать DateTime.ParseExact
статический метод, особенно это oveload:
DateTime.ParseExact(textBox.Text, "dd/MM/yyyy",
CultureInfo.InvariantCulture
)
Это проанализирует ваш текст в соответствии с указанным вами форматом ("dd/MM/yyyy"
в настоящее время дело важно, так как mm
минуты в отличие от MM
месяцы). Использование CultureInfo.InvariantCulture
гарантирует, что разделители даты будут извлечены из строки формата (второй параметр). Я заметил, что если используется текущая культура, она переопределяет некоторые аспекты строки формата, которую вы передаете ParseExact
,
Заметка на КультурИнфо
Инвариантная культура хороша также по той причине, что ваша локальная среда разработки может иметь настройку региональной информации, отличную от среды развертывания. Обычно.NET использует текущую культуру во всех .ToString
вызовы и неявное форматирование или разбор. При явном форсировании форматной и культурной инвариантности вы менее подвержены проблемам, которые не можете воспроизвести локально, но существуют в производственном приложении.
Примечание о форматах даты / времени
Предполагается, что при точном разборе формат даты и времени будет строго соответствовать формату ввода. Затем вы должны принять во внимание следующие примеры:
dd
соответствует только двузначным дням. Так"dd/MM/yyyy"
это будет соответствовать"01/01/2013"
, но не получится"1/1/2013"
потому что он ожидает точное количество цифр для части дня. Если вы не хотите использовать начальные нули, используйте:d/M/yyyy
вместо. Одна буква означает одну цифру для дней меньше10
и две цифры для остальных.MM
соответствует двузначному месяцу, так что все, что относится кdd
противd
то же самое в течение нескольких месяцев.yyyy
ожидает, что год будет в 4 цифры. Если вы используете двузначный год, используйтеyy
вместо.
Замечание о некоторых провайдерах ADO.NET
Как оказывается в случае с MS Access, правильно проанализированный объект даты и времени не достаточен для того, чтобы запрос работал. В настоящее время следующий код
cmd.Parameters.AddWithValue(...)
используется для добавления параметров в запрос. Однако в этом подходе пропускается передача информации поставщику базы данных ADO.NET, который сообщает, какой тип базы данных использовать для параметра. Я читал на некоторых форумах, что MS Access/OleDb не способен разрешить правильный тип во всех случаях. Поэтому я рекомендую следующий подход:
Dim prm as OleDbParameter = _
New OleDbParameter("@dateTimeParameterName", OleDbType.DateTime)
prm.Value = value 'value is an instance of `System.DateTime` parsed
'from the input
cmd.Parameters.Add(prm)
Приведенный выше код позволяет явно указывать тип базы данных параметров, поэтому драйвер OleDb теперь способен правильно передавать DateTime
Объект для базы данных MS Access.
Я использовал ниже короткий код:
//myDateValue is System.DateTime object.
OleDbCommand commandObject = new OleDbCommand();
...
commandObject.Parameters.Add(new OleDbParameter("@ADDED_DATE_PARAM", OleDbType.Date).Value = myDateValue);