sql >> Base de Datos >  >> RDS >> Sqlserver

Conversión de fecha juliana JDE a gregoriana

Creo que es más eficiente usar matemáticas de fecha y hora nativas que todo este cambio de ida y vuelta a varios formatos de cadena, fecha y numéricos.

DECLARE @julian VARCHAR(6) = '111186';

SELECT DATEADD(YEAR, 
  100*CONVERT(INT, LEFT(@julian,1))
  +10*CONVERT(INT, SUBSTRING(@julian, 2,1))
  +CONVERT(INT, SUBSTRING(@julian,3,1)), 
 DATEADD(DAY, CONVERT(INT,SUBSTRING(@julian, 4, 3))-1, 
 0));

Resultado:

===================
2011-07-05 00:00:00

Suponiendo que estos datos no cambien con frecuencia, puede ser mucho más eficiente almacenar la fecha como una columna calculada (por eso elegí la fecha base de 0 en lugar de alguna representación de cadena, lo que causaría problemas de determinismo que evitarían que la columna se mantenga y se indexe potencialmente).

CREATE TABLE dbo.JDEDates
(
    JDEDate VARCHAR(6),

    GregorianDate AS CONVERT(SMALLDATETIME, 
      DATEADD(YEAR, 
        100*CONVERT(INT, LEFT(RIGHT('0'+JDEDate,6),1))
        +10*CONVERT(INT, SUBSTRING(RIGHT('0'+JDEDate,6), 2,1))
        +CONVERT(INT, SUBSTRING(RIGHT('0'+JDEDate,6),3,1)), 
      DATEADD(DAY, CONVERT(INT, RIGHT(JDEDate, 3))-1, 
      0))
    ) PERSISTED
);

INSERT dbo.JDEDates(JDEDate) SELECT '111186';

SELECT JDEDate, GregorianDate FROM dbo.JDEDates;

Resultados:

JDEDate GregorianDate
======= ===================
111186  2011-07-05 00:00:00

Incluso si no indexa la columna, aún le oculta el feo cálculo, siendo persistente, solo paga eso en el momento de la escritura, ya que no hace que realice costosas operaciones funcionales en el momento de la consulta cada vez que se hace referencia a esa columna. ...