Como alternativa, como a Microsoft tornou possível a viagem no tempo?
Considere 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
é definido antes @UTC
, mas às vezes possui um valor posterior . (Tentei isso no SQL Server 2008 R2 e no SQL Server 2016. Você deve executá-lo algumas vezes para detectar as ocorrências suspeitas.)
Isso não parece ser simplesmente uma questão de arredondamento ou falta de precisão. (Na verdade, acho que o arredondamento é o que "corrige" o problema ocasionalmente). Os valores para uma execução de amostra são os seguintes:
- Deslocamento
- 2017-06-07 12: 01: 58.8801139 -05: 00
- UTC
- 2017-06-07 17: 01: 58.877
- UTC do deslocamento:
- 2017-06-07 17: 01: 58.880
Portanto, a precisão de data e hora permite o .880 como um valor válido.
Até os exemplos GETUTCDATE da Microsoft mostram que os valores SYS * são posteriores aos métodos mais antigos, apesar de terem sido selecionados 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 */
Presumo que isso ocorre porque eles vêm de diferentes informações subjacentes do sistema. Alguém pode confirmar e fornecer detalhes?
A documentação SYSDATETIMEOFFSET da Microsoft diz "O SQL Server obtém os valores de data e hora usando a API do Windows GetSystemTimeAsFileTime ()" (obrigado srutzky), mas a documentação GETUTCDATE é muito menos específica, dizendo apenas que o "valor é derivado do sistema operacional do computador no qual a instância do SQL Server está sendo executada ".
(Isso não é totalmente acadêmico. Encontrei um problema menor causado por isso. Eu estava atualizando alguns procedimentos para usar SYSDATETIMEOFFSET em vez de GETUTCDATE, na esperança de obter maior precisão no futuro, mas comecei a receber pedidos estranhos porque outros procedimentos eram ainda usando GETUTCDATE e ocasionalmente "pulando à frente" dos meus procedimentos convertidos nos logs.)