el Guille, la Web del Visual Basic, C#, .NET y más...

Averiguar la cultura actual para ajustar las fechas correctamente

Y cómo hacer una consulta en SQL Server usando parámetros

Publicado el 29/Dic/2005
Actualizado el 04/Abr/2006
Autor: Guillermo 'guille' Som

En este ejemplo te muestro cómo utilizar el formato de fecha correcta según la cultura en la que se esté ejecutando nuestra aplicación, ya sea de escritorio o aplicación Web.
También te muestro cómo realizar una consulta de SQL Server usando parámetros en la consulta.

En este link tienes cómo averiguar el separador decimal y el de miles y otras cosas relacionadas con el formato numérico.



 

Introducción:

Es una cosa muy simple, pero creo que es conveniente saber cómo hacerlo.

Te explico que este código es el que utilizo en mis foros a la hora de mostrar la fecha actual.
Debido a que el foro está alojado en un servidor que reside en los Estados Unidos de Norteamérica (USA), dicho formato de fecha y hora es diferente, por ejemplo al usado en España.
En realidad, la fecha la puedo mostrar como quiera, pero si, por ejemplo, esa fecha (o formato) la quiero usar para acceder a una base de datos, si no está en el mismo formato del idioma en el que se ejecuta la base de datos, posiblemente no funcionará correctamente.

El código que utilizo es el siguiente, en este caso para mostrar dos fechas, una 15 días antes de la actual y otra la actual, ambas en formato universal, es decir, según la hora universal (UTC) o de Greenwich (GMT):

 

Dim s As String
s = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern
txtDesde.Text = DateTime.Now.ToUniversalTime().Subtract(New TimeSpan(15, 0, 0, 0)).ToString(s)
txtHasta.Text = DateTime.Now.ToUniversalTime().ToString(s)

 

En este caso, estoy usando la propiedad ShortDatePattern que vendría a ser algo así como MM/dd/yyyy, es deir, en formato mes/día/año.

Por otro lado, al usar el método ToUniversalTime de la la propiedad Now, estoy obteniendo la fecha UTC, es decir, para que no utilice la del pacífico, que es la hora que tiene mi servidor, por ejemplo, estos valores que se muestran a continuación se obtienen directamente del servidor, y en el caso de que estés viendo la página desde elGuille.info, (pulsa en el link para ir a esta misma página en elguille.info), verás que hay unas 8 horas de diferencia con la fecha universal (UTC/GMT), sin embargo, si lo ves desde MundoProgramacion.com, (pulsa en el link para ir a esta misma página en mundoprogramacion), esa fecha será la de España, ya que el servidor donde está alojado ese sitio reside en España.

La fecha en formato "normal", usando dd/MM/yyyy: 22/12/2024
Código usado: Dim fecha1 As String = DateTime.Now.ToString("dd/MM/yyyy")
Este mostrando la fecha y la hora con dd/MM/yyyy HH:mm: 22/12/2024 17:12

La fecha en formato "universal", usando dd/MM/yyyy: 22/12/2024
Código usado: Dim fecha2 As String = DateTime.Now.ToUniversalTime().ToString("dd/MM/yyyy")
Este mostrando la fecha y la hora con dd/MM/yyyy HH:mm: 22/12/2024 16:12

La fecha según la cultura (en formato universal): 22/12/2024
Código usado: Dim fecha3 As String = DateTime.Now.ToString(s)

La fecha según la cultura (según la hora del servidor): 22/12/2024
Código usado: Dim fecha4 As String = DateTime.Now.ToUniversalTime().ToString(s)

En estos dos últimos casos, el valor de "s" se obtiene con:
s = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern

 

Nota:
Internamente esta página está usando código de Visual Basic .NET para mostrar esas fechas.

 

¿Cómo influye esto en una consulta de SQL Server?

Aunque parezca una tontería, al usar los valores desde y hasta del código mostrado más arriba, si esos valores los uso en una consulta de SQL Server para obtener los datos entre dos fechas, funcionará bien lo ejecute donde lo ejecute, pero si en lugar de usar la "fecha globalizada" usara el formato habitual: dd/MM/yyyy, sólo me funcionaría si la base de datos estuviese en un servidor configurado con ese "tipo" de fecha.

La consulta usada es esta: (en realidad faltan cosas que indicar, pero lo importante es cómo usarla)

