A ver si consigo explicarme,
SQL Server no guarda las fechas ni en formato
dd/MM/yyyy ni en formato MM/dd/yyyy, ni en ningún otro formato por el estilo.
Sql Server guarda las fechas como un número binario de 64 bits independiente de
la cultura.
Otra cosa muy distinta es cómo SQL Server
interpreta una fecha proporcionada como una cadena de caracteres. Por ejemplo si
tenemos una tabla con un campo fecha y ejecutamos:
INSERT INTO Tabla (CampoFecha) VALUES (
'05/11/2003" )
SQL Server puede interpretar la cadena '05/11/2003'
como el cinco de noviembre del 2003 o como el 11 de mayo del 2003. Dependiendo
de la configuración de SQL Server. Independientemente de la configuración de SQL
Server, se le puede decir que las fechas las interprete de una manera
determinada mediante la instrucción SET DATEFORMAT. Por ejemplo:
SET DATEFORMAT DMY
INSERT INTO Tabla (CampoFecha) VALUES (
'05/11/2003" )
hará que se inserte en la tabla la fecha 5 de noviembre del 2003
y
SET DATEFORMAT MDY
INSERT INTO Tabla (CampoFecha) VALUES (
'05/11/2003" )
hará que se inserte en la tabla la fecha 11 de mayo de 2003
Independientemente de como se interpreten las fechas, el analizador de
consultas de SQL Server siempre muestra las fechas en formato yyyy-mm-dd
hh:mm:ss.msmsms.
con lo que si ejecutas en el analizador de consultas:
SET DATEFORMAT DMY
INSERT INTO Tabla (CampoFecha) VALUES (
'05/11/2003" )
SELECT CampoFecha
FROM Tabla
WHERE CampoFecha = '05/11/2003'
mostrará:
2003-11-05 00:00:00.000
Para evitar problemas con la forma en que se interpretan las fechas en SQL
Server, existe el formato ANSI yyyymmdd hh:mm:ss.msmsms. Por ejemplo para el
cinco de noviembre de 2003 sería '20031105 00:00:000.000' o simplemente
'20031105'
Cuando desde
ADO.NET estamos insertando o modificando valores de tipo
fecha, es muy recomendable usar parámetros en vez de construir la instrucción
SQL concatenando cadenas, ya que SqlClient formateará de forma correcta los
valores de fecha, en realidad utilizará el formato ANSI.
Por ejemplo para insertar una fecha en la tabla podríamos escribir un
código así:
Dim con As New
SqlClient.SqlConnection("CadenaConexión")
Dim InsertarFecha As New SqlClient.SqlCommand("insert into tabla(CampoFecha)
values(@fecha)", con)
InsertaFecha.Parameters.Add("@fecha", SqlDbType.DateTime).Value =
DateTime.Today
con.Open()
InsertaFecha.ExecuteNonQuery()
con.Close()
Similarmente a como ocurre con SQL Server las varibles de tipo
fecha en .NET y en VB.NET y en C# y en cualquier otro lenguaje
.NET, tampoco se guardan ni en formato DD/MM/YYYY ni en formato
MM/DD/YYYY ni en ningún otro formato por el estilo, sino que se guardan como
números binarios de 64 bits independientes de la cultura. Otra cuestión es cómo
se interpreta una cadena que contiene una fecha y como convertimos una variable
de tipo fecha a una cadena de caracteres para mostrarla. Eso depende de la
cultura actual, concrétamente depende del valor de
Thread.CurrentThread.CurrentCulture.
Aquí tienes un ejemplo que muestra primero la fecha
según la configuración actual del ordenador, según la cultura Inglés de Estados
Unidos y según la cultura Español de España.
Thread.CurrentThread.CurrentCulture =
System.Globalization.CultureInfo.InstalledUICulture
MsgBox(DateTime.Today)
Dim
cultura1 As New
System.Globalization.CultureInfo("EN-US")
Thread.CurrentThread.CurrentCulture =
cultura1
MsgBox(DateTime.Today)
Dim
cultura2 As New
System.Globalization.CultureInfo("ES-es")
Thread.CurrentThread.CurrentCulture =
cultura2
MsgBox(DateTime.Today)
Si no cambias el valor de CurrentCulture éste
corresponderá con InstalledUICulture. Al igual que la conversión de un valor de
tipo DateTime a una cadena de caracteres depende del CurrentCultrue. La forma en
la que se interpreta una cadena para convertirla en un valor DateTime depende de
CurrentCulture.
Este código primero establece la cultura como
Inglés de Estados Unidos ("EN-US") con lo que la cadena "11/05/03" se interpreta
como 5 de noviembre de 2003, luego cambia la cultura actual a Español de España
con lo que en el cuadro de mensaje se muestra 05/11/03:
Dim
cultura1 As New
System.Globalization.CultureInfo("EN-US")
Thread.CurrentThread.CurrentCulture =
cultura1
Dim fecha As Date =
CDate("11/05/03")
Dim
cultura2 As New
System.Globalization.CultureInfo("ES-es")
Thread.CurrentThread.CurrentCulture =
cultura2
MsgBox(fecha)
Espero haberte aclarado el tema de los formatos de
fecha.
--
Saludos:
Jesús López
MVP Microsoft .NET
"No darás tropezón ni desatino que no te haga adelantar
camino"