Conversión no determinista de las cadenas de fecha literales en valores DATENondeterministic conversion of literal date strings into DATE values

Tenga cuidado al permitir la conversión de las cadenas de caracteres en tipos de datos DATE.Use caution when allowing conversion of your CHARACTER strings into DATE data types. El motivo es que estas conversiones a menudo son no deterministas.The reason is that such conversions are often nondeterministic.

Para controlar estas conversiones no deterministas debe tener en cuenta la configuración de SET LANGUAGE (ESTABLECER IDIOMA) y SET DATEFORMAT (ESTABLECER FORMATO DE FECHA).You control these nondeterministic conversions by accounting for the settings of SET LANGUAGE and SET DATEFORMAT.

Ejemplo de SET LANGUAGE: nombre del mes en polacoSET LANGUAGE example: Month name in Polish

  • SET LANGUAGE Polish;

Una cadena de caracteres puede ser el nombre de un mes.A character string can be the name of a month. ¿Pero el nombre está en inglés, polaco, croata o en otro idioma?But is the name in English, or Polish, or Croatian, or in another language? Y, ¿se establecerá la sesión del usuario en el idioma correcto correspondiente?And, will the user's session be set to the correct corresponding LANGUAGE?

Por ejemplo, considere la palabra listopad, que es el nombre de un mes.For example, consider the word listopad, which is the name of a month. Qué mes es depende del idioma que el sistema SQL considera que se usa:But which month it is depends on the language the SQL system believes is being used:

  • Si es polaco, listopad se traduce como el undécimo mes (noviembre en español).If Polish, then listopad translates to month 11 (November in English).
  • Si es polaco, listopad se traduce como el décimo mes (octubre en español).If Croatian, then listopad translates to month 10 (October in English).

Ejemplo de código de SET LANGUAGECode example of SET LANGUAGE

--SELECT alias FROM sys.syslanguages ORDER BY alias;

DECLARE @yourInputDate  NVARCHAR(32) = '28 listopad 2018';

SET LANGUAGE Polish;
SELECT CONVERT(DATE, @yourInputDate) AS [SL_Polish];

SET LANGUAGE Croatian;
SELECT CONVERT(DATE, @yourInputDate) AS [SL_Croatian];

SET LANGUAGE English;


/***  Actual output:  For the two months, note the 11 versus the 10.
SL_Polish
2018-11-28

SL_Croatian
2018-10-28
***/

Ejemplo de SET DATEFORMATSET DATEFORMAT example

  • SET DATEFORMAT dmy;

El formato dmy anterior dice que el significado de la cadena de fecha de ejemplo “01-03-2018” se interpretaría como el primer día de marzo del año 2018.The preceding dmy format says that an example date string of '01-03-2018' would be interpreted to mean the first day of March in the year 2018.

Si en su lugar se ha especificado mdy, la misma cadena “01-03-2018” significaría el tercer día de enero de 2018.If instead mdy was specified, then the same '01-03-2018' string would mean the third day of January in 2018.

Y si se ha especificado ymd, no hay ninguna garantía de cuáles serían los resultados.And if ymd was specified, there is no guarantee of what the output would be. El valor numérico de “2018” es demasiado grande para ser un día.The numeric value of '2018' is too large to be a day.

Países específicosSpecific countries

En Japón y China, se utiliza el DATEFORMAT ymd.In Japan and China, the DATEFORMAT of ymd is used. Los elementos del formato están en una secuencia que va de la unidad mayor a la menor.The format's parts are in a sensible sequence of largest unit to smallest. Por lo tanto, este formato es útil cuando se quiere ordenar.Consequently, this format sorts well. Este formato se considera el formato internacional.This format is considered to be the international format. Es internacional porque los cuatro dígitos del año son inequívocos y ningún país en la tierra usa el formato arcaico ydm.It is international because the four digits of the year are unambiguous, and no country on Earth uses the archaic format of ydm.

