2008-10-21 18 views
13

que tienen una aplicación web que estoy escribiendo (C#, MSSQL) y necesito para almacenar la fecha y hora cuando se almacena un registro en el sistema. Normalmente, solo haría esto con SQL y la función DATETIME. Sin embargo, el servidor está ubicado en una zona horaria diferente a la que se encuentra nuestra empresa ... Y podemos cambiar a otro servidor en una zona horaria completamente diferente. La empresa de alojamiento no cambiará la hora del servidor para que coincida con nuestra zona horaria local. (No es que los culpe, pero fue una cosa que probé)¿Cómo lidiar con el tiempo de almacenamiento en SQL

Entonces, mi pregunta es, ¿cuál es la mejor manera de almacenar la fecha/hora de la actualización de registro y cuál es la mejor manera de presentar eso? fecha/hora de regreso al usuario en nuestra zona horaria local?

Quiero la manera menos complicado de hacer esto, por lo que una combinación de C# y SQL estaría bien, siempre y cuando la solución es fácil de implementar. (Mi estilo normal es hacer más trabajo en los procedimientos almacenados y menos en C#, si lo que importa.)

¿Me puede mostrar algunos ejemplos de código? ¡Gracias!

Respuesta

17

siempre almacenar datos DATETIME en Tiempo Universal Coordinado (UTC también conocido como GMT)

  • Esto evita toda zona horaria emite
  • emite este modo se evita la luz del día-ahorro en tiempo
  • esto permite fechas simples matemáticas para trabajar siempre
  • esto permite que las transacciones en diferentes zonas horarias para mantenerse en sincronía
  • Esto le permite mover los datos a un servidor diferente en una zona horaria diferente y no meter todo lo que hasta
  • tiempo
  • etc. "universal", tiene sentido?

C# DateTime proporciona DateTime.UtcNow y ToLocalTime(), SQL proporciona GETUTCDATE(). He aquí una función SQL para convertir UTC a la hora local -

-- convert UTC to local time 
create FUNCTION [dbo].[udfUtcToLocalTime] 
(
    @gmt datetime 
) 
RETURNS datetime 
AS 
BEGIN 
    DECLARE @dt datetime 
    SELECT 
     @dt = dateadd(millisecond,datediff(millisecond,getutcdate(), getdate()),@gmt) 
    RETURN @dt 
END 

ejemplo:

SELECT dbo.udfUtcToLocalTime(someDateTimeField) 
FROM someTable 
+0

Esta función fallará cuando la compensación de timzeone cambie debido al horario de verano. –

+0

@ [Dave Markle]: se supone que cambia cuando cambia el horario de verano. –

+0

Lo que quiere decir es que si nos fijamos en la información de la semana pasada, antes del cambio de fecha, verá que con el actual no compensa el desplazamiento desde la semana pasada. Su función solo funciona si desea ver las horas locales basadas en el desplazamiento de hoy. La función .Net DateTime.ToLocalTime no funciona de esta manera. Le mostrará la hora local basada en el desplazamiento en esa fecha. –

7

tiempos Guardar UTC en su base de datos y localizar aquellos tiempos cada vez que quiere mostrarles a un usuario

+1

En los procedimientos almacenados utilizan GETUTCDATE() en lugar de GETDATE() si no se proporciona desde la aplicación. – tvanfosson

4

tienda como la hora UTC y luego realice el procedimiento de cálculo de zona horaria en el cliente final en C# utilizan .ToUniversalTime () en el objeto DateTime para obtener la hora UTC, almacénela en el servidor y luego use .ToLocalTime() para convertirla.

+0

Esto es similar a lo que hago, excepto que tengo mi propio método de extensión ToLocalTime en C#. Esto se debe a que el servidor web se encuentra en los EE. UU., Pero quiero que los horarios aparezcan como en Australia. – Craig

Cuestiones relacionadas