none
¿Validar fecha?

    Question

  • Hola. Tengo un maskedTextBox en el cual he puesto dentro de su evento "validate" lo siguiente para validar si lo que han ingresado es o no una fecha:

    If(IsDate(mtbFechaNacimiento.Text)) = False Then
    MsgBox("Fecha errónea")
    Else
    MsgBox("Fecha correcta")
    End If

    Si bien esto me reconoce los meses y días mal ingresados, no me reconoce los años... Por ejemplo, si pongo 01/01/097 o 01/04/198 No me da el mensaje de erróneo...

    ¿Cómo consigo solucionar esto?

    Gabriela
    Wednesday, July 29, 2009 2:51 AM

Answers

  • "Gabriela Calligaro Bosetti" preguntó:

    > Si bien esto me reconoce los meses y días mal ingresados,
    > no me reconoce los años... Por ejemplo, si pongo
    > 01/01/097 o 01/04/198 No me da el mensaje de erróneo...
    >
    > ¿Cómo consigo solucionar esto?

    Esos años son correctos para un valor DateTime. Lo que tienes que hacer es establecer una fecha mínima y máxima permitidas, y ver si el valor escrito en el control está dentro de dichas fechas:


        Private Sub MaskedTextBox1_Validating( _
            ByVal sender As Object, _
            ByVal e As System.ComponentModel.CancelEventArgs) _
            Handles mtbFechaNacimiento.Validating

            Dim fechaMinima As New DateTime(1900, 1, 1)
            Dim fechaMaxima As DateTime = DateTime.Now

            Try
                ' Obtenemos el texto del control
                '
                Dim fecha As DateTime = CDate(mtbFechaNacimiento.Text)

                If (fecha < fechaMinima) OrElse (fecha > fechaMaxima) Then
                    MessageBox.Show("Fecha errónea")
                    'e.Cancel = True
                End If

            Catch ex As Exception
                'e.Cancel = True
            End Try

        End Sub

    Si quieres cancelar el evento, quita los comentarios donde se establece a True el valor de la propiedad Cancel.

    Se entiende que el valor de la propiedad TextMaskFormat del control MaskedTextBox incluye los literales de la máscara:


          mtbFechaNacimiento.TextMaskFormat = MaskFormat.IncludeLiterals
          mtbFechaNacimiento.Mask = "90/90/9900"


    Enrique Martínez [MS MVP - VB]
    Wednesday, July 29, 2009 3:14 PM
  • "Gabriela Calligaro Bosetti" escribió:

    > Sigo con el mismo problema cuando pongo, por ejemplo 01/03/_198

    Si has seguido al pié de la letra el ejemplo que te he puesto, esa fecha será ERRÓNEA, porque no está comprendida entre el 01/01/1900 y la fecha de hoy, 29/07/2009.

    Si la máscara y el valor de la propiedad TextMaskFormat son las que yo he indicado en mi anterior respuesta, el valor de la propiedad Text del control será "01/03/ 198", por tanto, fecha ERRÓNEA. :-)

    Enrique Martínez [MS MVP - VB]
    Wednesday, July 29, 2009 4:52 PM
  • ¡Jeje! Gabriela, si es que creo que lo estás haciendo al revés. :-)))

    Si tu intención es registrar aquellas personas mayores de 18 años, no puedes validar la fecha cuando ésta no está dentro del intervalo permitido entre la fecha mínima y la máxima:

     Public Function ValidarFechaNac() As Boolean

            txtFechaNac.TextMaskFormat = MaskFormat.IncludeLiterals
            fechaNac = CDate(txtFechaNac.Text)


            Dim fechaMaxima As DateTime = Now.Date
            Dim fechaMinima As New DateTime(1900, 1, 1)


            If (fechaNac < fechaMinima) OrElse (fechaNac > fechaMaxima) Then

                ' FECHA NO VÁLIDA

                Return False

            Else

                ' FECHA VÁLIDA

                If IsDate(txtFechaNac.Text) = False Then
                    MsgBox("La fecha ingresada no es válida", MsgBoxStyle.Exclamation, "Error")
                    txtFechaNac.Text = ""
                Else
                    If ((DateDiff(DateInterval.Day, CDate(txtFechaNac.Text), Now.Date) / 365) < 18.0) Then
                        MsgBox("No se permite registrar a personas menores de 18 años.", MsgBoxStyle.Exclamation, "Error")
                        Return False
                    Else
                        Return True
                    End If
                End If


            End If


        End Function


    Enrique Martínez [MS MVP - VB]
    Thursday, July 30, 2009 2:04 PM
  • "Gabriela Calligaro Bosetti" escribió:

    >  If ((DateDiff(DateInterval.Day, CDate(txtFechaNac.Text), Now.Date) / 365) < 18.0) Then

    Ahora que estoy repasando la conversación, observo que el método que utilizas para averiguar si una persona es mayor de 18 años, no es del todo correcto, porque si ejecutamos el código a fecha de hoy (31/07/2009), estarás haciendo mayor de edad a aquellas personas que hayan nacido hasta el día 05 de Agosto de 1991, por tanto no es correcto, porque una persona nacida el día 03/08/1991, todavía le faltan tres días para cumplir los 18 años de edad. ;-)

    Entiendo que hay otros métodos más sencillos para verificar si una persona ha cumplido 18 años de edad, como por ejemplo, la siguiente función:

         Private Overloads Function EsMayorDeEdad(ByVal fechaNacimiento As DateTime) As Boolean

            Dim fechaMinima As DateTime = New DateTime(1900, 1, 1)
            Dim hoy As DateTime = DateTime.Now

            ' Si la fecha de nacimiento no está comprendida entre la fecha
            ' mínima y la fecha de hoy, abandonamos el procedimiento.
            '
            If (fechaNacimiento < fechaMinima) OrElse _
               (fechaNacimiento > hoy) Then Return False

            ' Obtenemos el número de años de diferencia.
            '
            Dim edad As Int32 = hoy.Year - fechaNacimiento.Year

            Select Case edad
                Case Is < 18
                    ' Es menor de edad
                    Return False

                Case Is > 18
                    ' Es mayor de edad
                    Return True

                Case Else
                    ' Este año cumple la edad requerida. Compruebo
                    ' si los ha cumplido a día de hoy.
                    '
                    If hoy.Month < fechaNacimiento.Month Then
                        ' Todavía no ha cumplido los años
                        Return False

                    ElseIf hoy.Month > fechaNacimiento.Month Then
                        ' Ya ha cumplido los años
                        Return True

                    Else
                        ' En este més cumple los años. Compruebo
                        ' si ha llegado el día del cumpleaños.
                        '
                        If hoy.Day < fechaNacimiento.Day Then
                            ' No ha llegado su cumpleaños.
                            Return False

                        Else
                            ' O es su cumpleaños, o éste ya ha pasado.
                            Return True
                        End If

                    End If

            End Select

         End Function

    Ahora, verificarías si una persona es mayor o menor de 18 años de la siguiente manera:

           Try
                Dim fecha As DateTime = Convert.ToDateTime(MaskedTextBox1.Text)

                MessageBox.Show(EsMayorDeEdad(fecha).ToString)

            Catch ex As Exception
                MaskedTextBox1.Text = String.Empty

           End Try

    ¡No sé! Yo lo veo menos complicado. :-)


    Enrique Martínez [MS MVP - VB]
    Friday, July 31, 2009 3:53 PM

