La Apocalipsis de Codificación: Cuando UTF-8 No es UTF-8
El peor desastre de datos que he presenciado ocurrió en una cadena minorista multinacional en 2017. Estaban consolidando datos de clientes de 47 bases de datos regionales en 12 países en un solo almacén de datos. Suficientemente simple, ¿verdad? Exportar a CSV, importar al almacén, ejecutar alguna lógica de deduplicación, y listo. Excepto que los CSV de la división francesa seguían corrompiendo nombres. "François" se convirtió en "François". "Chloé" se convirtió en "Chloé". La división alemana tuvo problemas similares con los umlaut. Los datos de la división japonesa eran completamente ilegibles: solo filas de signos de interrogación y caracteres de reemplazo. ¿La causa raíz? Cada equipo regional había exportado sus CSV utilizando diferentes codificaciones. Francia usó ISO-8859-1 (Latin-1). Alemania usó Windows-1252. Japón usó Shift-JIS. Los equipos del Reino Unido y EE. UU. usaron UTF-8, pero algunos tenían UTF-8 con BOM (Byte Order Mark) y otros sin. Un equipo en España había exportado sus datos en UTF-16LE de alguna manera. El proyecto de consolidación, originalmente programado para tres meses, tomó once meses. Tuvimos que construir una tubería de detección de codificación personalizada que: 1. Intentara detectar la codificación usando múltiples bibliotecas (chardet, charset-normalizer y una heurística personalizada) 2. Validara la detección comprobando patrones de caracteres comunes en cada idioma 3. Convirtiera todo a UTF-8 sin BOM 4. Registrara cada conversión con puntajes de confianza para revisión manual Incluso con esta tubería, tuvimos una tasa de error del 3% que requería corrección manual. Eso es el 3% de 47 millones de registros de clientes: 1.4 millones de nombres que necesitaban revisión humana. ¿La lección? Nunca confíes en la codificación de un CSV. Nunca. Incluso si alguien te dice "definitivamente es UTF-8", verifícalo. He visto archivos que afirmaban ser UTF-8 en sus metadatos pero en realidad eran Windows-1252 con caracteres de alto ASCII. He visto archivos UTF-8 con fragmentos aleatorios de ISO-8859-1 donde alguien copió y pegó desde un sistema antiguo. Incluso he visto un archivo que cambió de codificación a mitad de camino porque el script de exportación falló y se reinició con diferentes configuraciones regionales. Ahora, cada CSV que pasa por mi escritorio se ejecuta a través de un script de validación de codificación antes de que siquiera mire los datos. Me ha ahorrado innumerables horas y ha prevenido al menos una docena de incidentes mayores.El Espacio en Blanco Que No Estaba Allí (Excepto Que Estaba)
En 2018, me trajeron para arreglar un sistema de reconciliación financiera que había estado fallando durante seis meses. La empresa era un procesador de pagos que manejaba miles de millones de dólares en transacciones. Su proceso de reconciliación comparaba registros de transacciones de su base de datos con informes CSV de socios bancarios. El sistema estaba reportando miles de desajustes cada día: transacciones que aparecían en los informes bancarios pero no en su base de datos, o viceversa. El equipo de finanzas estaba conciliando manualmente estos desajustes, trabajando semanas de 60 horas para mantenerse al día. Revisaban cada transacción señalada y encontraban que en realidad existía en ambos sistemas. Los ID de transacción coincidían perfectamente. Pero el sistema automatizado seguía señalándolos como desajustes. Pasé dos días analizando el código, las consultas a la base de datos y la lógica de análisis CSV. Todo parecía correcto. Luego hice algo que debería haber sido obvio desde el principio: abrí el CSV en un editor hexadecimal. Ahí estaba. Cada ID de transacción en los archivos CSV del banco tenía un espacio final. No visible en Excel. No visible en la mayoría de los editores de texto. Pero allí, en el volcado hexadecimal: `54 52 41 4E 53 31 32 33 34 35 20` en lugar de `54 52 41 4E 53 31 32 33 34 35`. Ese último `20` era un carácter de espacio. La base de datos almacenaba los ID de transacción sin espacios finales. La lógica de comparación estaba haciendo una coincidencia exacta de cadenas. "TRANS12345" ≠ "TRANS12345 ". Miles de desajustes falsos, cientos de horas desperdiciadas, todo por un solo carácter de espacio final. Pero aquí es donde se pone peor: los espacios finales no eran consistentes. Algunos ID de transacción los tenían, otros no. Algunos tenían espacios finales, otros tenían espacios iniciales, y algunos tenían ambos. Unos pocos tenían tabulaciones en lugar de espacios. Un archivo memorable tenía una mezcla de espacios, tabulaciones y espacios no separables (U+00A0). La solución fue simple: recortar todos los espacios en blanco durante la importación. Pero la lección fue profunda: el espacio en blanco en los CSV nunca es accidental, siempre es problemático y frecuentemente invisible. Ahora tengo una regla: cada campo de cadena se recorta en la importación, sin excepciones. No me importa si la lógica comercial dice que el campo debería preservar espacios en blanco. No me importa si alguien insiste en que los datos están limpios. Recorta todo. También he aprendido a estar atento a otros caracteres invisibles: espacios de ancho cero (U+200B), no unión de ancho cero (U+200C), unión de ancho cero (U+200D) y el temido carácter de marca de orden de bytes (U+FEFF) que a veces aparece en medio de los archivos. Estos caracteres son los fantasmas en la máquina, invisibles para los humanos pero muy reales para las computadoras.El Formato de Fecha Que Rompió el Comercio Internacional
Déjame contarte sobre la vez que encontré un formato de fecha tan maldito, tan fundamentalmente roto, que todavía atormenta mis sueños. Esto fue en una empresa de logística que coordinaba envíos entre fabricantes en Asia y minoristas en América del Norte y Europa. El sistema funcionaba así: los fabricantes subirían archivos CSV con detalles del envío, incluyendo fechas de recogida, fechas de entrega estimadas y fechas de despacho de aduana. El sistema analizaba estas fechas, calculaba los tiempos de tránsito y coordinaba con las compañías de envío y los agentes de aduana. Todo funcionó bien durante años. Luego, en marzo de 2016, el sistema comenzó a programar envíos para fechas en el pasado. Contenedores que deberían haber sido recogidos el 15 de marzo de 2016, estaban siendo programados para el 15 de marzo de 1916. Documentación aduanera se estaba presentando para fechas que precedían la invención del envío en contenedores. ¿La causa raíz? El formato de fecha automático de Excel combinado con diferencias en los formatos de fecha regionales y una comprensión verdaderamente espectacular de cómo funcionan las fechas. Esto es lo que estaba pasando: 1. Un fabricante en China ingresaría una fecha como "3/15/2016" (15 de marzo de 2016 en formato MM/DD/YYYY) 2. Excel interpretaría esto como una fecha y la almacenaría internamente como un número de serie (42444 para el 15 de marzo de 2016) 3. Al exportarse a CSV, Excel la formatearía de acuerdo con la configuración regional del sistema 4. La configuración regional china usaba el formato YYYY-MM-DD, por lo que se exportó como "2016-03-15" 5. Nuestro sistema de importación, configurado para el formato MM/DD/YYYY, analizaría "2016-03-15" como "2016/03/15" (el mes 2016, día 3, año 15) 6. Dado que el mes 2016 es inválido, el analizador volvería a interpretarlo como "20/16/03/15" 7. A través de una serie de intentos de análisis cada vez más desesperados, finalmente se quedaría con "03/15/1916" Pero espera, se pone peor. Algunos fabricantes estaban usando el formato DD/MM/YYYY. Algunos estaban usando YYYY-MM-DD. Algunos estaban usando MM/DD/YY (años de dos dígitos). Y un fabricante en Taiwán estaba usando el calendario Minguo, donde el año 105 corresponde a 2016 d.C. (1912 + 105). Terminamos con fechas que abarcan desde 1916 hasta 2116, con un grupo particularmente denso alrededor de 1970 (la época de Unix) porque algunos sistemas estaban exportando fechas como marcas de tiempo de Unix y nuestro analizador las estaba interpretando como formato YYYYMMDD. La solución requirió: - Implementar un analizador de fechas con múltiples estrategias que intentaría detectar el formato - Agregar reglas de validación (rechazar fechas antes de 2000 o después de 2050) - Requerir a los fabricantes que usaran exclusivamente el formato ISO 8601 (YYYY-MM-DD) - Construir una interfaz web para cargas de CSV que previsualizara las fechas analizadas antes de la importación - Crear un conjunto de pruebas exhaustivo con fechas en todos los formatos concebibles Incluso con todas estas salvaguardias, ocasionalmente todavía obtenemos errores de análisis de fechas. Justo el mes pasado, encontré un CSV donde alguien había ingresado "2/29/2023" (29 de febrero de 2023—una fecha que no existe porque 2023 no es un año bisiesto). Excel lo aceptó con gusto, lo almacenó como número de serie 45000 y lo exportó como "2023-02-29". Nuestro sistema lo importó, validó que estaba en el formato correcto y programó un envío para una fecha que no existe."El problema con las fechas es que todos piensan que las entienden, pero nadie realmente lo hace. Las fechas son construcciones culturales, no matemáticas. Tienen zonas horarias, horario de verano, años bisiestos, segundos bisiestos, y reformas de calendario. Tienen diferentes formatos en diferentes países, diferentes puntos de partida en diferentes eras, y diferentes significados en diferentes contextos. Y los archivos CSV, con su completa falta de metadatos, no te dan forma de saber qué interpretación es correcta."Esta cita de un colega captura perfectamente el problema de las fechas. Los CSVs no tienen tipos de datos. No tienen esquemas. Son solo texto. Cuando ves "01/02/03" en un CSV, ¿es eso el 2 de enero de 2003? ¿El 1 de febrero de 2003? ¿El 2 de marzo de 2001? ¿El 3 de febrero de 2001? No hay forma de saberlo sin contexto, y el contexto es exactamente lo que los CSVs no proporcionan.
Los Números Que No Eran Números
Aquí hay una tabla de los problemas de datos numéricos más comunes que he encontrado, junto con su frecuencia e impacto típico:| Tipo de Problema | Frecuencia | Impacto Típico | Ejemplo |
|---|---|---|---|
| Separadores de miles | Muy Alto (60%) | Fallos en la importación, errores de tipo | "1,234.56" analizado como cadena |
| Símbolos de moneda | Alto (45%) | Fallos en la importación, errores de cálculo | "$1,234.56" o "€1.234,56" |
| Diferencias en separadores decimales | Alto (40%) | Errores de cálculo catastróficos | "1.234,56" (europeo) vs "1,234.56" (EE. UU.) |
| Notación científica | Medio (25%) | Pérdida de precisión, mala interpretación | "1.23E+05" o "1.23456789E-10" |
| Ceros a la izquierda | Medio (30%) | Pérdida de datos, corrupción de ID | "00123" se convierte en "123" |
| Signos de porcentaje | Medio (20%) | Errores de cálculo 100x | "15%" almacenado como 15 en lugar de 0.15 |
| Formatos de números negativos | Bajo (15%) | Pérdida de signo, cálculos incorrectos | "(123) C
Written by the CSV-X Team Our editorial team specializes in data analysis and spreadsheet management. We research, test, and write in-depth guides to help you work smarter with the right tools. Related Tools Related Articles Data Cleaning 101: Fix Messy Data in 10 Steps — csv-x.com Excel Pivot Tables: Beginner to Advanced How to Fix CSV Encoding Issues (UTF-8, Latin-1, and the Dreaded Mojibake)Put this into practice Try Our Free Tools → |