Voici une petite fonction assez pratique. Qui n’a pas été embêter par une colonne au format texte et contenant des dates impossibles à formater correctement en raison du manque de structuration de la donnée ? Voici « enfin » une fonction vous permettant de nettoyer tout ça.
La sortie est au format texte, il faudra donc typer la données par la suite.
Les variables au début de définition de la fonction permettent de connaitre les séparateurs supportés.
Voici un tableau avec quelques exemples (dont un seul ne fonctionne pas, saurez vous le trouver ?) :
| Valeur initiale | Valeur finale | Commentaire |
|---|---|---|
| 2020/03/01 | 2020-03-01 00:00:00 | |
| 2020/04/02 à 15h33 | 2020-04-02 15:33:00 | Les heures sont détectées |
| le 03/05/2020 | 2020-05-03 00:00:00 | Le texte ne pose pas de problème |
| 06/07/2020, 12h15 | 2020-07-06 12:15:00 | Les virgules sont autorisées |
| 4/08/2020 | 2020-08-04 00:00:00 | Pas besoin de 0 en début de nombre |
| 07/9/2020,12h | 2020-09-07 12:00:00 | |
| 09//08/2020 | 2020-08-09 00:00:00 | Les erreurs sont automatiquement corrigées |
| 09/08/ 2020 | 2020-08-09 00:00:00 | |
| 05/15/2020 | 2020-05-15 00:00:00 | Les dates américaines ne posent pas de problèmes |
| 05/15 //2020 | 2020-05-15 00:00:00 | |
| 17/102/2020 | 2020-01-01 00:00:00 | Erreur non identifiable : seul cas de date non reconnue |
| 18/03/19 | 2019-03-18 00:00:00 | Les dates à deux chiffres sont reconnues (l’année 30 fait la limite : 2029 / 1930) |
| 18/03/45 | 1945-03-18 00:00:00 | |
| 45/03/18 | 1945-03-18 00:00:00 | Les dates à deux chiffres dans l’autre sens sont aussi détectées |
| 10.10 2020 12/42-12 | 2020-10-10 12:42:12 | Séparateurs : point, espace, slash, tiret et divers textes |
| 20121011 | 2012-10-11 00:00:00 | Identifié par défaut comme aaaammjj : attention aux dates américaines non reconnues |
| 20201010 | 2020-10-10 00:00:00 | |
| 20212020 | 2021-01-01 00:00:00 | |
| 20122010 | 2010-12-20 00:00:00 | Identifié comme jjmmaaaa car l’inverse aurait impliqué un 20ème mois |
| 10102020 | 2020-10-10 00:00:00 | |
| 2020 | 2020-01-01 00:00:00 | L’année est complétée avec une date par défaut |
| 11 novembre 2020 | 2020-11-11 00:00:00 | Les mois textuels sont supportés (accentués ou non) |
| Aout 2018 | 2018-08-01 00:00:00 | Le numéro du jour n’est pas obligatoire |
| Mai 45 | 1945-05-01 00:00:00 | L’année peut être sur deux chiffres |
| le 12 décembre | 1900-12-12 00:00:00 | Une année par défaut est appliquée si elle n’est pas détectée |
| j’arrive le 22 décembre 2020, 15h | 2020-12-22 15:00:00 | Les phrases sont supportées |
| le 6 octobre 2020 à 6h27 | 2020-10-13 06:27:00 | |
| Je m’appelle Arthur, j’ai 3 ans et je suis né le 5 juillet 1964 à 8h32 | 1964-07-05 08:32:00 | La date est détectée malgré la présence d’un autre nombre |
| july 14, 2020 | 2020-07-14 00:00:00 | Les dates anglaises sont supportées |
| maybe the 15 june 2020 @ 12 | 2020-06-15 12:00:00 | L’heure est détectée ici aussi |
| maybe the 16 august 2020 at 12 o’clock 15 minutes | 2020-08-16 12:15:00 | Le o’clock est également supporté |
| maybe the 16th august 2020 at 12 o’clock | 2020-08-16 12:00:00 |
Vous trouverez également une requête l’utilisant et vous montrant les performance de celle-ci :
SELECT
column1 AS "Valeur initiale",
public.ab_UltimateDateDetector(column1,'null','',0) AS "Valeur finale",
column2 AS "Commentaire"
FROM
(
VALUES
('2020/03/01', ''),
('2020/04/02 à 15h33', 'Les heures sont détectées'),
('le 03/05/2020', 'Le texte ne pose pas de problème'),
('06/07/2020, 12h15', 'Les virgules sont autorisées'),
('4/08/2020', 'Pas besoin de 0 en début de nombre'),
('07/9/2020,12h', ''),
('09//08/2020', 'Les erreurs sont automatiquement corrigées'),
('09/08/ 2020', ''),
('05/15/2020', 'Les dates américaines ne posent pas de problèmes'),
('05/15 //2020', ''),
('17/102/2020', 'Erreur non identifiable : seul cas de date non reconnue'),
('18/03/19', 'Les dates à deux chiffres sont reconnues (l''année 30 fait la limite : 2029 / 1930)'),
('18/03/45', ''),
('45/03/18', 'Les dates à deux chiffres dans l''autre sens sont aussi détectées'),
('01-sept-18', 'Les dates à deux chiffres avec mois en lettre sont détectées'),
('10.10 2020 12/42-12', 'Séparateurs : point, espace, slash, tiret et divers textes'),
('20121011', 'Identifié par défaut comme aaaammjj : attention aux dates américaines non reconnues'),
('20201010', ''),
('20212020', ''),
('20122010', 'Identifié comme jjmmaaaa car l''inverse aurait impliqué un 20ème mois'),
('10102020', ''),
('2020', 'L''année est complétée avec une date par défaut'),
('11 novembre 2020', 'Les mois textuels sont supportés (accentués ou non)'),
('Aout 2018', 'Le numéro du jour n''est pas obligatoire'),
('Mai 45', 'L''année peut être sur deux chiffres'),
('le 12 décembre', 'Une année par défaut est appliquée si elle n''est pas détectée'),
('j''arrive le 22 décembre 2020, 15h', 'Les phrases sont supportées'),
('le 6 octobre 2020 à 6h27', ''),
('Je m''appelle Arthur, j''ai 3 ans et je suis né le 5 juillet 1964 à 8h32', 'La date est détectée malgré la présence d''un autre nombre'),
('july 14, 2020', 'Les dates anglaises sont supportées'),
('maybe the 15 june 2020 @ 12', 'L''heure est détectée ici aussi'),
('maybe the 16 august 2020 at 12 o''clock 15 minutes', 'Le o''clock est également supporté'),
('maybe the 16th august 2020 at 12 o''clock', '')
) AS valeur
;
-- Fonction ab_UltimateDateDetector
CREATE OR REPLACE FUNCTION public.ab_UltimateDateDetector(date_to_format TEXT, output_format TEXT = null, flag TEXT = null, verbosity int = null)
RETURNS TEXT AS
$corps$
-- Auteur : Arthur Bazin - https://www.arthurbazin.com
-- Description
-- Cette fonction permet de détecter tout type de date et les retourne au format text suivant : aaaa-mm-jj hh:mm:ss.
-- Paramètres :
-- date_to_format : la date à formater
-- output_format : en cas de non correspondance, quelle valeur sortir :
-- null (défaut) = NULL,
-- empty = '',
-- same = valeur initiale
-- flag : restriction sur les formats à détecter (pour accélérer la fonction)
-- Tous les drapeaux peuvent être combinés pour rechercher plusieurs formats :
-- Type : (peuvent être combinés) ('' = 'td')
-- t : date avec heure
-- d : date sans heure
-- Format : (peuvent être combinés) ('' = 'IFEUT')
-- I : format ISO uniquement (2020/12/25)
-- F : format FR uniquement (25/12/2020)
-- E : format ENG uniquement (december 25th, 2020)
-- U : format US uniquement (2020/25/12 ou 12/25/2020)
-- T : format mois textuel (1er janvier 2020) (n''inclut pas les formats ENG)
-- verbosity : Niveau de verbosité de la fonction dans la sortie de la BDD (notice)
-- De 0 (défaut) à 3
DECLARE
-- Flag des tests
flag_type TEXT := '';
flag_format TEXT := '';
-- Boucle d'expression régulière
liste_regex record;
-- Récupération regex
rxm text[];
-- Formatage date
-- Suffixes
-- Année
suf_a text := 'années|année|ans|an|years|year|y| |\/|-|\.' ;
-- Mois
suf_m text := 'mois|month|m| |\/|-|\.' ;
-- Jour
suf_j text := 'jours|jour|j|days|day|d|st|nd|rd|th| |\/|-|\.' ;
-- Heure
suf_h text := 'heures|heure|h|ours|our|oclock|o''clock|o| |\/|-|:|\.' ;
-- Minute
suf_min text := 'minutes|minute|min|m| |\/|-|:|\.' ;
-- Seconde
suf_sec text := 'secondes|seconde|seconds|second|sec|s| |\/|-|:|\.' ;
-- Séparateur
-- date/horaire
sep_d_h text := '-| |a|à|@|at|,' ;
-- Répétition
-- Répétition minimale du motif
rep_min text := '1' ;
-- Répétition maximale du motif
rep_max text := '4' ;
-- Variantes
-- Janvier
vari_m_ja text[] := ARRAY ['janvier|janv|january|jan', '01'] ;
-- Février
vari_m_fev text[] := ARRAY ['février|fevrier|fév|fev|february|feb', '02'] ;
-- Mars
vari_m_ma text[] := ARRAY ['mars|march|mar', '03'] ;
-- Avril
vari_m_av text[] := ARRAY ['avril|avr|av|april|apr|ap', '04'] ;
-- Mai
vari_m_mai text[] := ARRAY ['mai|may', '05'] ;
-- Juin
vari_m_juin text[] := ARRAY ['juin|june|jun', '06'] ;
-- Juillet
vari_m_juil text[] := ARRAY ['juillet|july|jul', '07'] ;
-- Aout
vari_m_aout text[] := ARRAY ['aout|août|aou|august|aug|au', '08'] ;
-- Septembre
vari_m_sept text[] := ARRAY ['septembre|september|sept|sep', '09'] ;
-- Octobre
vari_m_oct text[] := ARRAY ['octobre|october|oct', '10'] ;
-- Novembre
vari_m_nov text[] := ARRAY ['novembre|november|nov', '11'] ;
-- Décembre
vari_m_dec text[] := ARRAY ['decembre|décembre|december|dec', '12'] ;
-- REGEX
-- Année
re_a text := '([0-2][0-9][0-9][0-9])(?: )*(?:' || suf_a || '){' || rep_min || ',' || rep_max || '}(?: )*' ;
re_a_f text := '([0-2][0-9][0-9][0-9])(?: )*(?:' || suf_a || '){0,' || rep_max || '}(?: )*' ;
re_a2 text := '([0-9][0-9])(?: )*(?:' || suf_a || '){' || rep_min || ',' || rep_max || '}(?: )*' ;
re_a2_f text := '([0-9][0-9])(?: )*(?:' || suf_a || '){0,' || rep_max || '}(?: )*' ;
-- Mois
re_m text := '(0[1-9]|1[0-2]|[1-9])(?: )*(?:' || suf_m || '){' || rep_min || ',' || rep_max || '}(?: )*' ;
re_m_f text := '(0[1-9]|1[0-2]|[1-9])(?: )*(?:' || suf_m || '){0,' || rep_max || '}(?: )*' ;
-- Mois texte
re_m_txt TEXT := '(' || vari_m_ja[1] || '|' || vari_m_fev[1] || '|' || vari_m_ma[1] || '|' || vari_m_av[1] || '|' || vari_m_mai[1] || '|' || vari_m_juin[1] || '|' || vari_m_juil[1] || '|' || vari_m_aout[1] || '|' || vari_m_sept[1] || '|' || vari_m_oct[1] || '|' || vari_m_nov[1] || '|' || vari_m_dec[1] || ')';
-- Jour
re_j text := '(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[1-9])(?: )*(?:' || suf_j || '){' || rep_min || ',' || rep_max || '}(?: )*' ;
re_j_f text := '(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[1-9])(?: )*(?:' || suf_j || '){0,' || rep_max || '}(?: )*' ;
re_j2 text := '(0[1-9]|1[0-9]|2[0-9]|3[0-1])(?: )*(?:' || suf_j || '){' || rep_min || ',' || rep_max || '}(?: )*' ;
-- Heure
re_h text := '(0[1-9]|1[0-9]|2[0-3]|[0-9]) *(?:' || suf_h || '){' || rep_min || ',' || rep_max || '}' ;
re_h_f text := '(0[1-9]|1[0-9]|2[0-3]|[0-9]) *(?:' || suf_h || '){0,' || rep_max || '}' ;
-- Minute
re_min text := '([0-5][0-9]|[0-9])(?:' || suf_min || '){' || rep_min || ',' || rep_max || '}' ;
re_min_f text := '([0-5][0-9]|[0-9])(?:' || suf_min || '){0,' || rep_max || '}' ;
-- Seconde
re_sec text := '([0-5][0-9]|[0-9])(?:' || suf_sec || '){0,' || rep_max || '}' ;
--Séparateur date/horaire
re_sep text := '(?: )*(?:' || sep_d_h || '){' || rep_min || ',' || rep_max || '}(?: )*' ;
-- Valeurs finales
-- Intermédiaires (valeur par défaut)
-- Année
fin_annee text := '1900' ;
-- Mois
fin_mois text := '01' ;
-- Jour
fin_jour text := '01' ;
-- Heure
fin_heure text := '00' ;
-- Minute
fin_min text := '00' ;
-- Seconde
fin_sec text := '00' ;
-- Sortie
formated_date TEXT;
BEGIN
-- Message d'information
IF verbosity >= 1 THEN
RAISE NOTICE USING MESSAGE =
chr(10) ||
$a$- - - - - - - - - - - - - - - - - - - - - - -$a$ || chr(10) ||
$b$Démarrage traitement $b$ || chr(10) || chr(10)
;
END IF;
-- Gestion paramètres
IF output_format IS NULL OR output_format = ''
THEN output_format = 'null';
END IF;
IF flag IS NULL OR flag = ''
THEN flag = 'tdIFEUT';
END IF;
IF verbosity IS NULL
THEN verbosity = 0;
END IF;
-- Traitement du paramètre flag
IF flag LIKE '%t%' THEN flag_type = flag_type || 't'; END IF;
IF flag LIKE '%d%' THEN flag_type = flag_type || 'd'; END IF;
IF flag_type = '' THEN flag_type = 'dt'; END IF;
IF flag LIKE '%I%' THEN flag_format = flag_format || 'I'; END IF;
IF flag LIKE '%F%' THEN flag_format = flag_format || 'F'; END IF;
IF flag LIKE '%E%' THEN flag_format = flag_format || 'E'; END IF;
IF flag LIKE '%U%' THEN flag_format = flag_format || 'U'; END IF;
IF flag LIKE '%T%' THEN flag_format = flag_format || 'T'; END IF;
IF flag_format = '' THEN flag_format = 'IFEUT'; END IF;
-- Message d'information
IF verbosity >= 3 THEN
RAISE NOTICE USING MESSAGE =
$a$Paramètres :$a$ || chr(10) ||
$b$ output_format : $b$ || output_format || chr(10) ||
$c$ flag : $c$ || flag || $d$ - flag_type : $d$ || flag_type || $e$ - flag_format : $e$ || flag_format || chr(10) ||
$f$ verbosity : $f$ || verbosity::text || chr(10) || chr(10)
;
END IF;
-- Message d'information
IF verbosity >= 1 THEN
RAISE NOTICE USING MESSAGE = $a$Valeur traitée : '$a$ || date_to_format::TEXT || $b$'$b$ || chr(10)
;
END IF;
-- Pour chaque motif REGEX possible
-- Chaque élément est composé de :
-- Une description du motif
-- Un motif REGEX
-- L'ordre de récupération des valeurs
-- Les flags associés
FOR liste_regex IN (
SELECT
column1 AS exemple,
column2 AS regex_recherche,
column3 AS ordre_valeur,
column4 AS flag
FROM
(
VALUES
(
'2020/01/01 23:59:59',
re_a || re_m || re_j_f || re_sep || re_h || re_min || re_sec,
ARRAY['annee','mois','jour','heure','min','sec'],
'tI'
),
(
'2020/21/01 23:59:59',
re_a || re_j || re_m_f || re_sep || re_h || re_min || re_sec,
ARRAY['annee','jour','mois','heure','min','sec'],
'tU'
),
(
'01/01/2020 23:59:59',
re_j || re_m || re_a_f || re_sep || re_h || re_min || re_sec,
ARRAY['jour','mois','annee','heure','min','sec'],
'tF'
),
(
'01/21/2020 23:59:59',
re_m || re_j || re_a_f || re_sep || re_h || re_min || re_sec,
ARRAY['mois','jour','annee','heure','min','sec'],
'tU'
),
(
'2020/01/01 23:59',
re_a || re_m || re_j_f || re_sep || re_h || re_min_f,
ARRAY['annee','mois','jour','heure','min'],
'tI'
),
(
'2020/21/01 23:59',
re_a || re_j || re_m_f || re_sep || re_h || re_min_f,
ARRAY['annee','jour','mois','heure','min'],
'tU'
),
(
'01/01/2020 23:59',
re_j || re_m || re_a_f || re_sep || re_h || re_min_f,
ARRAY['jour','mois','annee','heure','min'],
'tF'
),
(
'01/21/2020 23:59',
re_m || re_j || re_a_f || re_sep || re_h || re_min_f,
ARRAY['mois','jour','annee','heure','min'],
'tU'
),
(
'2020/01/01 23',
re_a || re_m || re_j_f || re_sep || re_h_f,
ARRAY['annee','mois','jour','heure'],
'tI'
),
(
'2020/21/01 23',
re_a || re_j || re_j_f || re_sep || re_h_f,
ARRAY['annee','jour','mois','heure'],
'tU'
),
(
'01/01/2020 23',
re_j || re_m || re_a_f || re_sep || re_h_f,
ARRAY['jour','mois','annee','heure'],
'tF'
),
(
'01/21/2020 23',
re_m || re_j || re_a_f || re_sep || re_h_f,
ARRAY['mois','jour','annee','heure'],
'tU'
),
(
'2020/01/01',
re_a || re_m || re_j_f,
ARRAY['annee','mois','jour'],
'dI'
),
(
'2020/21/01',
re_a || re_j || re_m_f,
ARRAY['mois','jour','annee'],
'dU'
),
(
'01/01/2020',
re_j || re_m || re_a_f,
ARRAY['jour','mois','annee'],
'dF'
),
(
'01/21/2020',
re_m || re_j || re_a_f,
ARRAY['mois','jour','annee'],
'dU'
),
(
'01/01/45',
re_j2 || re_m || re_a2_f,
ARRAY['jour','mois','annee'],
'dF'
),
(
'45/01/01',
re_a2 || re_m || re_j_f,
ARRAY['annee','mois','jour'],
'dF'
),
(
'01-sept-45',
re_j2 || re_m_txt || '(?:' || suf_m || '){' || rep_min || ',' || rep_max || '}(?: )*' || re_a2_f,
ARRAY['jour','mois','annee'],
'dF'
),
(
'20200101',
'([0-2][0-9][0-9][0-9])(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])',
ARRAY['annee','mois','jour'],
'dI'
),
(
'01012020',
'(0[1-9]|1[0-9]|2[0-9]|3[0-1])(0[1-9]|1[0-2])([0-2][0-9][0-9][0-9])',
ARRAY['jour','mois','annee'],
'dF'
),
(
'20200101000000',
'([0-2][0-9][0-9][0-9])(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])(0[1-9]|1[0-9]|2[0-3])([0-5][0-9])([0-5][0-9])',
ARRAY['annee','mois','jour','heure','min','sec'],
'tI'
),
(
'01012020000000',
'(0[1-9]|1[0-9]|2[0-9]|3[0-1])(0[1-9]|1[0-2])([0-2][0-9][0-9][0-9])(0[1-9]|1[0-9]|2[0-3])([0-5][0-9])([0-5][0-9])',
ARRAY['jour','mois','annee','heure','min','sec'],
'tF'
),
(
'1 janvier 2020 à 15h30m12s',
'(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[1-9])' || '(?: |st|nd|rd|th)*' || re_m_txt || '(?: )*' || '([0-2][0-9][0-9][0-9])' || re_sep || re_h || re_min || re_sec,
ARRAY['jour','mois','annee','heure', 'min', 'sec'],
'tT'
),
(
'1 janvier 2020 à 15h30m',
'(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[1-9])' || '(?: |st|nd|rd|th)*' || re_m_txt || '(?: )*' || '([0-2][0-9][0-9][0-9])' || re_sep || re_h || re_min_f,
ARRAY['jour','mois','annee','heure', 'min'],
'tT'
),
(
'1 janvier 2020 à 15h',
'(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[1-9])' || '(?: |st|nd|rd|th)*' || re_m_txt || '(?: )*' || '([0-2][0-9][0-9][0-9])' || re_sep || re_h_f,
ARRAY['jour','mois','annee','heure'],
'tT'
),
(
'1 janvier 2020',
'(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[1-9])' || '(?: |st|nd|rd|th)*' || re_m_txt || '(?: )*' || '([0-2][0-9][0-9][0-9])',
ARRAY['jour','mois','annee'],
'dT'
),
(
'1 janvier',
'(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[1-9])' || '(?: |st|nd|rd|th)*' || re_m_txt,
ARRAY['jour','mois'],
'dT'
),
(
'janvier 2020',
re_m_txt || '(?: )*' || re_a_f,
ARRAY['mois','annee'],
'dT'
),
(
'january 1st, 2020 at 12h30min18s',
re_m_txt || '(?: )*' || '(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[1-9])' || '(?: |st|nd|rd|th)*' || '[, ]*' || '([0-2][0-9][0-9][0-9])' || re_sep || re_h || re_min || re_sec,
ARRAY['mois','jour','annee','heure','min','sec'],
'tE'
),
(
'january 1st, 2020 at 12h30min',
re_m_txt || '(?: )*' || '(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[1-9])' || '(?: |st|nd|rd|th)*' || '[, ]*' || '([0-2][0-9][0-9][0-9])' || re_sep || re_h || re_min_f,
ARRAY['mois','jour','annee','heure','min'],
'tE'
),
(
'january 1st, 2020 at 12h',
re_m_txt || '(?: )*' || '(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[1-9])' || '(?: |st|nd|rd|th)*' || '[, ]*' || '([0-2][0-9][0-9][0-9])' || re_sep || re_h_f,
ARRAY['mois','jour','annee','heure'],
'tE'
),
(
'january 1st, 2020',
re_m_txt || '(?: )*' || '(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[1-9])' || '(?: |st|nd|rd|th)*' || '[, ]*' || '([0-2][0-9][0-9][0-9])',
ARRAY['mois','jour','annee'],
'dE'
),
(
'janvier 45',
re_m_txt || '(?: )*' || re_a2_f,
ARRAY['mois','annee'],
'dT'
),
(
'2020',
'(?:.* )?' || re_a_f || '(?: .*)?',
ARRAY['annee'],
'dIFUET'
)
) AS valeur
WHERE
(regexp_split_to_array(column4, '')) && (regexp_split_to_array(flag_type, ''))
AND
(regexp_split_to_array(column4, '')) && (regexp_split_to_array(flag_format, ''))
)
-- Pour chaque élément de la liste des motifs REGEX possible
LOOP
-- On démarre une transaction pour capturer les erreurs
BEGIN
-- On récupère le résultat de la recherche REGEX
rxm = regexp_matches(date_to_format, liste_regex.regex_recherche, 'i');
-- Message d'information
IF verbosity >= 3 THEN
RAISE NOTICE USING MESSAGE =
$a$Format testé : $a$ || liste_regex.exemple || chr(10) ||
$b$ REGEX recherche : $b$ || liste_regex.regex_recherche
;
END IF;
-- Si la recherche REGEX donne un résultat
IF rxm IS NOT NULL THEN
-- Message d'information
IF verbosity >= 2 THEN
RAISE NOTICE USING MESSAGE =
chr(10) ||
$a$Valeurs identifiées : $a$ || array_to_string(rxm,' | ') || chr(10) ||
$b$ Ordre des valeurs : $b$ || array_to_string(liste_regex.ordre_valeur,' | ')
;
END IF;
-- On boucle sur le nombre d'éléments retrouvés pour traiter chaque élément : année, mois, jour, heure, minute, seconde
FOR i IN 1..array_length(rxm, 1) BY 1
LOOP
-- Si l'élément du tableau rxm existe
IF rxm[i] IS NOT NULL THEN
-- On défini l'élément comme étant "tel partie" de la date par rapport à la valeur ayant la même position dans le tableau liste_regex.ordre_valeur
IF liste_regex.ordre_valeur[i] = 'annee' THEN
-- Si l'année est sur 2 chiffres
IF length(rxm[i]) = 2 THEN
IF rxm[i]::integer > 29 THEN
fin_annee = '19' || rxm[i]::TEXT;
ELSE
fin_annee = '20' || rxm[i]::TEXT;
END IF;
ELSE
fin_annee = lpad(rxm[i]::text,4,'0');
END IF;
END IF;
IF liste_regex.ordre_valeur[i] = 'mois' THEN
-- Cas particulier des mois : ils peuvent être au format texte : on test donc chaque valeur posible pour récupérer le numéro du mois
IF regexp_matches(rxm[i], '(' || vari_m_ja[1] || ')', 'i' ) IS NOT NULL THEN
fin_mois = vari_m_ja[2];
ELSIF regexp_matches(rxm[i], '(' || vari_m_fev[1] || ')', 'i' ) IS NOT NULL THEN
fin_mois = vari_m_fev[2];
ELSIF regexp_matches(rxm[i], '(' || vari_m_ma[1] || ')', 'i' ) IS NOT NULL THEN
fin_mois = vari_m_ma[2];
ELSIF regexp_matches(rxm[i], '(' || vari_m_av[1] || ')', 'i' ) IS NOT NULL THEN
fin_mois = vari_m_av[2];
ELSIF regexp_matches(rxm[i], '(' || vari_m_mai[1] || ')', 'i' ) IS NOT NULL THEN
fin_mois = vari_m_mai[2];
ELSIF regexp_matches(rxm[i], '(' || vari_m_juin[1] || ')', 'i' ) IS NOT NULL THEN
fin_mois = vari_m_juin[2];
ELSIF regexp_matches(rxm[i], '(' || vari_m_juil[1] || ')', 'i' ) IS NOT NULL THEN
fin_mois = vari_m_juil[2];
ELSIF regexp_matches(rxm[i], '(' || vari_m_aout[1] || ')', 'i' ) IS NOT NULL THEN
fin_mois = vari_m_aout[2];
ELSIF regexp_matches(rxm[i], '(' || vari_m_sept[1] || ')', 'i' ) IS NOT NULL THEN
fin_mois = vari_m_sept[2];
ELSIF regexp_matches(rxm[i], '(' || vari_m_oct[1] || ')', 'i' ) IS NOT NULL THEN
fin_mois = vari_m_oct[2];
ELSIF regexp_matches(rxm[i], '(' || vari_m_nov[1] || ')', 'i' ) IS NOT NULL THEN
fin_mois = vari_m_nov[2];
ELSIF regexp_matches(rxm[i], '(' || vari_m_dec[1] || ')', 'i' ) IS NOT NULL THEN
fin_mois = vari_m_dec[2];
ELSE
fin_mois = lpad(rxm[i]::text,2,'0');
END IF;
END IF;
IF liste_regex.ordre_valeur[i] = 'jour' THEN
fin_jour = lpad(rxm[i]::text,2,'0');
END IF;
IF liste_regex.ordre_valeur[i] = 'heure' THEN
fin_heure = lpad(rxm[i]::text,2,'0');
END IF;
IF liste_regex.ordre_valeur[i] = 'min' THEN
fin_min = lpad(rxm[i]::text,2,'0');
END IF;
IF liste_regex.ordre_valeur[i] = 'sec' THEN
fin_sec = lpad(rxm[i]::text,2,'0');
END IF;
END IF;
END LOOP;
-- La date est construite en assemblant les différents résultats
formated_date = fin_annee || '-' || fin_mois || '-' || fin_jour || ' ' || fin_heure || ':' || fin_min || ':' || fin_sec;
--RAISE NOTICE USING MESSAGE = formated_date;
-- On sort de la boucle
EXIT;
END IF;
-- On capture l'erreur si la recherche de REGEX à posé problème (surtout utile en debug)
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE USING MESSAGE =
chr(10) ||
$a$ /!\ Erreur traitement /!\$a$ || chr(10) ||
$b$ /!\ Code erreur : $b$ || SQLSTATE || $c$ - Message : $c$ || SQLERRM
;
END;
END LOOP;
-- Gestion de la valeur de sortie
-- Si aucun résultat n'a été trouvé
IF formated_date IS NULL THEN
-- Message d'information
IF verbosity >= 1 THEN
RAISE NOTICE USING MESSAGE =
chr(10) ||
$a$Aucun motif de date identifié$a$
;
END IF;
-- Le résultat est défini par rapport au paramètre "output_format"
IF output_format = 'empty' THEN
formated_date = '';
ELSIF output_format = 'same' THEN
formated_date = date_to_format;
END IF;
ELSE
-- Message d'information
IF verbosity >= 1 THEN
RAISE NOTICE USING MESSAGE =
chr(10) ||
$a$Date extraite : $a$ || formated_date
;
END IF;
END IF;
-- Message d'information
IF verbosity >= 1 THEN
RAISE NOTICE USING MESSAGE =
chr(10) ||
$a$Fin du traitement $a$ || chr(10) ||
$b$- - - - - - - - - - - - - - - - - - - - - - -$b$ || chr(10) ||
chr(10)
;
END IF;
-- Retour final
RETURN formated_date;
END
$corps$
LANGUAGE plpgsql
;
Cet article vous a plu ?
N'hésitez pas à le partager, il interessera surement certains de vos contacts.
Les thèmes suivants contiennent des articles en lien avec celui-ci, allez faire un tour :
BDDPostgreSQLProgrammationSQL datedatetimefonctionformatagetime