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écision | Minimum | Maximum | Année Min | Année Max |
|---|---|---|---|---|
| Secondes (32-bit) | 0 | 2147483647 | 1970 | 2038 |
| Secondes (64-bit) | 0 | 253402300799 | 1970 | 9999 |
| Millisecondes | 0 | 253402300799999 | 1970 | 9999 |
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 !