Alternativamente, ¿cómo hizo Microsoft posible viajar en el tiempo?
Considera este código:
DECLARE @Offset datetimeoffset = sysdatetimeoffset();
DECLARE @UTC datetime = getUTCdate();
DECLARE @UTCFromOffset datetime = CONVERT(datetime,SWITCHOFFSET(@Offset,0));
SELECT
Offset = @Offset,
UTC = @UTC,
UTCFromOffset = @UTCFromOffset,
TimeTravelPossible = CASE WHEN @UTC < @UTCFromOffset THEN 1 ELSE 0 END;
@Offset
se establece antes @UTC
, pero a veces tiene un valor posterior . (He intentado esto en SQL Server 2008 R2 y SQL Server 2016. Debe ejecutarlo varias veces para detectar los casos sospechosos).
Esto no parece ser simplemente una cuestión de redondeo o falta de precisión. (De hecho, creo que el redondeo es lo que "soluciona" el problema ocasionalmente). Los valores para una ejecución de muestra son los siguientes:
- Compensar
- 2017-06-07 12: 01: 58.8801139 -05: 00
- UTC
- 2017-06-07 17: 01: 58.877
- UTC desde compensación:
- 2017-06-07 17: 01: 58.880
Entonces, la precisión de fecha y hora permite que el .880 sea un valor válido.
Incluso los ejemplos GETUTCDATE de Microsoft muestran que los valores SYS * son posteriores a los métodos anteriores, a pesar de haber sido SELECCIONADOS anteriormente :
SELECT 'SYSDATETIME() ', SYSDATETIME(); SELECT 'SYSDATETIMEOFFSET()', SYSDATETIMEOFFSET(); SELECT 'SYSUTCDATETIME() ', SYSUTCDATETIME(); SELECT 'CURRENT_TIMESTAMP ', CURRENT_TIMESTAMP; SELECT 'GETDATE() ', GETDATE(); SELECT 'GETUTCDATE() ', GETUTCDATE(); /* Returned: SYSDATETIME() 2007-05-03 18:34:11.9351421 SYSDATETIMEOFFSET() 2007-05-03 18:34:11.9351421 -07:00 SYSUTCDATETIME() 2007-05-04 01:34:11.9351421 CURRENT_TIMESTAMP 2007-05-03 18:34:11.933 GETDATE() 2007-05-03 18:34:11.933 GETUTCDATE() 2007-05-04 01:34:11.933 */
Supongo que esto se debe a que provienen de información del sistema subyacente diferente. ¿Alguien puede confirmar y proporcionar detalles?
La documentación SYSDATETIMEOFFSET de Microsoft dice que "SQL Server obtiene los valores de fecha y hora utilizando la API de Windows GetSystemTimeAsFileTime ()" (gracias srutzky), pero su documentación GETUTCDATE es mucho menos específica, diciendo solo que el "valor se deriva del sistema operativo del equipo en el que se ejecuta la instancia de SQL Server ".
(Esto no es completamente académico. Me encontré con un problema menor causado por esto. Estaba actualizando algunos procedimientos para usar SYSDATETIMEOFFSET en lugar de GETUTCDATE, con la esperanza de una mayor precisión en el futuro, pero comencé a obtener pedidos extraños porque otros procedimientos eran sigo usando GETUTCDATE y ocasionalmente "saltando" de mis procedimientos convertidos en los registros).