none
Como castear valor del tipo DateTimeOffSet de SQL a un objeto de .Net a un formato de hora local RRS feed

  • Pregunta

  • Hola, tengo en mi base de datos una tabla con una columna DateTimeOffSet donde guardo formatos de fecha en formato UTC. Al leer los valores de mis tablas, si son fechas lo leo de la siguiente manera:

    if(reader.Read()){
    DateTime date = Convert.ToDateTime(reader["Date"]);
    }

    Ahora me pregunto dos cosas:
    1- Como casteo la fecha si no es del tipo DateTime si no DateTimeOffSet en SQL.

    2- Luego cuando tenga mi objeto en .net con el formato UCT, me interesaria en ocaciones pasarlo a un string, pero con la hora del país donde se encuentre el usuario. Es decir, desde mi aplicacion yo puedo saber el pais, entonces como la convierto ejemplo a hora de España.

    Saludos

    • Editado Zr-.- domingo, 6 de marzo de 2016 2:42
    domingo, 6 de marzo de 2016 2:34

Respuestas

  • Esta es la respuesta:

    public static DateTime ToDateTimeUTCLocal(this DateTime datetime, string timezone)
            {
                //get date time offset for UTC date stored in the database
                DateTimeOffset dbDateTimeOffset = new DateTimeOffset(datetime, TimeSpan.Zero);

                //get user's time zone from profile stored in the database
                TimeZoneInfo userTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timezone);

                //convert  db offset to user offset
                DateTimeOffset userDateTimeOffset = TimeZoneInfo.ConvertTime(dbDateTimeOffset, userTimeZone);
                return userDateTimeOffset.DateTime;
            }

    Saludos

    • Marcado como respuesta Zr-.- jueves, 10 de marzo de 2016 5:17
    jueves, 10 de marzo de 2016 5:16

