TSQL: Cómo convertir la hora local a UTC? (SQL Server 2008)
Estamos tratando con una aplicación que necesita manejar datos de hora globales de diferentes zonas horarias y ajustes de horario de verano. La idea es almacenar todo en formato UTC internamente y solo convertir hacia adelante y hacia atrás para las interfaces de usuario localizadas. ¿Ofrece el servidor SQL algún mecanismo para tratar las traducciones dadas una hora, un país y una zona horaria?
Esto debe ser un problema común, así que me sorprende que Google no aparezca nada utilizable.
Cualquiera los punteros?
10 answers
Pasaron 7 años y...
en realidad, hay esta nueva función de SQL Server 2016 que hace exactamente lo que necesita.
Se llama AT TIME ZONE y convierte la fecha en una zona horaria especificada teniendo en cuenta los cambios DST (horario de verano).
Más información aquí:
https://msdn.microsoft.com/en-us/library/mt612795.aspx
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-28 07:49:39
Esto funciona para fechas que actualmente tienen el mismo desplazamiento UTC que el host de SQL Server; no tiene en cuenta los cambios de horario de verano. Reemplace YOUR_DATE
con la fecha local a convertir.
SELECT DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), YOUR_DATE);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-06 22:28:53
Si bien algunas de estas respuestas lo llevarán al estadio, no puede hacer lo que está tratando de hacer con fechas arbitrarias para SQLServer 2005 y anteriores debido al horario de verano. El uso de la diferencia entre el UTC actual y el local actual me dará el desplazamiento tal como existe hoy en día. No he encontrado la manera de determinar cuál habría sido la compensación para la fecha en cuestión.
Dicho esto, sé que SQLServer 2008 proporciona algunas nuevas funciones de fecha que pueden abordar eso problema, pero las personas que usan una versión anterior deben ser conscientes de las limitaciones.
Nuestro enfoque es persistir UTC y realizar la conversión en el lado del cliente donde tenemos más control sobre la precisión de la conversión.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-14 18:50:42
SQL Server 2008 tiene un tipo llamado datetimeoffset
. Es muy útil para este tipo de cosas.
Http://msdn.microsoft.com/en-us/library/bb630289.aspx
Luego puede usar la función SWITCHOFFSET
para moverla de una zona horaria a otra, pero manteniendo el mismo valor UTC.
Http://msdn.microsoft.com/en-us/library/bb677244.aspx
Rob
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-07 13:11:07
Puede usar mi proyecto Soporte de Zona horaria de SQL Server para convertir entre zonas horarias estándar de IANA, como se indica aquí.
UTC a Local es así:
SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'America/Los_Angeles')
Local a UTC es así:
SELECT Tzdb.LocalToUtc('2015-07-01 00:00:00', 'America/Los_Angeles', 1, 1)
Las opciones numéricas son un indicador para controlar el comportamiento cuando los valores de la hora local se ven afectados por el horario de verano. Estos se describen en detalle en la documentación del proyecto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-03 05:50:39
Tiendo a inclinarme hacia el uso de DateTimeOffset para todo el almacenamiento de fecha y hora que no está relacionado con un evento local (es decir: reunión/fiesta, etc., 12pm-3pm en el museo).
Para obtener el DTO actual como UTC:
DECLARE @utcNow DATETIMEOFFSET = CONVERT(DATETIMEOFFSET, SYSUTCDATETIME())
DECLARE @utcToday DATE = CONVERT(DATE, @utcNow);
DECLARE @utcTomorrow DATE = DATEADD(D, 1, @utcNow);
SELECT @utcToday [today]
,@utcTomorrow [tomorrow]
,@utcNow [utcNow]
NOTA: Siempre usaré UTC cuando envíe el cable... JS del lado del cliente puede llegar fácilmente a / desde UTC local. Véase: new Date().toJSON()
...
El siguiente JS manejará el análisis de una fecha UTC/GMT en formato ISO8601 a una fecha y hora local.
if (typeof Date.fromISOString != 'function') {
//method to handle conversion from an ISO-8601 style string to a Date object
// Date.fromISOString("2009-07-03T16:09:45Z")
// Fri Jul 03 2009 09:09:45 GMT-0700
Date.fromISOString = function(input) {
var date = new Date(input); //EcmaScript5 includes ISO-8601 style parsing
if (!isNaN(date)) return date;
//early shorting of invalid input
if (typeof input !== "string" || input.length < 10 || input.length > 40) return null;
var iso8601Format = /^(\d{4})-(\d{2})-(\d{2})((([T ](\d{2}):(\d{2})(:(\d{2})(\.(\d{1,12}))?)?)?)?)?([Zz]|([-+])(\d{2})\:?(\d{2}))?$/;
//normalize input
var input = input.toString().replace(/^\s+/,'').replace(/\s+$/,'');
if (!iso8601Format.test(input))
return null; //invalid format
var d = input.match(iso8601Format);
var offset = 0;
date = new Date(+d[1], +d[2]-1, +d[3], +d[7] || 0, +d[8] || 0, +d[10] || 0, Math.round(+("0." + (d[12] || 0)) * 1000));
//use specified offset
if (d[13] == 'Z') offset = 0-date.getTimezoneOffset();
else if (d[13]) offset = ((parseInt(d[15],10) * 60) + (parseInt(d[16],10)) * ((d[14] == '-') ? 1 : -1)) - date.getTimezoneOffset();
date.setTime(date.getTime() + (offset * 60000));
if (date.getTime() <= new Date(-62135571600000).getTime()) // CLR DateTime.MinValue
return null;
return date;
};
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-21 18:32:15
Aquí el código para convertir una zona DateTime
a otra zona DateTime
DECLARE @UTCDateTime DATETIME = GETUTCDATE();
DECLARE @ConvertedZoneDateTime DATETIME;
-- 'UTC' to 'India Standard Time' DATETIME
SET @ConvertedZoneDateTime = @UTCDateTime AT TIME ZONE 'UTC' AT TIME ZONE 'India Standard Time'
SELECT @UTCDateTime AS UTCDATE,@ConvertedZoneDateTime AS IndiaStandardTime
-- 'India Standard Time' to 'UTC' DATETIME
SET @UTCDateTime = @ConvertedZoneDateTime AT TIME ZONE 'India Standard Time' AT TIME ZONE 'UTC'
SELECT @ConvertedZoneDateTime AS IndiaStandardTime,@UTCDateTime AS UTCDATE
Nota : Esto(AT TIME ZONE
) trabajando solo en SQL Server 2016 + y esta ventaja es considerando automáticamente la luz del día mientras se convierte a una zona horaria particular
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-06 11:30:46
Sí, hasta cierto punto como se detalla aquí.
El enfoque que he utilizado (antes de 2008) es hacer la conversión en la lógica de negocio.NET antes de insertar en la base de datos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-30 08:20:59
Puede usar la función GETUTCDATE () para obtener la fecha y hora UTC Probablemente puede seleccionar la diferencia entre GETUTCDATE() y GETDATE () y usar esta diferencia para ajustar sus fechas a UTC
Pero estoy de acuerdo con el mensaje anterior, que es mucho más fácil controlar la fecha y hora correcta en la capa de negocio (en.NET, por ejemplo).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-30 08:21:03
Uso de la muestra:
SELECT
Getdate=GETDATE()
,SysDateTimeOffset=SYSDATETIMEOFFSET()
,SWITCHOFFSET=SWITCHOFFSET(SYSDATETIMEOFFSET(),0)
,GetutcDate=GETUTCDATE()
GO
Devuelve:
Getdate SysDateTimeOffset SWITCHOFFSET GetutcDate
2013-12-06 15:54:55.373 2013-12-06 15:54:55.3765498 -08:00 2013-12-06 23:54:55.3765498 +00:00 2013-12-06 23:54:55.373
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-07 00:37:36