Преобразование содержимого текстового элемента управления 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>

Когда я пытаюсь заполнить форму, я получаю эту ошибку:

ошибка даты и времени

Мои два вопроса:

  1. Что не так с приведенным выше кодом, и как мне успешно использовать класс DateTimeFormatInfo для преобразования строки в дату / время?
  2. В дополнение к этому, 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);
Другие вопросы по тегам