Todas las respuestas

  • Para recuperar valores del tipo DateTimeOffset de SQL Server dispones también del tipo DateTimeOffset en .NET:

                        DateTimeOffset dto = (DateTimeOffset) reader["Date"];
                        DateTime dt = dto.UtcDateTime;
                        dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
    


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    domingo, 6 de marzo de 2016 9:53
  • Por cierto para convertir una fecha de tipo UTC a otra de tipo local no tienes más que utilizar el método ToLocalTime:

    DateTime dtLocal = dt.ToLocal();


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    domingo, 6 de marzo de 2016 11:00
  • Por cierto para convertir una fecha de tipo UTC a otra de tipo local no tienes más que utilizar el método ToLocalTime:

    DateTime dtLocal = dt.ToLocal();


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    Hola Aserie, gracias nuevamente. Habia abierto otro hilo el cual se alargo un poco y llegue a preguntar esto... Pero para no alargar mas aquel y salirme del tema inicial es mejor por aqui.

    Ya entendi el primer punto, como castear el objeto de base de datos. 

    Pero el segundo punto ToLocalTime no me sirve, ya que este lo que hace es convertir al local del servidor y este pudiera tener una configuracion x. Necesito es poder castearlo a un uso horario que yo especifique, puede ser España, Venezuela, Argentina, etc..

    Saludos

    domingo, 6 de marzo de 2016 19:29
  • Hola,

    Has probado usar CultureInfo ?

    System.Globalization.CultureInfo cultureinfo =
            new System.Globalization.CultureInfo("es-ES");
    DateTime dt = DateTime.Parse(date, cultureinfo);

    CultureInfo

    Con esto puedes tener acceso a la referencia cultural de una determinada región (país).

    Saludos.


    JC NaupaCrispín

    domingo, 6 de marzo de 2016 19:46
  • No Joel,

    eso no va a funcionar. El método Parse requiere un argumento de tipo string. Lo que hará es mostrar la fecha en el formato definido por la referencia cultural pero no hace ninguna conversión teniendo en cuenta la zona horaria.


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    domingo, 6 de marzo de 2016 20:14
  • Hola,

    Has probado usar CultureInfo ?

    System.Globalization.CultureInfo cultureinfo =
            new System.Globalization.CultureInfo("es-ES");
    DateTime dt = DateTime.Parse(date, cultureinfo);

    CultureInfo

    Con esto puedes tener acceso a la referencia cultural de una determinada región (país).

    Saludos.


    JC NaupaCrispín

    Hola como estas

    Ya lo hice, pero no funciona. Configura el formato mas no el valor, ej.

    DateTimeOffset dto = DateTimeOffset.UtcNow;
    DateTime dt = DateTime.Parse(dto.ToString(), new CultureInfo("es-ES")); -- 06/03/2016 15:58:39
    DateTime dt1 = DateTime.Parse(dto.ToString(), new CultureInfo("fr-FR")); -- 06/03/2016 15:58:39
    DateTime dt2 = DateTime.Parse(dto.ToString(), new CultureInfo("en-US")); -- 03/06/2016 15:58:39

    Saludos

    domingo, 6 de marzo de 2016 20:31
  • Ya di con la solución, aqui pongo 3 ejemlos...

            const string FORMAT_VZLA = "Venezuela Standard Time";
            const string FORMAT_USA = "US Eastern Standard Time";
            const string FORMAT_EUROPE = "E. Europe Standard Time";

    DateTimeOffset userDateTimeOffsetVzla = TimeZoneInfo.ConvertTime(dtDataBase, TimeZoneInfo.FindSystemTimeZoneById(FORMAT_VZLA));
                DateTimeOffset userDateTimeOffsetUsa = TimeZoneInfo.ConvertTime(dtDataBase, TimeZoneInfo.FindSystemTimeZoneById(FORMAT_USA));
                DateTimeOffset userDateTimeOffsetEurope = TimeZoneInfo.ConvertTime(dtDataBase, TimeZoneInfo.FindSystemTimeZoneById(FORMAT_EUROPE));

    Para obtener el listado de zonas horarias pueden hacerlo con el siguiente código:

    TimeZoneInfo.GetSystemTimeZones();

    Para mayor detalle pueden aprender en este link:

    http://www.binaryintellect.net/articles/e954127b-42a8-4beb-bd4a-bbb24be74d0e.aspx

    Ahora el detalle es como guardarlo en una variable o algo y luego poder hacer las asociaciones dependienddo del país del usuario.

    Saludos

    lunes, 7 de marzo de 2016 4:35
  • No es tan sencillo. Ten en cuenta que, aunque mantuvieses una tabla con la correspondencia entre países y zonas horarias te encontrarías con el problema de que hay muchos países con diferentes zonas horarias.

    Otra opción sería recuperar la información de la zona horaria del equipo del usuario a través de JavaScript con el método getTimezoneOffset y utilizar este offset en tus conversiones.

    Aunque yo creo que la mejor opción es recuperar las zonas horarias definidas en el servidor con el método que comentas (TimeZoneInfo.GetSysteTimeZones()) y que cada usuario seleccione una de estas zonas horarias en su configuración.


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    lunes, 7 de marzo de 2016 8:17
  • Esta es la respuesta:

    public static DateTime ToDateTimeUTCLocal(this DateTime datetime, string timezone)
            {
                //get date time offset for UTC date stored in the database
                DateTimeOffset dbDateTimeOffset = new DateTimeOffset(datetime, TimeSpan.Zero);

                //get user's time zone from profile stored in the database
                TimeZoneInfo userTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timezone);

                //convert  db offset to user offset
                DateTimeOffset userDateTimeOffset = TimeZoneInfo.ConvertTime(dbDateTimeOffset, userTimeZone);
                return userDateTimeOffset.DateTime;
            }

    Saludos

    • Marcado como respuesta Zr-.- jueves, 10 de marzo de 2016 5:17
    jueves, 10 de marzo de 2016 5:16