docs / decisiones / 0016decisions / 0016
ADR 0016. Tipos date y decimal#
- Estado: aceptada
- Fecha: 2026-09-17 (SPEC 1.1)
- Especificación: SPEC.md §4, §6 y §7
Contexto y problema#
Los dominios de integración declaran con frecuencia fechas y montos. En SPEC 1.0 solo
podían representarse como str (sin validación) o float (con pérdida de precisión
binaria y sin conservar la escala, p. ej. 12.50). Las familias oficiales ya describían
fechas como texto libre: la clave de cabecera d es str con la descripción «generation
date YYYYMMDD». El ingeniero integrador necesita declarar el tipo y que el analizador
reporte E06 con número de línea cuando un valor no lo cumple, o conocer la justificación
de su exclusión.
Alternativas consideradas#
- Excluir los tipos y documentar el uso de
strcon validación en la aplicación. dateydecimalcomo tipos escalares con forma textual estricta y valor canónico string.- Fecha y hora con zona horaria (ISO 8601 completo) y decimales como
numberJSON.
Decisión#
Se adopta la alternativa 2:
date:AAAA-MM-DD, día existente del calendario gregoriano proléptico entre 0001-01-01 y 9999-12-31; JSON canónico, el mismo texto.min/maxopcionales como cadenasAAAA-MM-DD(E13).decimal:-?[0-9]+(\.[0-9]+)?, sin exponente; JSON canónico string, sin ceros a la izquierda en la parte entera ni signo en el cero, conservando todos los dígitos fraccionarios.min/maxopcionales como cadenas decimales o enteros menores que 2^53 en valor absoluto, comparados exactamente (E13).- Formas inválidas: E06 con la línea del registro o de la cabecera. Límites inválidos en el contrato: E20. Ambos tipos se admiten en campos, elementos de lista, componentes de tupla y claves de cabecera.
Consecuencias#
- Un documento 1.0 no cambia; un contrato que usa
dateodecimalrequiere una implementación 1.1. El caso de contrato 1.0 que usabadatecomo tipo desconocido pasa a usardatetime. - El valor canónico string evita que JavaScript o Python redondeen el decimal por coma
flotante binaria y conserva la escala; el consumidor decide la conversión a su tipo
exacto (p. ej.
decimal.Decimal). - Se excluye la hora y la zona horaria (alternativa 3): sus variantes (desplazamientos,
segundos intercalares, fracciones) exceden una forma léxica simple y verificable por
línea; un instante puede declararse como
stro como dos campos. - El serializador Python acepta además
datetime.dateydecimal.Decimal; unfloatpara undecimales E06, porque su valor exacto no es el decimal escrito. - El bloque de especificación del prompt indica la forma textual de ambos tipos.
Evidencia#
- forks/a/README.md: la clave de cabecera
dse documenta comostr, «generation date YYYYMMDD», sin validación de tipo. - generative/results/e1_samples.csv: los fallos de CSV con Haiku («invalid literal for int() with base 10: '0.2'») muestran que la ausencia de tipos explícitos traslada la validación numérica a cada consumidor.
- Casos 1.1 en conformance/cases/types.json
(
date-decimal-basic,decimal-normalised,decimal-exact-digits,date-decimal-composites,date-bad-format,date-not-in-calendar,date-error-linecon E06 en la línea 3,date-range,decimal-range-max,date-lenient, entre otros), header.json (hdr-date-bad), roundtrip.json (dumps-date-decimal,dumps-error-date,dumps-error-decimal-float) y contract.json (contract-date-decimal-valid,contract-date-bad-bound,contract-decimal-float-bound). - El caso
decimal-exact-digitsusa0.1000000000000000055511151231257827, que unfloatbinario no conserva.
Decision records are written in Spanish.
ADR 0016. Tipos date y decimal#
- Estado: aceptada
- Fecha: 2026-09-17 (SPEC 1.1)
- Especificación: SPEC.md §4, §6 y §7
Contexto y problema#
Los dominios de integración declaran con frecuencia fechas y montos. En SPEC 1.0 solo
podían representarse como str (sin validación) o float (con pérdida de precisión
binaria y sin conservar la escala, p. ej. 12.50). Las familias oficiales ya describían
fechas como texto libre: la clave de cabecera d es str con la descripción «generation
date YYYYMMDD». El ingeniero integrador necesita declarar el tipo y que el analizador
reporte E06 con número de línea cuando un valor no lo cumple, o conocer la justificación
de su exclusión.
Alternativas consideradas#
- Excluir los tipos y documentar el uso de
strcon validación en la aplicación. dateydecimalcomo tipos escalares con forma textual estricta y valor canónico string.- Fecha y hora con zona horaria (ISO 8601 completo) y decimales como
numberJSON.
Decisión#
Se adopta la alternativa 2:
date:AAAA-MM-DD, día existente del calendario gregoriano proléptico entre 0001-01-01 y 9999-12-31; JSON canónico, el mismo texto.min/maxopcionales como cadenasAAAA-MM-DD(E13).decimal:-?[0-9]+(\.[0-9]+)?, sin exponente; JSON canónico string, sin ceros a la izquierda en la parte entera ni signo en el cero, conservando todos los dígitos fraccionarios.min/maxopcionales como cadenas decimales o enteros menores que 2^53 en valor absoluto, comparados exactamente (E13).- Formas inválidas: E06 con la línea del registro o de la cabecera. Límites inválidos en el contrato: E20. Ambos tipos se admiten en campos, elementos de lista, componentes de tupla y claves de cabecera.
Consecuencias#
- Un documento 1.0 no cambia; un contrato que usa
dateodecimalrequiere una implementación 1.1. El caso de contrato 1.0 que usabadatecomo tipo desconocido pasa a usardatetime. - El valor canónico string evita que JavaScript o Python redondeen el decimal por coma
flotante binaria y conserva la escala; el consumidor decide la conversión a su tipo
exacto (p. ej.
decimal.Decimal). - Se excluye la hora y la zona horaria (alternativa 3): sus variantes (desplazamientos,
segundos intercalares, fracciones) exceden una forma léxica simple y verificable por
línea; un instante puede declararse como
stro como dos campos. - El serializador Python acepta además
datetime.dateydecimal.Decimal; unfloatpara undecimales E06, porque su valor exacto no es el decimal escrito. - El bloque de especificación del prompt indica la forma textual de ambos tipos.
Evidencia#
- forks/a/README.md: la clave de cabecera
dse documenta comostr, «generation date YYYYMMDD», sin validación de tipo. - generative/results/e1_samples.csv: los fallos de CSV con Haiku («invalid literal for int() with base 10: '0.2'») muestran que la ausencia de tipos explícitos traslada la validación numérica a cada consumidor.
- Casos 1.1 en conformance/cases/types.json
(
date-decimal-basic,decimal-normalised,decimal-exact-digits,date-decimal-composites,date-bad-format,date-not-in-calendar,date-error-linecon E06 en la línea 3,date-range,decimal-range-max,date-lenient, entre otros), header.json (hdr-date-bad), roundtrip.json (dumps-date-decimal,dumps-error-date,dumps-error-decimal-float) y contract.json (contract-date-decimal-valid,contract-date-bad-bound,contract-decimal-float-bound). - El caso
decimal-exact-digitsusa0.1000000000000000055511151231257827, que unfloatbinario no conserva.