Tutoriels

Meilleures Pratiques de Validation d'Horodatages : Guide Complet

Introduction

La validation des horodatages est cruciale pour la sécurité et la fiabilité de votre application. Ce tutoriel couvre les meilleures pratiques pour valider les horodatages dans différents contextes.

Ce que Vous Apprendrez

  • ✅ Validation de format et longueur
  • ✅ Validation de plage
  • ✅ Validation de précision
  • ✅ Validation de fuseau horaire
  • ✅ Considérations de sécurité

Validation de Format

JavaScript

function validerTimestamp(valeur) {
  // Doit être un nombre ou une chaîne numérique
  const num = Number(valeur);

  if (isNaN(num)) {
    return { valide: false, erreur: 'Pas un nombre valide' };
  }

  // Vérifier la longueur pour déterminer la précision
  const str = String(Math.floor(num));
  const longueurs = [10, 13, 16, 19];

  if (!longueurs.includes(str.length)) {
    return { 
      valide: false, 
      erreur: `Longueur invalide : ${str.length}. Attendu : ${longueurs.join(', ')}` 
    };
  }

  return { valide: true, precision: obtenirPrecision(str.length) };
}

function obtenirPrecision(longueur) {
  const carte = { 10: 'secondes', 13: 'millisecondes', 16: 'microsecondes', 19: 'nanosecondes' };
  return carte[longueur];
}

Python

def valider_timestamp(valeur: str) -> dict:
    """Valide le format de l'horodatage"""
    # Chiffres uniquement
    if not valeur.isdigit():
        return {'valide': False, 'erreur': 'Doit contenir uniquement des chiffres'}

    longueur = len(valeur)
    precisions = {10: 'secondes', 13: 'millisecondes', 16: 'microsecondes', 19: 'nanosecondes'}

    if longueur not in precisions:
        return {
            'valide': False, 
            'erreur': f'Longueur invalide : {longueur}. Attendu : {list(precisions.keys())}'
        }

    return {'valide': True, 'precision': precisions[longueur]}

Validation de Plage

Plages Valides par Précision

PrécisionMinimumMaximumAnnée MinAnnée Max
Secondes (32-bit)0214748364719702038
Secondes (64-bit)025340230079919709999
Millisecondes025340230079999919709999

JavaScript

function validerPlage(timestamp, precision = 'millisecondes') {
  const PLAGES = {
    secondes: { min: 0, max: 253402300799 },
    millisecondes: { min: 0, max: 253402300799999 },
    microsecondes: { min: 0, max: 253402300799999999n },
    nanosecondes: { min: 0n, max: 253402300799999999999n }
  };

  const plage = PLAGES[precision];
  if (!plage) {
    return { valide: false, erreur: 'Précision inconnue' };
  }

  const valeur = precision.includes('nano') ? BigInt(timestamp) : Number(timestamp);

  if (valeur < plage.min || valeur > plage.max) {
    return { 
      valide: false, 
      erreur: `Hors plage : ${plage.min} - ${plage.max}` 
    };
  }

  return { valide: true };
}

Validation de Plage Métier

from datetime import datetime, timezone

def valider_plage_metier(timestamp_ms: int, config: dict) -> dict:
    """Valide que l'horodatage est dans les plages métier"""
    dt = datetime.fromtimestamp(timestamp_ms / 1000, tz=timezone.utc)

    # Ne peut pas être dans le futur
    if config.get('pas_futur', True):
        if dt > datetime.now(timezone.utc):
            return {'valide': False, 'erreur': 'Horodatage dans le futur'}

    # Ne peut pas être trop ancien
    annee_min = config.get('annee_minimum', 2000)
    if dt.year < annee_min:
        return {'valide': False, 'erreur': f'Année antérieure à {annee_min}'}

    # Ne peut pas être trop dans le futur
    annee_max = config.get('annee_maximum', 2100)
    if dt.year > annee_max:
        return {'valide': False, 'erreur': f'Année postérieure à {annee_max}'}

    return {'valide': True, 'datetime': dt}

Validation de Fuseau Horaire

Valider ISO 8601 avec Fuseau Horaire

function validerIso8601(valeur) {
  // Regex pour ISO 8601 avec fuseau horaire obligatoire
  const regex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;

  if (!regex.test(valeur)) {
    return { 
      valide: false, 
      erreur: 'Format ISO 8601 invalide ou fuseau horaire manquant' 
    };
  }

  const date = new Date(valeur);
  if (isNaN(date.getTime())) {
    return { valide: false, erreur: 'Date résultante invalide' };
  }

  return { valide: true, date };
}

Valider Identifiant de Fuseau Horaire

from zoneinfo import ZoneInfo

def valider_fuseau_horaire(zone: str) -> dict:
    """Valide qu'il s'agit d'un identifiant IANA valide"""
    try:
        ZoneInfo(zone)
        return {'valide': True}
    except Exception as e:
        return {'valide': False, 'erreur': f'Fuseau horaire invalide : {zone}'}

# Exemple
print(valider_fuseau_horaire('America/New_York'))  # {'valide': True}
print(valider_fuseau_horaire('EST'))  # {'valide': False, ...} - ambigu

Considérations de Sécurité

1. Prévenir l'Injection

function assainirTimestamp(entree) {
  // N'autoriser que les chiffres et caractères ISO valides
  const assaini = String(entree).replace(/[^0-9TZ:.\-+]/g, '');

  if (assaini !== String(entree)) {
    throw new Error('Caractères invalides détectés');
  }

  return assaini;
}

2. Prévenir le Dépassement

import sys

def valider_sans_depassement(valeur: str) -> dict:
    """Prévient le dépassement d'entiers"""
    try:
        num = int(valeur)

        # Vérifier les limites 64-bit
        if num > sys.maxsize:
            return {'valide': False, 'erreur': 'Dépasse la limite d\'entier'}

        if num < 0:
            return {'valide': False, 'erreur': 'Horodatages négatifs non autorisés'}

        return {'valide': True, 'valeur': num}
    except ValueError:
        return {'valide': False, 'erreur': 'Pas un entier valide'}

3. Rate Limiting pour Horodatages

// Prévenir la manipulation d'horodatages dans les requêtes
function validerTimestampRequete(timestamp, toleranceMs = 30000) {
  const maintenant = Date.now();
  const diff = Math.abs(maintenant - timestamp);

  if (diff > toleranceMs) {
    return { 
      valide: false, 
      erreur: `Horodatage hors tolérance : ${diff}ms > ${toleranceMs}ms` 
    };
  }

  return { valide: true };
}

Résumé

  • Validez le format : Vérifiez longueur et caractères
  • Validez la plage : Technique et métier
  • Validez le fuseau horaire : Utilisez les identifiants IANA
  • Considérez la sécurité : Assainissez, prévenez le dépassement
  • Utilisez des validateurs complets : Combinez toutes les validations

Essayez notre Convertisseur Unix Timestamp pour valider les horodatages !