Introducción
La validación de timestamps es crucial para la seguridad y confiabilidad de tu aplicación. Este tutorial cubre las mejores prácticas para validar timestamps en diferentes contextos.
Lo que Aprenderás
- ✅ Validación de formato y longitud
- ✅ Validación de rango
- ✅ Validación de precisión
- ✅ Validación de zona horaria
- ✅ Consideraciones de seguridad
Validación de Formato
JavaScript
JAVASCRIPT1function validarTimestamp(valor) { 2 // Debe ser número o string numérico 3 const num = Number(valor); 4 5 if (isNaN(num)) { 6 return { valido: false, error: 'No es un número válido' }; 7 } 8 9 // Verificar longitud para determinar precisión 10 const str = String(Math.floor(num)); 11 const longitudes = [10, 13, 16, 19]; 12 13 if (!longitudes.includes(str.length)) { 14 return { 15 valido: false, 16 error: `Longitud inválida: ${str.length}. Esperado: ${longitudes.join(', ')}` 17 }; 18 } 19 20 return { valido: true, precision: obtenerPrecision(str.length) }; 21} 22 23function obtenerPrecision(longitud) { 24 const mapa = { 10: 'segundos', 13: 'milisegundos', 16: 'microsegundos', 19: 'nanosegundos' }; 25 return mapa[longitud]; 26}
Python
PYTHON1def validar_timestamp(valor: str) -> dict: 2 """Valida formato de timestamp""" 3 # Solo dígitos 4 if not valor.isdigit(): 5 return {'valido': False, 'error': 'Debe contener solo dígitos'} 6 7 longitud = len(valor) 8 precisiones = {10: 'segundos', 13: 'milisegundos', 16: 'microsegundos', 19: 'nanosegundos'} 9 10 if longitud not in precisiones: 11 return { 12 'valido': False, 13 'error': f'Longitud inválida: {longitud}. Esperado: {list(precisiones.keys())}' 14 } 15 16 return {'valido': True, 'precision': precisiones[longitud]}
Validación de Rango
Rangos Válidos por Precisión
| Precisión | Mínimo | Máximo | Año Min | Año Max |
|---|---|---|---|---|
| Segundos (32-bit) | 0 | 2147483647 | 1970 | 2038 |
| Segundos (64-bit) | 0 | 253402300799 | 1970 | 9999 |
| Milisegundos | 0 | 253402300799999 | 1970 | 9999 |
JavaScript
JAVASCRIPT1function validarRango(timestamp, precision = 'milisegundos') { 2 const RANGOS = { 3 segundos: { min: 0, max: 253402300799 }, 4 milisegundos: { min: 0, max: 253402300799999 }, 5 microsegundos: { min: 0, max: 253402300799999999n }, 6 nanosegundos: { min: 0n, max: 253402300799999999999n } 7 }; 8 9 const rango = RANGOS[precision]; 10 if (!rango) { 11 return { valido: false, error: 'Precisión desconocida' }; 12 } 13 14 const valor = precision.includes('nano') ? BigInt(timestamp) : Number(timestamp); 15 16 if (valor < rango.min || valor > rango.max) { 17 return { 18 valido: false, 19 error: `Fuera de rango: ${rango.min} - ${rango.max}` 20 }; 21 } 22 23 return { valido: true }; 24}
Validación de Rango de Negocio
PYTHON1from datetime import datetime, timezone 2 3def validar_rango_negocio(timestamp_ms: int, config: dict) -> dict: 4 """Valida que el timestamp esté dentro de rangos de negocio""" 5 dt = datetime.fromtimestamp(timestamp_ms / 1000, tz=timezone.utc) 6 7 # No puede ser en el futuro 8 if config.get('no_futuro', True): 9 if dt > datetime.now(timezone.utc): 10 return {'valido': False, 'error': 'Timestamp en el futuro'} 11 12 # No puede ser demasiado antiguo 13 min_year = config.get('año_minimo', 2000) 14 if dt.year < min_year: 15 return {'valido': False, 'error': f'Año anterior a {min_year}'} 16 17 # No puede ser demasiado en el futuro 18 max_year = config.get('año_maximo', 2100) 19 if dt.year > max_year: 20 return {'valido': False, 'error': f'Año posterior a {max_year}'} 21 22 return {'valido': True, 'datetime': dt}
Validación de Zona Horaria
Validar ISO 8601 con Zona Horaria
JAVASCRIPT1function validarIso8601(valor) { 2 // Regex para ISO 8601 con zona horaria obligatoria 3 const regex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/; 4 5 if (!regex.test(valor)) { 6 return { 7 valido: false, 8 error: 'Formato ISO 8601 inválido o falta zona horaria' 9 }; 10 } 11 12 const fecha = new Date(valor); 13 if (isNaN(fecha.getTime())) { 14 return { valido: false, error: 'Fecha resultante inválida' }; 15 } 16 17 return { valido: true, fecha }; 18}
Validar Identificador de Zona Horaria
PYTHON1from zoneinfo import ZoneInfo 2 3def validar_zona_horaria(zona: str) -> dict: 4 """Valida que sea un identificador IANA válido""" 5 try: 6 ZoneInfo(zona) 7 return {'valido': True} 8 except Exception as e: 9 return {'valido': False, 'error': f'Zona horaria inválida: {zona}'} 10 11# Ejemplo 12print(validar_zona_horaria('America/New_York')) # {'valido': True} 13print(validar_zona_horaria('EST')) # {'valido': False, ...} - ambiguo
Consideraciones de Seguridad
1. Prevenir Inyección
JAVASCRIPT1function sanitizarTimestamp(entrada) { 2 // Solo permitir dígitos y caracteres ISO válidos 3 const sanitizado = String(entrada).replace(/[^0-9TZ:.\-+]/g, ''); 4 5 if (sanitizado !== String(entrada)) { 6 throw new Error('Caracteres inválidos detectados'); 7 } 8 9 return sanitizado; 10}
2. Prevenir Overflow
PYTHON1import sys 2 3def validar_sin_overflow(valor: str) -> dict: 4 """Previene overflow de enteros""" 5 try: 6 num = int(valor) 7 8 # Verificar límites de 64-bit 9 if num > sys.maxsize: 10 return {'valido': False, 'error': 'Excede límite de entero'} 11 12 if num < 0: 13 return {'valido': False, 'error': 'Timestamps negativos no permitidos'} 14 15 return {'valido': True, 'valor': num} 16 except ValueError: 17 return {'valido': False, 'error': 'No es un entero válido'}
3. Rate Limiting para Timestamps
JAVASCRIPT1// Prevenir manipulación de timestamps en requests 2function validarTimestampRequest(timestamp, toleranciaMs = 30000) { 3 const ahora = Date.now(); 4 const diff = Math.abs(ahora - timestamp); 5 6 if (diff > toleranciaMs) { 7 return { 8 valido: false, 9 error: `Timestamp fuera de tolerancia: ${diff}ms > ${toleranciaMs}ms` 10 }; 11 } 12 13 return { valido: true }; 14}
Validador Completo
PYTHON1from datetime import datetime, timezone 2from typing import Union 3 4class ValidadorTimestamp: 5 def __init__(self, config=None): 6 self.config = config or {} 7 8 def validar(self, valor: Union[str, int]) -> dict: 9 """Validación completa de timestamp""" 10 errores = [] 11 12 # 1. Formato 13 formato = self._validar_formato(valor) 14 if not formato['valido']: 15 return formato 16 17 # 2. Rango técnico 18 rango = self._validar_rango(valor, formato['precision']) 19 if not rango['valido']: 20 return rango 21 22 # 3. Rango de negocio 23 negocio = self._validar_negocio(valor, formato['precision']) 24 if not negocio['valido']: 25 return negocio 26 27 return { 28 'valido': True, 29 'precision': formato['precision'], 30 'datetime': negocio['datetime'] 31 } 32 33 def _validar_formato(self, valor): 34 # ... implementación 35 pass 36 37 def _validar_rango(self, valor, precision): 38 # ... implementación 39 pass 40 41 def _validar_negocio(self, valor, precision): 42 # ... implementación 43 pass
Resumen
- Valida formato: Verifica longitud y caracteres
- Valida rango: Técnico y de negocio
- Valida zona horaria: Usa identificadores IANA
- Considera seguridad: Sanitiza, previene overflow
- Usa validadores completos: Combina todas las validaciones
¡Prueba nuestro Convertidor Unix Timestamp para validar timestamps!