Grâce à la diversité des cultures sur Terre, nous avons une variété de formats de date. Pour les dates numériques, nous avons mois-jour-année, jour-mois-année et année-mois-jour. Nous avons également des formats courts et longs. Les dates peuvent être mélangées avec le temps, ce qui est une autre histoire. Cette réalité nous suit au travail. C'est pourquoi le format de date SQL n'est pas quelque chose que nous pouvons prendre facilement.
Aux Philippines, nous utilisons 2 formats :mois-jour-année et jour-mois-année. Mois-jour-année est le format général des dates numériques. Mais avec des formats de date plus longs, nous utilisons indifféremment jour-mois-année et mois-jour-année.
Au travail, je n'ai jamais rencontré de paramètre de format de date SQL Server autre que mois-jour-année. Cependant, cela varie dans les rapports et les fichiers pour les échanges de données et le projet Extract-Transform-Load (ETL). Sans parler des utilisateurs qui le changent dans leurs stations pour des préférences personnelles ! Avec tous ces scénarios, ne pas les gérer de manière appropriée est une recette à casser.
Vos applications traitent-elles de cultures différentes ? C'est un autre niveau de complexité et un problème lorsqu'il s'agit de ces différents formats de date SQL. Dans cet article, nous explorerons la norme pour traiter toutes ces variétés et exemples. A lire jusqu'au bout ! Mais avant de continuer, faisons un petit détour sur la façon dont SQL Server stocke les dates.
Comment SQL Server stocke les dates
Faites une supposition. SQL Server stocke-t-il le 29/03/2021 21h35 tel quel dans la base de données ? Que diriez-vous du 2021-03-29 ? Sont-ils stockés sous forme de chaînes formatées ? D'après cette documentation de Microsoft, ce n'est pas comme ça.
Prenons le type de données DATE, par exemple. Il est stocké sous la forme d'un entier de 3 octets.
Comment le savons-nous ?
Eh bien, Microsoft le dit, mais ne fournit pas plus d'informations. Cela ne signifie pas que nous ne pouvons pas le savoir avec certitude. Tout d'abord, la valeur minimale du type de données DATE est 01/01/0001 ou 1er janvier, 1 CE ou ère commune. Pour convertir ceci en entier, nous convertissons d'abord cette date en VARBINARY, comme ceci :
SELECT CAST(CAST('01/01/0001' AS DATE) AS VARBINARY(3))
Le résultat est 0x000000 au format hexadécimal. À partir de cette valeur, nous pouvons voir que la valeur entière du 1er janvier 1 CE est 0. C'est logique car c'est la valeur DATE minimale.
Maintenant, nous avançons d'un jour.
SELECT CAST(CAST('01/02/0001' AS DATE) AS VARBINARY(3)) -- January 2, 1 CE
Le résultat est 0x010000 . C'est un peu délicat, mais cet article nous a donné une idée. On ne peut pas le traiter comme on le voit. Les octets sont inversés et la valeur hexadécimale réelle est 0x000001 . Si vous connaissez un peu les nombres hexadécimaux, vous savez que cela est égal à 1 - c'est 1 jour à partir du point de départ, le 1er janvier 1 CE.
Maintenant, essayons une date récente :29/03/2021.
SELECT CAST(CAST('03/29/2021' AS DATE) AS VARBINARY(3))
Le résultat est 0x55420B . Lorsque nous l'inversons, il devient 0x0B4255 . Cette fois, nous ne pouvons pas connaître la valeur en la regardant. Donc, nous le multiplions par 1 comme un entier.
SELECT 0x0B4255 * CAST(1 AS INT)
Le résultat est 737 877 . C'est le nombre de jours depuis le 1er janvier 1 CE. Vérifions-le avec DATEDIFF.
SELECT DATEDIFF(DAY,CAST('01/01/0001' AS DATE),CAST('03/29/2021' AS DATE))
Le résultat est le même :737 877 jours. Très cool !
Conclusion :la date formatée est uniquement à des fins de présentation
C'est ainsi que SQL Server stocke les types de données DATE. C'est différent pour DATETIME, SMALLDATETIME et DATETIME2, mais toujours stockés sous forme d'entiers. SQL Server calcule la durée à partir du point de départ et affiche la date que nous pouvons tous comprendre.
Que vous le regardiez dans SQL Server Management Studio, dbForge Studio pour SQL Server ou votre application, le 29/03/2021 n'est qu'une présentation. Si vous modifiez la région ou la langue, la valeur stockée 0x55420B restera le même.
Nous savons maintenant que les dates ne sont pas stockées sous forme de chaînes. Nous pouvons oublier de stocker les dates dans un format spécifique . Ce n'est pas comme ça que ça marche de toute façon. Examinons plutôt différentes manières dans SQL de formater les dates dont vos applications ont besoin.
Les 4 façons simples de formater les dates
Examinons les fonctions de date SQL suivantes :
- Fonction CONVERT
- DÉFINIR LA LANGUE
- RÉGLER LE FORMAT DE DATE
- Fonction FORMAT
Vous pouvez également utiliser un formateur de requête SQL.
1. Fonction CONVERT
CONVERT est l'une des fonctions de conversion de données qui peut également servir au formatage de la date. La figure 1 montre un exemple.
Les deux premiers arguments de CONVERT sont le type de données cible et la valeur de date. Le troisième est facultatif mais s'applique également aux dates. Les valeurs numériques sont les styles de format de date SQL à utiliser lors de la conversion de date en chaîne.
Dans la figure 1, le Japon utilise un format année-mois-jour avec une barre oblique comme séparateur. L'Allemagne utilise jour-mois-année avec des points comme séparateurs. La Grande-Bretagne et la France utilisent la même séquence que l'Allemagne, mais avec une barre oblique comme séparateur. Seuls les États-Unis utilisent mois-jour-année avec un trait d'union comme séparateur.
En SQL, vous pouvez également convertir l'expression DATETIME en DATE.
Pour une liste complète des styles de format de date CONVERT dans SQL, consultez cette référence de Microsoft.
2. DÉFINIR LA LANGUE
Ce paramètre spécifie la langue appliquée à la session. Cela affecte les formats de date et les messages système. Lorsque vous définissez une langue, vous appliquez également implicitement les paramètres SET DATEFORMAT (nous y reviendrons plus tard).
Pour l'instant, vérifions les exemples de la figure 2. Je modifie les paramètres de langue en lituanien, puis en anglais.
Regardez la figure 2. Le format de date lituanien est année-mois-jour. Chaque fois que j'essaie des dates différentes, la date longue inclut toujours "m." avant le mois et "d." après le jour. La première lettre du mois et le nom du jour de la semaine ne sont pas non plus en majuscule. C'est différent pour les autres paramètres de langue, mais vous avez compris.
Pour plus d'informations sur SET LANGUAGE, consultez cette référence de Microsoft.
3. DÉFINIR LE FORMAT DE DATE
Ce paramètre place l'ordre du mois, du jour et de l'année pour l'interprétation des chaînes de caractères de date. Il remplacera les paramètres de format de date implicites définis par SET LANGUAGE. Voici un exemple dans la figure 3.
Dans la figure 3, le code utilise le format DMY ou jour-mois-année. Avec ces paramètres, toute valeur de date définie sur une variable de date doit suivre ce modèle. 30/03/2021 correspond à ce format, mais 03/31/2021 déclenche une erreur car 31 n'est pas un mois valide.
Ainsi, les modifications du format de date peuvent casser votre application si la logique fonctionne sur la prémisse d'un autre format.
Pour plus d'informations sur SET DATEFORMAT, consultez cette référence de Microsoft.
4. Fonction FORMATER
De toutes les options de formatage disponibles, celle-ci est la plus flexible. Il en va de même pour le formatage de la date dans .Net, car FORMAT repose sur la présence du .Net Framework sur le serveur sur lequel SQL Server est installé. C'est cependant l'inconvénient de cette option.
Tout comme le faire en C #, FORMAT prend une valeur de date et une chaîne de format. Prenons quelques exemples dans la figure 4.
Comme dans .Net, dans SQL Server, vous pouvez formater les dates en utilisant différents séparateurs. De plus, vous pouvez positionner le mois, le jour et l'année n'importe où. Ensuite, vous pouvez obtenir les informations culturelles et utiliser leur format de date.
Pour plus d'informations et d'exemples sur FORMAT, consultez cette référence de Microsoft.
Maintenant, nous avons identifié 4 façons de formater les dates et la variété des formats de date. Existe-t-il un format standard qui fonctionne toujours lors de la conversion de chaînes en dates ?
ISO 8601 - Le format de date SQL le plus portable et sans erreur que vous pouvez utiliser pour la conversion
ISO 8601 existe depuis 1988. C'est la norme internationale dans les échanges de données relatives aux dates et heures .
Il est également disponible dans la fonction CONVERT comme l'un des styles de format de date :les styles 126 et 127 sont conformes à la norme ISO 8601.
Qu'est-ce qui le rend portable et sans erreur ?
Le problème avec les formats non ISO 8601
Démontrons le problème pour les non-ISO 8601 avec un exemple :
DECLARE @d VARCHAR(10) = '03/09/2021';
SET LANGUAGE Italian;
SELECT FORMAT(CONVERT(DATETIME, @d),'D')
SET LANGUAGE English
SELECT FORMAT(CONVERT(DATETIME, @d),'D')
SET DATEFORMAT DMY
SELECT FORMAT(CONVERT(DATETIME, @d),'D')
SET DATEFORMAT MDY
SELECT FORMAT(CONVERT(DATETIME, @d),'D')
En fonction de votre date locale, vous pouvez interpréter @d comme le 9 mars 2021 ou le 3 septembre 2021. Vous ne pouvez pas être sûr de qui est qui. C'est là que réside le problème.
Vérifiez le résultat dans la figure 5 ci-dessous :
Même SQL Server ne le sait pas avec certitude !
Pire encore, ce type de scénario peut casser votre application comme ce qui s'est passé dans la figure 3 plus tôt. Cette situation est problématique pour les applications traitant avec des utilisateurs multiculturels.
La norme ISO 8601 peut-elle vous aider ?
Utilisation d'ISO 8601 pour résoudre les problèmes de formatage
Remarquez quand le format ISO 8601 aaaaMMjj est utilisé à la place de MM/jj/aaaa et vérifiez le résultat dans la Figure 6 :
Ce sera toujours le 9 mars, quels que soient les paramètres de langue et de format de date utilisés. C'est idéal pour les échanges de données et les intégrations de systèmes. Si votre utilisateur a un autre format de date dans la station, cela n'aura pas d'importance non plus.
Si vous devez transformer vos dates en chaînes et inversement, utilisez ISO 8601.
ISO 8601 dans SQL Server se décline en 2 versions :
- AAAAMMJJ est pour les dates seulement.
- AAAA-MM-JJTHH:MM:SS pour un mélange de date et d'heure, où T est le délimiteur entre la date et l'heure.
Autres façons de gérer les formats de date des applications vers SQL Server
1. Utiliser les commandes sensibles à la date dans l'application
Lorsque vous demandez à un utilisateur de saisir des dates dans un formulaire, ne le laissez pas utiliser de texte libre. Utilisez des contrôles de date qui permettent de choisir uniquement parmi les valeurs valides.
2. Convertir dans un format différent uniquement en cas de besoin
Ne continuez pas à transformer les dates en chaînes et vice versa. Utilisez les types de données natifs Date ou DateTime de l'application appelante. Si vous devez les transformer pour quelque raison que ce soit, utilisez la norme ISO 8601.
3. Définissez la date/heure, le fuseau horaire et la culture dans le démarrage de votre application, le cas échéant
Si votre application utilise un format de date fixe et que vos utilisateurs aiment modifier les formats de date, vous pouvez corriger les deux au démarrage de l'application. Définissez explicitement ce dont votre application a besoin. Ce sera bien mieux si votre administrateur réseau peut verrouiller ces paramètres.
À emporter
Alors, la gestion des variétés de format de date SQL est-elle écrasante ? Je ne peux pas vous en vouloir si vous le trouvez toujours ainsi, mais nous avons découvert que ce n'est pas impossible.
Voici ce que nous avons couvert :
- Les dates SQL sont stockées sous forme d'entiers . Ce que nous voyons de nos yeux est déjà formaté en fonction des paramètres de SQL Server. Peu importe combien de fois nous changeons de langue et de format de date, la valeur stockée restera la même. Il est inutile de penser à stocker des dates dans un format spécifique.
- Il existe 4 façons de formater les dates :CONVERTIR , DÉFINIR LA LANGUE , RÉGLER LE FORMAT DE DATE , et FORMAT .
- Si vous devez transformer des dates en chaînes et vice versa, utilisez le format ISO 8601 .
- Il existe 3 autres façons de gérer les formats de date :
- utilisation de contrôles sensibles à la date dans votre application ;
- transformer les dates en chaînes uniquement lorsque cela est nécessaire;
- définir le fuseau horaire requis, la culture, la date/l'heure du serveur au démarrage, le cas échéant .
Pensez-vous que cela sera utile pour vous et pour les autres ? Ensuite, partagez cet article sur vos plateformes de médias sociaux préférées.