Montos en pesos y unidades fijas: precisión, vigencia y tipo de cambio normativo
Una integración auditable conserva cantidad de UF, valor unitario, moneda, período y total como datos separados. Reducirlos a un número flotante impide reconstruir el cálculo.
Por Marco Ferreiro ·
Una respuesta que dice monto: 85162.5 parece sencilla hasta que alguien pregunta de dónde salió. No revela si el origen estaba en pesos o en unidades fijas, qué valor unitario se usó, cuál era su vigencia ni si otro sistema redondeó el número durante el intercambio.
En multas expresadas en UF, el total es un resultado derivado. Para auditarlo hay que conservar los operandos y el contexto normativo, no sólo el último número de la operación.
ARS y UF no son el mismo tipo de dato
ISO 4217 proporciona códigos para identificar monedas y su relación con unidades menores. ARS identifica al peso argentino. Una UF, en cambio, no es otra moneda: es una unidad definida por una norma jurisdiccional y convertida a pesos según reglas locales.
La diferencia evita un contrato engañoso. Un campo llamado currency: "UF" mezclaría dos conceptos. Es preferible representar:
unit: "UF"para la unidad de sanción;quantitypara la cantidad atribuida por la fuente;unitValuepara su valor monetario;currency: "ARS"para la moneda de conversión;validFromy, cuando exista,validTopara la vigencia.
Así el consumidor sabe qué dato provino de la norma y cuál fue calculado.
Un total sin versión no se puede reproducir
Provincia de Buenos Aires publica una página específica con el valor vigente y la resolución que lo establece. CABA, por su parte, regula en la Ley 451 una UF vinculada a un parámetro de combustible y un momento de conversión. Estos ejemplos muestran por qué no existe un valor nacional intercambiable.
Una integración debe asociar el valor unitario a su jurisdicción y fuente. Como mínimo, el registro necesita:
| Campo | Ejemplo ficticio | Función |
|---|---|---|
quantityUf |
"12.5" |
Cantidad informada |
unitValueArs |
"1234.56" |
Valor unitario exacto |
validFrom |
"2026-01-01" |
Inicio de vigencia declarado |
sourceUrl |
URL oficial | Evidencia normativa |
totalArs |
"15432.00" |
Resultado reproducible |
El ejemplo no corresponde a una multa real. Sirve para probar que 12.5 × 1234.56 = 15432.00 se conserva sin alterar la escala.
Por qué un flotante binario puede cambiar centavos
RFC 8259 permite números JSON con fracción, pero también advierte que las implementaciones pueden limitar rango y precisión. Muchos lenguajes convierten esos números al formato binario IEEE 754. Ciertos decimales cotidianos no tienen una representación binaria exacta, de modo que operaciones encadenadas pueden producir residuos invisibles al principio y diferencias al redondear.
El problema no significa que JSON sea inadecuado. Significa que el contrato debe elegir una estrategia:
- cadenas decimales con patrón, escala máxima y reglas de normalización;
- enteros en la unidad mínima acordada, cuando todos los valores admiten esa escala;
- un tipo decimal nativo dentro de cada sistema, con serialización explícita en el borde.
RFC 8785 señala que números que no encajan naturalmente en el ecosistema JSON pueden envolverse como cadenas. Para dinero y UF, esa decisión debe documentarse y probarse en todos los clientes soportados.
La escala también forma parte del contrato
"10", "10.0" y "10.00" representan el mismo valor matemático, pero no siempre la misma intención contable. El contrato puede exigir dos decimales para ARS y permitir una escala definida para UF. También debe decidir si acepta ceros finales, signo positivo, notación exponencial o separador decimal distinto del punto.
Una opción conservadora es prohibir notación científica y comas, aceptar sólo cadenas como ^-?[0-9]+(\.[0-9]+)?$ y declarar la escala máxima. Después se aplica redondeo decimal una sola vez, en el punto establecido por la regla del negocio.
No conviene redondear cada operando antes de multiplicar y volver a redondear el total sin documentarlo. Ese doble redondeo puede impedir reconciliar la respuesta con la fuente.
Vigencia no equivale a fecha del hecho
Guardar validFrom no responde automáticamente qué UF corresponde a un expediente. Según la jurisdicción, pueden importar la fecha del hecho, el pago voluntario, una resolución firme, el efectivo pago u otro momento normativo. La API no debe inventar esa selección.
Por eso proponemos separar:
occurredAt, si la fuente informa cuándo ocurrió el hecho;unitValueValidAt, fecha a la que pertenece la tabla elegida;calculatedAt, momento en que el integrador hizo la operación;calculationBasis, referencia textual y URL oficial.
Si la fuente entrega sólo un total en pesos, quantityUf o unitValueArs deben quedar ausentes, no reconstruidos a partir de una división especulativa.
Pruebas de ida y vuelta
Una prueba útil serializa el objeto, lo consume desde cada lenguaje soportado y vuelve a producirlo. El valor decimal debe conservarse byte a byte o normalizarse a la misma forma canónica. Además conviene probar:
- cantidades enteras y fraccionarias de UF;
- valores unitarios con centavos;
- totales grandes sin notación exponencial;
- campos ausentes cuando la fuente no expone el desglose;
- cambio de vigencia sin sobrescribir cálculos históricos;
- correcciones de la fuente mediante una nueva versión, no una mutación silenciosa.
La reconciliación debe comparar decimal exacto y procedencia. Comparar sólo lo que muestra la interfaz puede ocultar que dos totales visualmente iguales se calcularon con tablas diferentes.
Una respuesta auditable conserva la fórmula
El contrato final no promete que el importe sea jurídicamente exigible ni elige la norma aplicable. Informa qué entregó la fuente, qué tabla se vinculó y cómo se obtuvo el total mostrado.
Con cantidad de UF, valor unitario, ARS, vigencia, fuente y regla de redondeo separados, un cliente puede reproducir el cálculo meses después. Esa trazabilidad es más valiosa que ahorrar cuatro campos y quedarse con un flotante imposible de explicar.
Metodología
- Alcance
- Diseño de un contrato de datos para montos expresados en unidades normativas y pesos argentinos, contrastado con estándares de intercambio.
- Unidad de análisis
- Cada componente reproducible del cálculo, incluyendo cantidad, valor unitario, moneda, vigencia, fuente y total.
- Cobertura
- Estándares ISO e IETF y ejemplos normativos oficiales de CABA y Provincia de Buenos Aires verificados el 14 de agosto de 2026.
Limitaciones
- El modelo no determina qué valor de UF corresponde aplicar a una infracción o expediente individual.
- Las jurisdicciones pueden definir unidades, períodos y momentos de conversión diferentes.
Fuentes
- ISO 4217 — códigos para la representación de monedas — International Organization for Standardization (consultada el )
- RFC 8259 — formato de intercambio de datos JSON — RFC Editor (consultada el )
- RFC 8785 — esquema de canonicalización de JSON — RFC Editor (consultada el )
- Valor y normativa vigente de la Unidad Fija bonaerense — Ministerio de Transporte de la Provincia de Buenos Aires (consultada el )
- Ley 451 de la Ciudad de Buenos Aires — Régimen de Faltas — Boletín Oficial de la Ciudad de Buenos Aires (consultada el )
Preguntas frecuentes
¿Conviene enviar el monto monetario como número JSON?
Para valores con decimales que deben conservarse exactamente entre lenguajes, una cadena decimal canónica suele ser más explícita. Otra opción es un entero en unidades menores, siempre que la escala y las reglas estén documentadas y versionadas.
¿La UF es una moneda con código ISO 4217?
No. ARS identifica al peso argentino; la UF es una unidad normativa definida por cada jurisdicción. Por eso la cantidad de UF y su conversión a ARS deben viajar en campos distintos.
¿Alcanza con guardar el valor actual de la UF?
No. También hacen falta su período de vigencia, la fuente oficial y cuándo fue observada. El valor actual puede cambiar y no explica qué versión utilizó una liquidación anterior.
Notas relacionadas
Cómo versionar una respuesta cuando cada jurisdicción cambia
Una respuesta agregada necesita distinguir versión de contrato, revisión de datos y estado de cada fuente. Así un cambio municipal no obliga a reinterpretar silenciosamente todo el resultado.
Cobertura de una API: cómo comunicar fuentes caídas y resultados parciales
Una integración de infracciones necesita informar qué fuentes respondió, cuáles fallaron y si el resultado es completo. Un cero sin cobertura comprobada puede inducir decisiones incorrectas.
Timeout no significa “sin multas”: cómo informar resultados parciales en una integración
Cuando una fuente no responde, el resultado es parcial o indeterminado, nunca cero. Un contrato explícito permite reintentar, alertar y decidir sin producir falsos negativos.