All replies

  • Aqui te dejo un link donde se explica un poco de esta funcion

    http://msdn.microsoft.com/es-es/library/00wf8zk9.aspx


    Saludos.

    Melvin.

    Todo Es posible si se studia con exfuerso no importando los de mas Dios esta con nosotros y no hay mas sabiduria que la de Dios, Everything is posible if you study a lot wiht esforce , God Loves us and there isn't anybody like God.... Melvin Saludos
    Wednesday, July 29, 2009 7:26 AM
  • Hola
    ¿Por que no usar un control DateTimeAndPicker?
    Si la respuesta es correcta, marcala como correcta.
    Tambien puedes votar como util si te fue de ayuda
    DCE 5 ESTRELLAS PLATINO
    Wednesday, July 29, 2009 1:11 PM
  • "Gabriela Calligaro Bosetti" preguntó:

    > Si bien esto me reconoce los meses y días mal ingresados,
    > no me reconoce los años... Por ejemplo, si pongo
    > 01/01/097 o 01/04/198 No me da el mensaje de erróneo...
    >
    > ¿Cómo consigo solucionar esto?

    Esos años son correctos para un valor DateTime. Lo que tienes que hacer es establecer una fecha mínima y máxima permitidas, y ver si el valor escrito en el control está dentro de dichas fechas:


        Private Sub MaskedTextBox1_Validating( _
            ByVal sender As Object, _
            ByVal e As System.ComponentModel.CancelEventArgs) _
            Handles mtbFechaNacimiento.Validating

            Dim fechaMinima As New DateTime(1900, 1, 1)
            Dim fechaMaxima As DateTime = DateTime.Now

            Try
                ' Obtenemos el texto del control
                '
                Dim fecha As DateTime = CDate(mtbFechaNacimiento.Text)

                If (fecha < fechaMinima) OrElse (fecha > fechaMaxima) Then
                    MessageBox.Show("Fecha errónea")
                    'e.Cancel = True
                End If

            Catch ex As Exception
                'e.Cancel = True
            End Try

        End Sub

    Si quieres cancelar el evento, quita los comentarios donde se establece a True el valor de la propiedad Cancel.

    Se entiende que el valor de la propiedad TextMaskFormat del control MaskedTextBox incluye los literales de la máscara:


          mtbFechaNacimiento.TextMaskFormat = MaskFormat.IncludeLiterals
          mtbFechaNacimiento.Mask = "90/90/9900"


    Enrique Martínez [MS MVP - VB]
    Wednesday, July 29, 2009 3:14 PM
  • Sigo con el mismo problema cuando pongo, por ejemplo 01/03/_198

    Probaré con el DateTimeAndPicker, pero la verdad que prefiero el masked...

    ¡¡Muchas gracias!!

    Gabriela
    Wednesday, July 29, 2009 4:03 PM
  • "Gabriela Calligaro Bosetti" escribió:

    > Sigo con el mismo problema cuando pongo, por ejemplo 01/03/_198

    Si has seguido al pié de la letra el ejemplo que te he puesto, esa fecha será ERRÓNEA, porque no está comprendida entre el 01/01/1900 y la fecha de hoy, 29/07/2009.

    Si la máscara y el valor de la propiedad TextMaskFormat son las que yo he indicado en mi anterior respuesta, el valor de la propiedad Text del control será "01/03/ 198", por tanto, fecha ERRÓNEA. :-)

    Enrique Martínez [MS MVP - VB]
    Wednesday, July 29, 2009 4:52 PM
  • Yo creo que  la respuesta de Softjaen es correcta y  Bueno  marcala como Correcta  Puesto que es una respuesta muy Explicada y no se puede Dudar que funciona.....

    : )


    Saludos.

    Melvin.
    Todo Es posible si se studia con exfuerso no importando los de mas Dios esta con nosotros y no hay mas sabiduria que la de Dios, Everything is posible if you study a lot wiht esforce , God Loves us and there isn't anybody like God.... Melvin Saludos
    Wednesday, July 29, 2009 8:01 PM
  • ¡Jeje! Gabriela, si es que creo que lo estás haciendo al revés. :-)))

    Si tu intención es registrar aquellas personas mayores de 18 años, no puedes validar la fecha cuando ésta no está dentro del intervalo permitido entre la fecha mínima y la máxima:

     Public Function ValidarFechaNac() As Boolean

            txtFechaNac.TextMaskFormat = MaskFormat.IncludeLiterals
            fechaNac = CDate(txtFechaNac.Text)


            Dim fechaMaxima As DateTime = Now.Date
            Dim fechaMinima As New DateTime(1900, 1, 1)


            If (fechaNac < fechaMinima) OrElse (fechaNac > fechaMaxima) Then

                ' FECHA NO VÁLIDA

                Return False

            Else

                ' FECHA VÁLIDA

                If IsDate(txtFechaNac.Text) = False Then
                    MsgBox("La fecha ingresada no es válida", MsgBoxStyle.Exclamation, "Error")
                    txtFechaNac.Text = ""
                Else
                    If ((DateDiff(DateInterval.Day, CDate(txtFechaNac.Text), Now.Date) / 365) < 18.0) Then
                        MsgBox("No se permite registrar a personas menores de 18 años.", MsgBoxStyle.Exclamation, "Error")
                        Return False
                    Else
                        Return True
                    End If
                End If


            End If


        End Function


    Enrique Martínez [MS MVP - VB]
    Thursday, July 30, 2009 2:04 PM
  • ¡¡Ya lo tengo!! Era cuestión de los operadores lógicos... pero aun así tengo una última duda: ¿Cómo hago que DateDiff me compare los resultados en formato inglés? Me explico: Como tengo que hacer consultas SQL a la base de datos con fechas, y estoy trabajando con Access 2003, no me queda otro remedio que tomar las fechas en formato "MM/DD/YYYY", en lugar de nuestro "DD/MM/YYYY". El siguiente código funciona bien, pero si ingreso por ejemplo "02/29/2008" me da error de conversiòn de datos... Supongo porque trabaja con "DD/MM/YYYY" y yo con "MM/DD/YYYY"... ¿Ayuda?


    Private Sub txtFechaNac_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles txtFechaNac.Validating

            If IsDate(txtFechaNac.Text) Then
                If ValidarFechaNac(txtFechaNac.Text) = False Then
                    txtFechaNac.Text = ""
                End If
            Else
                MsgBox("La fecha ingresada no es válida", MsgBoxStyle.Exclamation = MsgBoxStyle.Exclamation, "Error")
            End If

        End Sub



        Public Function ValidarFechaNac(ByVal fechaNac As Date) As Boolean

            Dim fechaMaxima As DateTime = Now.Date
            Dim fechaMinima As New DateTime(1900, 1, 1)

            If (fechaNac > fechaMinima) And (fechaNac < fechaMaxima) Then

                If IsDate(txtFechaNac.Text) = False Then
                    MsgBox("La fecha ingresada no es válida", MsgBoxStyle.Exclamation, "Error")
                    txtFechaNac.Text = ""
                Else
                    If ((DateDiff(DateInterval.Day, CDate(txtFechaNac.Text), Now.Date) / 365) < 18.0) Then
                        MsgBox("No se permite registrar a personas menores de 18 años.", MsgBoxStyle.Exclamation, "Error")
                        Return False
                    Else
                        Return True
                    End If
                End If

            Else
                MsgBox("La fecha ingresada no es válida", MsgBoxStyle.Exclamation = MsgBoxStyle.Exclamation, "Error")
            End If

    End Function

    Gabriela
    Thursday, July 30, 2009 2:07 PM
  • Solucionado, era puro problema de Lògica. Gracias SoftJaèn
    Gabriela
    Thursday, July 30, 2009 3:00 PM
  • "Gabriela Calligaro Bosetti" preguntó:

    > ¿Cómo hago que DateDiff me compare los resultados en formato inglés?
    >
    > Me explico: Como tengo que hacer consultas SQL a la base de datos con
    > fechas, y estoy trabajando con Access 2003, no me queda otro remedio
    > que tomar las fechas en formato "MM/DD/YYYY", en lugar de nuestro
    > "DD/MM/YYYY". El siguiente código funciona bien, pero si ingreso por
    > ejemplo "02/29/2008" me da error de conversiòn de datos... Supongo
    > porque trabaja con "DD/MM/YYYY" y yo con "MM/DD/YYYY"... ¿Ayuda?

    Si lo deseas, puedes especificar una referencia cultural de Inglés de Estados Unidos al método Convert.ToDateTime para que reconozca las fechas en formato americano, pero en éste supuesto, si el usuario es español y escribe 29/02/2008, obtendrás una excepción como un camión de grande. Es decir, te sucederá justo lo contrario que ahora te está pasando cuando el usuario español escribe una fecha en formato americano, como por ejemplo 02/29/2008.

    Tu tienes que dejar que el usuario introduzca las fechas como él desee, de acuerdo con la configuración regional que tenga establecida en su sistema operativo. Tu misión es capturar la posible excepción que se pueda producir a la hora de convertir la fecha es un valor DateTime válido. Si se produce la excepción es porque el usuario ha introducido la fecha que le ha venido en gana. Cuando se canse de recibir mensajes de error, verás como introduce correctamente la fecha. :-)

    Como bien podrás comprender, un usuario francés o ruso, no va a especificar las fechas en formato americano; las escribirá de acuerdo al formato de su idioma.

    Y en lo que respeta a las fechas existentes en la base de datos, tu misión será SIEMPRE, recalco SIEMPRE, utilizar el formato americano (meses/días/año), tanto para seleccionar datos como para actualizar los mismos.

    Enrique Martínez [MS MVP - VB]
    Thursday, July 30, 2009 3:28 PM
  • "Gabriela Calligaro Bosetti" escribió:

    >  If ((DateDiff(DateInterval.Day, CDate(txtFechaNac.Text), Now.Date) / 365) < 18.0) Then

    Ahora que estoy repasando la conversación, observo que el método que utilizas para averiguar si una persona es mayor de 18 años, no es del todo correcto, porque si ejecutamos el código a fecha de hoy (31/07/2009), estarás haciendo mayor de edad a aquellas personas que hayan nacido hasta el día 05 de Agosto de 1991, por tanto no es correcto, porque una persona nacida el día 03/08/1991, todavía le faltan tres días para cumplir los 18 años de edad. ;-)

    Entiendo que hay otros métodos más sencillos para verificar si una persona ha cumplido 18 años de edad, como por ejemplo, la siguiente función:

         Private Overloads Function EsMayorDeEdad(ByVal fechaNacimiento As DateTime) As Boolean

            Dim fechaMinima As DateTime = New DateTime(1900, 1, 1)
            Dim hoy As DateTime = DateTime.Now

            ' Si la fecha de nacimiento no está comprendida entre la fecha
            ' mínima y la fecha de hoy, abandonamos el procedimiento.
            '
            If (fechaNacimiento < fechaMinima) OrElse _
               (fechaNacimiento > hoy) Then Return False

            ' Obtenemos el número de años de diferencia.
            '
            Dim edad As Int32 = hoy.Year - fechaNacimiento.Year

            Select Case edad
                Case Is < 18
                    ' Es menor de edad
                    Return False

                Case Is > 18
                    ' Es mayor de edad
                    Return True

                Case Else
                    ' Este año cumple la edad requerida. Compruebo
                    ' si los ha cumplido a día de hoy.
                    '
                    If hoy.Month < fechaNacimiento.Month Then
                        ' Todavía no ha cumplido los años
                        Return False

                    ElseIf hoy.Month > fechaNacimiento.Month Then
                        ' Ya ha cumplido los años
                        Return True

                    Else
                        ' En este més cumple los años. Compruebo
                        ' si ha llegado el día del cumpleaños.
                        '
                        If hoy.Day < fechaNacimiento.Day Then
                            ' No ha llegado su cumpleaños.
                            Return False

                        Else
                            ' O es su cumpleaños, o éste ya ha pasado.
                            Return True
                        End If

                    End If

            End Select

         End Function

    Ahora, verificarías si una persona es mayor o menor de 18 años de la siguiente manera:

           Try
                Dim fecha As DateTime = Convert.ToDateTime(MaskedTextBox1.Text)

                MessageBox.Show(EsMayorDeEdad(fecha).ToString)

            Catch ex As Exception
                MaskedTextBox1.Text = String.Empty

           End Try

    ¡No sé! Yo lo veo menos complicado. :-)


    Enrique Martínez [MS MVP - VB]
    Friday, July 31, 2009 3:53 PM