In alternativa, in che modo Microsoft ha reso possibile il viaggio nel tempo?
Considera questo codice:
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
è impostato prima @UTC
, ma a volte ha un valore successivo . (L'ho provato su SQL Server 2008 R2 e SQL Server 2016. È necessario eseguirlo alcune volte per rilevare le occorrenze sospette.)
Questo non sembra essere semplicemente una questione di arrotondamento o mancanza di precisione. (In effetti, penso che l'arrotondamento sia ciò che "risolve" il problema di tanto in tanto.) I valori per un'esecuzione di esempio sono i seguenti:
- Compensare
- 07/06/2017 12: 01: 58.8801139-05: 00
- UTC
- 07-06-2017 17: 01: 58.877
- UTC dall'offset:
- 07/06/2017 17: 01: 58.880
Quindi la precisione del datetime consente a .880 di essere un valore valido.
Anche gli esempi GETUTCDATE di Microsoft mostrano che i valori SYS * sono successivi ai metodi precedenti, nonostante siano stati SELEZIONATI in precedenza :
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 che ciò avvenga perché provengono da diverse informazioni di sistema sottostanti. Qualcuno può confermare e fornire dettagli?
La documentazione di Microsoft SYSDATETIMEOFFSET afferma che "SQL Server ottiene i valori di data e ora utilizzando l'API Windows GetSystemTimeAsFileTime ()" (grazie srutzky), ma la loro documentazione GETUTCDATE è molto meno specifica, dicendo solo che il "valore è derivato dal sistema operativo del computer su cui è in esecuzione l'istanza di SQL Server ".
(Questo non è del tutto accademico. Ho riscontrato un piccolo problema causato da questo. Stavo aggiornando alcune procedure per utilizzare SYSDATETIMEOFFSET invece di GETUTCDATE, nella speranza di una maggiore precisione in futuro, ma ho iniziato a ottenere ordini strani perché altre procedure erano usando ancora GETUTCDATE e occasionalmente "saltando avanti" delle mie procedure convertite nei registri.)