''' <summary>
''' Obtener los registros de una tabla entre dos fechas.
''' </summary>
''' <param name="desde">Fecha desde la que queremos los datos</param>
''' <param name="hasta">Fecha hasta la que queremos los datos</param>
''' <param name="max">El máximo de mensajes a devolver (entre 100 y 600, por defecto 400)</param>
''' <returns>Un DataTable con los mensajes hallados</returns>
''' <remarks></remarks>
''' <fecha>29/Dic/2005</fecha>
Public Shared Function MensajesForo( _
                ByVal desde As String, _
                ByVal hasta As String, _
                Optional ByVal max As Integer = 400) As DataTable
    '
    Dim cnn As SqlConnection = Nothing
    Dim dt As New DataTable
    '
    ' Dentro de un Try/Catch por si se produce un error
    Try
        If max > 600 OrElse max < 100 Then max = 400

        ' Obtenemos la cadena de conexión adecuada
        Dim sConn As String = "data source=(local); " & _
		"initial catalog=<nombre base de datos>; " & _
		"user id=<usuario>; password=<contraseña>;"
        cnn = New SqlConnection(sConn)
        cnn.Open()
        ' Creamos el comando para la consulta
        Dim cmd As SqlCommand = New SqlCommand
        Dim sel As String = _
            "SELECT TOP " & max & " <los campos a devolver> " & _
            "FROM <nombre de la tabla> " & _
            "WHERE ( Fecha >= @Fecha1 AND Fecha <= @Fecha2 ) " & _
            "ORDER BY Fecha DESC"
        '
        cmd.CommandText = sel
        cmd.Connection = cnn
        cmd.CommandType = CommandType.Text
        cmd.CommandTimeout = 90
        ' Los parámetros usados en la cadena de la consulta 
        cmd.Parameters.Add(New SqlParameter("@Fecha1", SqlDbType.DateTime))
        cmd.Parameters.Add(New SqlParameter("@Fecha2", SqlDbType.DateTime))
        cmd.Parameters("@Fecha1").Value = desde
        cmd.Parameters("@Fecha2").Value = hasta
        '
        ' Creamos el dataAdapter y asignamos el comando de selección
        Dim da As New SqlDataAdapter
        da.SelectCommand = cmd
        ' Llenamos la tabla
        da.Fill(dt)
    Catch 'ex As Exception
        ' Si hay error, devolvemos un valor nulo.
        Return Nothing
    Finally
        ' Por si se produce un error,
        ' comprobamos si en realidad el objeto Connection está iniciado,
        ' de ser así, lo cerramos.
        If Not cnn Is Nothing Then
            cnn.Close()
        End If
    End Try
    '
    ' Devolvemos el objeto DataTable con los datos de la consulta
    Return dt
End Function

 

Y esto es todo, espero que te sea de utilidad.

Nos vemos.
Guillermo

 


Código para Visual Basic.NET (VB.NET)El código para VB .NET

Es el mostrado anteriormente.

 


Código para C Sharp (C#)El código para C#

Este es el código para asignar las cadenas de las fechas según la cultura actual:

string s;
s = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
string desde = DateTime.Now.ToUniversalTime().Subtract(new TimeSpan(15, 0, 0, 0)).ToString(s);
string hasta = DateTime.Now.ToUniversalTime().ToString(s);

 

Este es el código para acceder a la base de datos y realizar la consulta:

/// <summary>
/// Obtener los registros de una tabla entre dos fechas.
/// </summary>
/// <param name="desde">Fecha desde la que queremos los datos</param>
/// <param name="hasta">Fecha hasta la que queremos los datos</param>
/// <param name="max">El máximo de mensajes a devolver (entre 100 y 600, por defecto 400)</param>
/// <returns>Un DataTable con los mensajes hallados</returns>
/// <remarks></remarks>
/// <fecha>29/Dic/2005</fecha>
public static DataTable MensajesForo(string desde, 
    				string hasta, 
    				int max)
{
    //
    SqlConnection cnn = null;
    DataTable dt = new DataTable();
    //
    // Dentro de un Try/Catch por si se produce un error
    try
    {
        if( max > 600 || max < 100 ) max = 400;

        string usuario = "<usuario>";
        string passw = "<password>";

        // Obtenemos la cadena de conexión adecuada
        string sConn = "data source=(local); " + 
            	       "initial catalog=<nombre base de datos>; " + 
            	       "user id=" + usuario + "; password=" + passw + ";";
        cnn = new SqlConnection(sConn);
        cnn.Open();
        // Creamos el comando para la consulta
        SqlCommand cmd = new SqlCommand();
        string sel = "SELECT TOP " + max + " <los campos a mostrar> " + 
            "FROM <nombre de la tabla> " + 
            "WHERE ( Fecha >= @Fecha1 AND Fecha <= @Fecha2 ) " + 
            "ORDER BY Fecha DESC";
        //
        cmd.CommandText = sel;
        cmd.Connection = cnn;
        cmd.CommandType = CommandType.Text;
        cmd.CommandTimeout = 90;
        // Los parámetros usados en la cadena de la consulta
        cmd.Parameters.Add(new SqlParameter("@Fecha1", SqlDbType.DateTime));
        cmd.Parameters.Add(new SqlParameter("@Fecha2", SqlDbType.DateTime));
        cmd.Parameters["@Fecha1"].Value = desde;
        cmd.Parameters["@Fecha2"].Value = hasta;
        //
        // Creamos el dataAdapter y asignamos el comando de selección
        SqlDataAdapter da = new SqlDataAdapter();
        da.SelectCommand = cmd;
        // Llenamos la tabla
        da.Fill(dt);
    }
    catch(Exception ex)
    {
        // Si hay error, devolvemos un valor nulo.
        Console.WriteLine(ex.Message);
        return null;
    }
    finally
    {
        // Por si se produce un error,
        // comprobamos si en realidad el objeto Connection está iniciado,
        // de ser así, lo cerramos.
        if( cnn != null )
            cnn.Close();
    }
    //
    // Devolvemos el objeto DataTable con los datos de la consulta
    return dt;
}

 



 


La fecha/hora en el servidor es: 22/12/2024 17:12:27

La fecha actual GMT (UTC) es: 

©Guillermo 'guille' Som, 1996-2024