En otros países, como Alemania y Francia, el DATEFORMAT es dmy, lo que significa “dd-mm-aaaa” .In other countries such as Germany and France, the DATEFORMAT is dmy, meaning 'dd-mm-yyyy'. El formato dmy no es adecuado para ordenar, pero es una secuencia razonable de la unidad más pequeña a la mayor.The dmy format does not sort well, but it is a sensible sequence of smallest unit to largest.

Los Estados Unidos y los Estados Federados de Micronesia son los únicos países que utilizan mdy, que no se puede ordenar.The United States, and the Federated States of Micronesia, are the only countries that use mdy, which does not sort. La secuencia mixta del formato coincide con un patrón para decir fechas en comunicación verbal.The format's mixed sequence matches a pattern of verbal speech in spoken dates.

Ejemplo de código de SET DATEFORMAT: mdy frente a dmyCode example of SET DATEFORMAT: mdy versus dmy

El ejemplo de código de Transact-SQL siguiente usa la misma cadena de caracteres de fecha con tres opciones distintas de DATEFORMAT.The following Transact-SQL code example uses the same date character string with three different DATEFORMAT settings. Una ejecución del código genera el resultado que se muestra en el comentario:A run of the code produces the output shown in the comment:

DECLARE @yourDateString NVARCHAR(10) = '12-09-2018';
PRINT @yourDateString + '  = the input.';

SET DATEFORMAT dmy;
SELECT CONVERT(DATE, @yourDateString) AS [DMY-Interpretation-of-input-format];

SET DATEFORMAT mdy;
SELECT CONVERT(DATE, @yourDateString) AS [MDY-Interpretation-of-input-format];

SET DATEFORMAT ymd;
SELECT CONVERT(DATE, @yourDateString) AS [YMD-Interpretation--?--NotGuaranteed];


/***  Actual output:
12-09-2018  = the input.

DMY-Interpretation-of-input-format
2018-09-12

MDY-Interpretation-of-input-format
2018-12-09

YMD-Interpretation--?--NotGuaranteed
2018-12-09
***/

En el ejemplo de código anterior, el último ejemplo tiene una discrepancia entre el formato ymd y la cadena de entrada.In the preceding code example, the final example has a mismatch between format ymd versus the input string. El tercer nodo de la cadena de entrada representa un valor numérico que es demasiado grande para ser un día.The third node of the input string represents a numeric value that is too large to be a day. Microsoft no garantiza el valor de salida de este tipo de errores.Microsoft does not guarantee the output value from such mismatches.

CONVERT ofrece códigos explícitos para control determinista de formatos de fechaCONVERT offers explicit codes for deterministic control of date formats

El artículo de documentación de CAST y CONVERT enumera códigos explícitos que puede usar con la función CONVERT para controlar de forma determinista las conversiones de fecha.Our CAST and CONVERT documentation article lists explicit codes that can you can use with the CONVERT function to deterministically control date conversions. Cada mes el artículo está entre nuestras páginas más visitadas.Every month the article has one of our highest pageview counts.

Nivel de compatibilidad 90 o superiorCompatibility level 90 and above

En SQL Server 2000, el nivel de compatibilidad era 80.In SQL Server 2000, the compatibility level was 80. Para configuraciones del nivel de 80 o inferiores, las conversiones de fecha implícita eran deterministas.For level settings of 80 or below, implicit date conversions were deterministic.

A partir de SQL Server 2005 y su nivel de compatibilidad 90, las conversiones de fecha implícitas pasaron a ser no deterministas.Starting with SQL Server 2005 and its compatibility level of 90, implicit date conversions became nondeterministic. Las conversiones de fecha se convirtieron en dependientes en SET LANGUAGE y SET DATEFORMAT a partir del nivel 90.Date conversions became dependent on SET LANGUAGE and SET DATEFORMAT starting with level 90.

UnicodeUnicode

La conversión de los datos de caracteres no Unicode entre intercalaciones también se considera no determinista.Conversion of non-Unicode character data between collations is also considered nondeterministic.

Vea tambiénSee also