none
Como dar formato de fecha "dd/MM/yyyy" a un campo en una sentencia SQL ?

    Question

  • Buenas tardes;

    Estoy tratando de leer un campo llamado fecha en una BD Access desde una sentencia SQL en vb.net por supuesto. resulta que las fechas las guardo con formato "yyyy/MM/dd", (sin "/") pero para mostrarla en el datagridview debo mostrarla "dd/MM/yyyy", entonces la sentencia es la siguiente...

    ... SELECT fecha from facturas WHERE .......

    la idea es que en esa misma sentencia tratar de darle formato a dicho campo para mostrar en el datagridview.

    el campo en la BD es tipo string y los registros están sin "/" ejemplo...


    Silvio Diaz


    • Edited by silvio.dol Wednesday, January 02, 2013 7:24 PM
    Wednesday, January 02, 2013 7:22 PM

Answers

  • "silvio.dol" escribió:

    > Gracias por el código, pero ya lo había utilizado y las consultas
    > funcionaban pero dentro de un mismo mes, cuando elegía un rango de
    > fechas con mas de un mes ahí entraba el error, no me mostraba los
    > registros de meses anteriores.

    ¿Como dices? ¿Que no funciona cuando el rango de fechas supera el mes? Me parece a mí que ni tan siquiera te has preocupado en probar el ejemplo que te he indicado en mi anterior mensaje.:-D

    Vamos a seleccionar todas las facturas correspondientes al año 2012:

     SELECT * FROM Facturas
     WHERE Fecha BETWEEN #01/01/2012# AND #12/31/2012#

    Aunque si utilizas dos controles DateTimePicker, en el de fecha de inicio escribirías 01/01/2012 y en el de fin el valor 31/12/20012, y la función ObtenerRangoFechas te devolverá un objeto DataTable con todas las facturas existentes en el rango especificado.

    Prueba primero el código y después indicas si obtienes un error.

    > Después de darle un giro al formato de campo fecha y guardar  fechas
    > como un único numero entero ahora mi aplicación se ha independizado
    > de la configuración regional de la pc ...

    Pero, ¿qué tiene que ver el tipo de dato Fecha/Hora de Access, o el tipo DateTime de SQL Server, con la configuración regional que tenga establecido el usuario en su sistema operativo?

    Te comento que los valores Fecha/Hora de Access, o DateTime de SQL Server, no se guardan como 03/12/2012 03:13:55; se guardan como valores de 8 bytes (64 bits) de los cuales los primeros 4 bytes son para el valor de la fecha, y los otros 4 bytes para el valor de la hora. Otra cosa muy diferente es la representación visual o textual que se haga de esos 64 bits, que es como los humanos solemos ver normalmente las fechas. :-)

    > y eso no es todo, lo mejor es que funciona y es mucho mas rápido
    > porque no tiene conversiones ni se toma en cuenta días, mes... etc.
    >

    No sé cómo puedes decir que funciona más rápido cuando tienes que convertir los valores alfanuméricos en valores System.DateTime, siempre y cuando el valor "20121231" quieras representarlo como la fecha correspondiente al día 31/12/2012. ¿?

    > puedo migrar a Mysql, Sqlserver, oracle sin producir grandes cambios
    > a diferencia que atar la programación con un formato Access que luego
    > tenga que migrar a otro motor de base de datos y generarme un gran
    > dolor de cabeza.

    A MySql u Oracle lo ignoro, pero a SQL Server lo podrás migrar porque aquí sí se insertan los valores en un campo DateTime utilizando el formato yyyymmdd (AñoMesDía), aunque no quiere decir que se guarden en ese formato, porque como he indicado anteriormente, se guarda como un número binario de 8 bytes. Pero si el tipo de dato de la base de Access es de Fecha/Hora, te aseguro que no vas a tener problemas para migrarlo a un campo DateTime de una base de datos de SQL Server.

    > ... y los invito a que lo prueben.

    Te agredezco la invitación que me ofreces, pero estoy muy contento y a gusto grabando las fechas en un campo de Fecha/Hora en Access y DateTime en SQL Server. :-D

    > lo único es que para guardar la fecha primero debemos dar formato
    > "yyyy/MM/dd" y posterior mente le quitarles los "/" con la función
    > "Replace" y ahí tenemos la fecha como un único numero, lista para
    > guardarla.

    Eso es ¡¡MUCHO TRABAJO!!

    > Lo que necesito ahora es darle formato a la columna del datagridview
    > para que dicha fecha que esta en la DB como un numero entero sea
    > legible para los usuarios con formato de 20130103 a que se muestre
    > 03/01/2013 en el datagridview.

    En mi anterior mensaje ya te he indicado lo que tienes que hacer: cambiar el tipo de dato del campo de la tabla de Access para que en lugar de ser del tipo Texto, sea del tipo Fecha/Hora. Todo lo que no sea hacer eso son ganas de complicarse la vida de una manera innecesaria. Pero comprendo que para gustos están los colores. ;-)


    Enrique Martínez
      [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, activa la instrucción Option Strict.

    • Marked as answer by silvio.dol Thursday, January 03, 2013 6:59 PM
    Thursday, January 03, 2013 3:40 PM

All replies

  • Podrias usar la funcion format de Access. Algo como esto:

    SELECT Format([fecha],'dd/MM/yyyy') AS Fecha
    FROM Factura

    Te adjunto este link:

    http://webcheatsheet.com/sql/access_functions/format.php

    Saludos


    Luis Muñoz Hidalgo
    Mi Blog
    Desarrollador de Software
    Trujillo-Perú

    Wednesday, January 02, 2013 7:58 PM
  • hola

    la primer pregunta es porque guardas la fecha de esta forma en la db, la verdad no lo veo correcto, porque seguramente el campo no sea del tipo datetime

    despues el formato porque quieres darlo en el sql server ? si podrias aplciarlo en codigo .net de forma directo usando

    Dim fechaentrada As DateTime = DateTime.ParseExact(CStr(row("campofecha")), "yyyyMMdd", CultureInfo.InvariantCulture)

    con eso tendrias el datetime en .net para aplciar el formato que quieras

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    Wednesday, January 02, 2013 8:09 PM
  • Ya aplique la consulta y parece que es la correcta sintaxis pero aun no trabaja, sospecho que es porque el tipo de datos del campo fecha en la BD es de tipo texto. talvez hay que convertirlo a tipo DATE en la sentencia SQL. tienes alguna idea de como convertirlo en la misma sentencia?.


    Silvio Diaz


    • Edited by silvio.dol Wednesday, January 02, 2013 8:25 PM
    Wednesday, January 02, 2013 8:24 PM
  • Hola Leandro,  voy a probar el código que me has dado y luego te cuento que tal trabaja gracias amigo...

    y eh guardado la fecha de esta forma porque tenia problemas con los rengos de fechas en Access y ahora funciona muy bien. solo que me pone las fechas 20130103 en el datagridview y lo que quiero es leer la fecha y pasarle el formato a dicho control para que se vea 03/01/2013. pero como te dije voy a probar tu código a ver que tal.


    Silvio Diaz


    • Edited by silvio.dol Wednesday, January 02, 2013 8:34 PM
    Wednesday, January 02, 2013 8:28 PM
  • "silvio.dol" escribió:

    > resulta que las fechas las guardo con formato "yyyy/MM/dd",
    > (sin "/") pero para mostrarla en el datagridview debo
    > mostrarla "dd/MM/yyyy", ...
    >
    > ... y eh guardado la fecha de esta forma porque tenia
    > problemas con los rengos de fechas en Access

    Hola:

    Si aceptas un consejo, mejor será que te olvides de guardar las fechas en un campo de texto o alfanumérico, máxime si tu intención es mostrar posteriormente las supuestas fechas como valores DateTime válidos, porque siempre vas a tener que estar pendiente de aplicar un formato de fecha concreto.

    Si tienes problemas con los rangos de fechas, en primer lugar habría que ver la sintaxis de la consulta SQL que estás intentando ejecutar para saber el motivo de los problemas, porque para seleccionar un rango de fechas se utiliza el operador BETWEEN.

    Eso por un lado, y por otro, como estás utilizando una base de datos de Access, los valores de las fechas que deseamos especificar en la consulta SQL tienen que escribirse en formato americano (mes/día/año) y encerrados entre el carácter #, tal y como muestra el siguiente ejemplo:

      ' Seleccionamos todas las facturas correspondientes
      ' al mes de diciembre/2012
      '
      SELECT * FROM Facturas
      WHERE Fecha BETWEEN #12/01/2012# AND #12/31/2012#

    Ahora vamos a aplicar ese ejemplo a tu proyecto de Visual Basic .net. Para ello insertarías en tu formulario o clase la siguiente función:

        Private Function ObtenerRangoFechas( _
         fechaInicio As DateTime, _
         fechaFin As DateTime) As DataTable
         
         Try
          ' Establecemos la conexión con la base de datos de Access
          Using cnn As New OleDbConnection(cadenaConexion)
           
           ' Creamos el comando
           Dim cmd As OleDbCommand = cnn.CreateCommand()
           
           ' Indicamos la consulta SQL que deseamos ejecutar
           cmd.CommandText = _
            "SELECT * FROM Facturas " & _
            "WHERE Fecha BETWEEN @fechaInicio AND @fechaFin"
           
           ' Agregamos los parámetros al comando, en el mismo
           ' orden en el que se han añadido.
           cmd.Parameters.AddWithValue("@fechaInicio", fechaInicio)
           cmd.Parameters.AddWithValue("@fechaFin", fechaFin)
           
           ' Creamos el adaptador de datos
           Dim da As New OleDbDataAdapter(cmd)
           
           ' Creamos un nuevo objeto DataTable
           Dim dt As New DataTable("FacturasPorFecha")
           
           ' Rellenamos el objeto DataTable
           da.Fill(dt)
           
           ' Devolvemos el objeto DataTable
           Return dt
           
          End Using
          
         Catch
          ' Devolvemos la excepción al procedimiento llamador
          Throw
          
         End Try
         
        End Function

    Está claro que en alguna parte deberás tener definida la variable 'cadenaConexion', que como su nombre indica, contendrá la cadena de conexión completa con la base de datos de Access a la cual deseas conectarte.

    Vamos a imaginar que tanto la fecha de inicio como de fin las tomas de dos controles DataTimePicker. Rellenarías de datos tu control DataGridView llamando a la función anterior de la siguiente manera:

      Try
       ' Fecha de inicio. Tomamos solamente el
       ' valor de la fecha, sin la hora
       Dim fecha1 As DateTime = DateTimePicker1.Value.Date
       
       ' Fecha final
       Dim fecha2 As DateTime = DateTimePicker2.Value.Date
       
       ' Rellenamos el control DataGridView
       DataGridView1.DataSource = ObtenerRangoFechas(fecha1, fecha2)
                
      Catch ex As Exception
       ' Se ha producido un error
       MessageBox.Show(ex.Message)
       
      End Try

    También podrías especificar las fechas creando dos nuevos valores DateTime:

      ' Fecha de inicio.
      Dim fecha1 As New DateTime(2012, 12, 1)
      
      ' Fecha final
      Dim fecha2 As New DateTime(2012, 12, 31)

    Digamos que ésta es la manera correcta y "certificada" de seleccionar un rango de fechas en una base de datos de Access, SQL Server o de cualquier otro motor de datos, cuyo lenguaje SQL acepte el operador BETWEEN. ;-)

    Un saludo y ¡Feliz Año Nuevo!


    Enrique Martínez
      [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, activa la instrucción Option Strict.


    Thursday, January 03, 2013 9:22 AM
  • Gracias por el código, pero ya lo había utilizado y las consultas funcionaban pero dentro de un mismo mes, cuando elegía un rango de fechas con mas de un mes ahí entraba el error, no me mostraba los registros de meses anteriores.

    Los motivos por el cual decidí utilizar la fecha con un campo de DB tipo texto y como un numero entero son las siguientes:

    Después de darle un giro al formato de campo fecha y guardar  fechas como un único numero entero ahora mi aplicación se ha independizado de la configuración regional de la pc y el formato de fecha que este configurado por defecto no afecta las fechas de la aplicacion y eso es un gran alivio para mi porque puedo instalar mi aplicación en cualquier pc de cualquier parte del mundo.

    y eso no es todo, lo mejor es que funciona y es mucho mas rápido porque no tiene conversiones ni se toma en cuenta días, mes... etc.

    puedo migrar a Mysql, Sqlserver, oracle sin producir grandes cambios a diferencia que atar la programación con un formato Access que luego tenga que migrar a otro motor de base de datos y generarme un gran dolor de cabeza.

    se que ustedes son los expertos pero por lógica creo que este método es maravilloso por lo antes mencionado y los invito a que lo prueben.

    lo único es que para guardar la fecha primero debemos dar formato "yyyy/MM/dd" y posterior mente le quitarles los "/" con la función "Replace" y ahí tenemos la fecha como un único numero, lista para guardarla.

    Lo que necesito ahora es darle formato a la columna del datagridview para que dicha fecha que esta en la DB como un numero entero sea legible para los usuarios con formato de 20130103 a que se muestre 03/01/2013 en el datagridview.

    Quien pueda ayudarme con el formato de la fecha ya sea en la query o dándole el formato en la columna de datagridview seria de mucha ayuda... y luego les dejare el código para que prueben la idea y se eviten tantos inconvenientes.


    Silvio Diaz

    Thursday, January 03, 2013 2:49 PM
  • "silvio.dol" escribió:

    > Gracias por el código, pero ya lo había utilizado y las consultas
    > funcionaban pero dentro de un mismo mes, cuando elegía un rango de
    > fechas con mas de un mes ahí entraba el error, no me mostraba los
    > registros de meses anteriores.

    ¿Como dices? ¿Que no funciona cuando el rango de fechas supera el mes? Me parece a mí que ni tan siquiera te has preocupado en probar el ejemplo que te he indicado en mi anterior mensaje.:-D

    Vamos a seleccionar todas las facturas correspondientes al año 2012:

     SELECT * FROM Facturas
     WHERE Fecha BETWEEN #01/01/2012# AND #12/31/2012#

    Aunque si utilizas dos controles DateTimePicker, en el de fecha de inicio escribirías 01/01/2012 y en el de fin el valor 31/12/20012, y la función ObtenerRangoFechas te devolverá un objeto DataTable con todas las facturas existentes en el rango especificado.

    Prueba primero el código y después indicas si obtienes un error.

    > Después de darle un giro al formato de campo fecha y guardar  fechas
    > como un único numero entero ahora mi aplicación se ha independizado
    > de la configuración regional de la pc ...

    Pero, ¿qué tiene que ver el tipo de dato Fecha/Hora de Access, o el tipo DateTime de SQL Server, con la configuración regional que tenga establecido el usuario en su sistema operativo?

    Te comento que los valores Fecha/Hora de Access, o DateTime de SQL Server, no se guardan como 03/12/2012 03:13:55; se guardan como valores de 8 bytes (64 bits) de los cuales los primeros 4 bytes son para el valor de la fecha, y los otros 4 bytes para el valor de la hora. Otra cosa muy diferente es la representación visual o textual que se haga de esos 64 bits, que es como los humanos solemos ver normalmente las fechas. :-)

    > y eso no es todo, lo mejor es que funciona y es mucho mas rápido
    > porque no tiene conversiones ni se toma en cuenta días, mes... etc.
    >

    No sé cómo puedes decir que funciona más rápido cuando tienes que convertir los valores alfanuméricos en valores System.DateTime, siempre y cuando el valor "20121231" quieras representarlo como la fecha correspondiente al día 31/12/2012. ¿?

    > puedo migrar a Mysql, Sqlserver, oracle sin producir grandes cambios
    > a diferencia que atar la programación con un formato Access que luego
    > tenga que migrar a otro motor de base de datos y generarme un gran
    > dolor de cabeza.

    A MySql u Oracle lo ignoro, pero a SQL Server lo podrás migrar porque aquí sí se insertan los valores en un campo DateTime utilizando el formato yyyymmdd (AñoMesDía), aunque no quiere decir que se guarden en ese formato, porque como he indicado anteriormente, se guarda como un número binario de 8 bytes. Pero si el tipo de dato de la base de Access es de Fecha/Hora, te aseguro que no vas a tener problemas para migrarlo a un campo DateTime de una base de datos de SQL Server.

    > ... y los invito a que lo prueben.

    Te agredezco la invitación que me ofreces, pero estoy muy contento y a gusto grabando las fechas en un campo de Fecha/Hora en Access y DateTime en SQL Server. :-D

    > lo único es que para guardar la fecha primero debemos dar formato
    > "yyyy/MM/dd" y posterior mente le quitarles los "/" con la función
    > "Replace" y ahí tenemos la fecha como un único numero, lista para
    > guardarla.

    Eso es ¡¡MUCHO TRABAJO!!

    > Lo que necesito ahora es darle formato a la columna del datagridview
    > para que dicha fecha que esta en la DB como un numero entero sea
    > legible para los usuarios con formato de 20130103 a que se muestre
    > 03/01/2013 en el datagridview.

    En mi anterior mensaje ya te he indicado lo que tienes que hacer: cambiar el tipo de dato del campo de la tabla de Access para que en lugar de ser del tipo Texto, sea del tipo Fecha/Hora. Todo lo que no sea hacer eso son ganas de complicarse la vida de una manera innecesaria. Pero comprendo que para gustos están los colores. ;-)


    Enrique Martínez
      [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, activa la instrucción Option Strict.

    • Marked as answer by silvio.dol Thursday, January 03, 2013 6:59 PM
    Thursday, January 03, 2013 3:40 PM
  • lo único es que para guardar la fecha primero debemos dar formato "yyyy/MM/dd" y posterior mente le quitarles los "/" con la función "Replace" y ahí tenemos la fecha como un único numero, lista para guardarla.

    porque haces eso si podrias aplciar el formato directo

    Dim fechastring As String = DateTime.Now.ToString("yyyyMMdd")

    o sea no necesitas ningun replace

    Lo que necesito ahora es darle formato a la columna del datagridview para que dicha fecha que esta en la DB como un numero entero sea legible para los usuarios con formato de 20130103 a que se muestre 03/01/2013 en el datagridview.

    es parte si la veo complicada sin un tipo datetime desde la db

    vas a tener que convertir la fecha a datetime desde la query para poder aplicarle formato, en access tienes funciones como ser

    Format(DateValue,"YYYY/MM/DD")

    o CDate()

    pero no creo que eso sea util para un valor numerico o string, se va a tener que parsear y cortar cada parte de la fecha para armar el date nuevamente en la query

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    Thursday, January 03, 2013 3:49 PM
  • Hola Enrique;

    eh puesto el campo fecha en Access tipo FECHA/HORA, y en la aplicación estoy guardando la fecha "dd/MM/yyyy" en la DB.

    Y en la consulta SQL puse las almohadillas en fechaInicial y fechaFinal.

    Resulta que tenían razón, todo esta funcionando correctamente, con la configuración que me recomendaste Enrique; disculpen por mi terquedad.

    Hace dos días implemente la consulta sql que se muestra arriba pero le faltaba las almohadillas (#), y no podía pasar el rango a mas de un mes, ese fue el motivo por el cual decidi poner las fechas tipo texto y tratarlas como todo un numero.

     Gracias Leandro y Enrique, son los mejores.


    Silvio Diaz

    Thursday, January 03, 2013 6:48 PM
  • "silvio.dol" escribió:

    > Resulta que tenían razón, todo esta funcionando correctamente,
    > con la configuración que me recomendaste Enrique; disculpen
    > por mi terquedad.

    ¡Ves como funcionaba! Las fechas literales en Access se establecen como te indique: en formato americano y encerrando su valor entre caracteres #.

    > Y en la consulta SQL puse las almohadillas en fechaInicial y fechaFinal.
    >

    Si vas a ejecutar la consulta desde tu aplicación de Visual Basic, en lugar de insertar los valores literales, UTILIZA PARÁMETROS, tal y como aparece en el ejemplo de mi primera respuesta:

           ' Agregamos los parámetros al comando, en el mismo
           ' orden en el que se han añadido.
           cmd.Parameters.AddWithValue("@fechaInicio", fechaInicio)
           cmd.Parameters.AddWithValue("@fechaFin", fechaFin)

    Por supuesto, fechaInicio y fechaFin son variables del tipo System.DateTime.


    Enrique Martínez
      [MS MVP - VB]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, activa la instrucción Option Strict.

    Thursday, January 03, 2013 7:06 PM