extraire_date extravagant #4830

Open
opened 1 month ago by JLuc · 9 comments
JLuc commented 1 month ago

cf https://git.spip.net/spip/spip/src/branch/master/ecrire/inc/filtres_dates.php#L24

Le phpdoc commence par
"Extrait une date d'un texte et renvoie le résultat au format de date SQL"
et termine par
"return string Date au format SQL tel que 2008-04-01"

MAIS au milieu du phpdoc on découvre un
"Les jours ne sont pas pris en compte et le résultat est toujours le 1er du mois."
C'est contradictoire avec ce qui précède, mais c'est effectivement ce que fait la fonction !

Avec un fonctionnement aussi extravagant, il n'est pas étonnant que la fonction ne soit présente nulle part sur la zone... et ne soit pas documentée en français sur spip.net .

Pour être exhaustif, elle fait tout de même 2 apparitions :

Je propose donc de mettre une fin à cette extravagance : que extraire_date renvoie une vraie date SQL, complète, avec le jour.

cf https://git.spip.net/spip/spip/src/branch/master/ecrire/inc/filtres_dates.php#L24 Le phpdoc commence par "Extrait une date d'un texte et renvoie le résultat au format de date SQL" et termine par "return string Date au format SQL tel que `2008-04-01`" MAIS au milieu du phpdoc on découvre un "Les jours ne sont pas pris en compte et le résultat est toujours le 1er du mois." C'est contradictoire avec ce qui précède, mais c'est effectivement ce que fait la fonction ! Avec un fonctionnement aussi extravagant, il n'est pas étonnant que la fonction ne soit présente nulle part sur la zone... et ne soit pas documentée en français sur spip.net . Pour être exhaustif, elle fait tout de même 2 apparitions : - son test unitaire, - dans le plugin "aspirateur" où l'autrice apprécierait visiblement avoir une vraie date complète puisqu'à défaut c'est `gmdate("Y-m-d\TH:i:s\Z");` qui est employé. cf https://git.spip.net/spip-contrib-extensions/aspirateur/src/branch/master/inc/aspirer_rss.php#L116 Je propose donc de mettre une fin à cette extravagance : que extraire_date renvoie une vraie date SQL, complète, avec le jour.
Poster

Erreur : elle est bien documentée sur spip.net, avec un warning dédié à cette spécifité. https://www.spip.net/fr_article5516.html
Il me semble tout de même souhaitable de corriger.

Erreur : elle est bien documentée sur spip.net, avec un warning dédié à cette spécifité. https://www.spip.net/fr_article5516.html Il me semble tout de même souhaitable de corriger.
Owner

Pourquoi pas. Je te propose (ou quelqu'un) de faire une PR pour ça.
Il faudrait ajouter en même temps des tests unitaires parce que bon.
Ci dessous un code valide qui fait la demande.

Ce qui me gène tout de même c'est le [^0-9]* dans la regex (déjà présente dans l'ancienne fonction) qui du coup peut chercher une date coupée dans un grand texte…
Tel que : "En 2012 à l’orée du bois se trouvait 10 chevaux et 4 biches.", qui sort la date "2012-10-04" (ou 2012-10-01 avant cette proposition).
Donc l'usage est possiblement assez limité de cette fonction si laissée telle quelle.


/**
 * Extrait une date d'un texte et renvoie le résultat au format de date SQL
 *
 * L'année et le mois doivent être numériques.
 * Le séparateur entre l'année et le mois peut être un `-`, un `:` ou un texte
 * quelconque ne contenant pas de chiffres.
 *
 * Si un numéro de jour valide n'est pas indiqué, le résultat est alors le 1er du mois.
 *
 * `link https://www.spip.net/5516
 * `param string $texte
 *    Texte contenant une date tel que `2008-04`
 * `return string
 *    Date au format SQL tel que `2008-04-01`
 **/
function extraire_date($texte) {
	// format = 2001-08-12 ou 2001-08
	$has_date = preg_match(
		",
		# une annee
		(?P<annee>[1-2][0-9]{3})
		# des caracteres sans numeros
		[^0-9]*
		# un mois
		(?P<mois>1[0-2]|0?[1-9])
		(?:
			# des caracteres sans numeros
			[^0-9]*
			# un jour
			(?P<jour>3[0-1]|[1-2][0-9]|0?[1-9])
		)?
		,x", 
		$texte, 
		$regs
	);
	if ($has_date) {
		$date = [
			$regs["annee"], 
			sprintf("%02d", $regs["mois"]), 
			sprintf("%02d", $regs["jour"] ?? "01") 
		];
		return implode("-", $date);
	}
}
</pre>

----


#SQUELETTE 

#SET{liste,#LISTE{
    "Une date 2020 01",
    "Une date 2020 12 autre",
    "Une date 2020 autre 12 autre",
    "Une date 2021 12 01",
    "Une date 2021 12 00",
    "Une date 2021 12 31",
    "Une date 2021 12 32",
    "Une date 2021 autre 12 date 21",
    "En 2012 à l’orée du bois se trouvait 10 chevaux et 4 biches."
}}

<dl>
<BOUCLE_extraire(DATA){source table, #GET{liste}}>
<dt>#VALEUR</dt>
<dd>[(#VALEUR|extraire_date)]</dd>
</BOUCLE_extraire>
</dl>


Sortie :


Une date 2020 01
    2020-01-01
Une date 2020 12 autre
    2020-12-01
Une date 2020 autre 12 autre
    2020-12-01
Une date 2021 12 01
    2021-12-01
Une date 2021 12 00
    2021-12-01
Une date 2021 12 31
    2021-12-31
Une date 2021 12 32
    2021-12-03
Une date 2021 autre 12 date 21
    2021-12-21
En 2012 à l’orée du bois se trouvait 10 chevaux et 4 biches.
    2012-10-04 
Pourquoi pas. Je te propose (ou quelqu'un) de faire une PR pour ça. Il faudrait ajouter en même temps des tests unitaires parce que bon. Ci dessous un code valide qui fait la demande. Ce qui me gène tout de même c'est le `[^0-9]*` dans la regex (déjà présente dans l'ancienne fonction) qui du coup peut chercher une date coupée dans un grand texte… Tel que : "En 2012 à l’orée du bois se trouvait 10 chevaux et 4 biches.", qui sort la date "2012-10-04" (ou 2012-10-01 avant cette proposition). Donc l'usage est possiblement assez limité de cette fonction si laissée telle quelle. ``` /** * Extrait une date d'un texte et renvoie le résultat au format de date SQL * * L'année et le mois doivent être numériques. * Le séparateur entre l'année et le mois peut être un `-`, un `:` ou un texte * quelconque ne contenant pas de chiffres. * * Si un numéro de jour valide n'est pas indiqué, le résultat est alors le 1er du mois. * * `link https://www.spip.net/5516 * `param string $texte * Texte contenant une date tel que `2008-04` * `return string * Date au format SQL tel que `2008-04-01` **/ function extraire_date($texte) { // format = 2001-08-12 ou 2001-08 $has_date = preg_match( ", # une annee (?P<annee>[1-2][0-9]{3}) # des caracteres sans numeros [^0-9]* # un mois (?P<mois>1[0-2]|0?[1-9]) (?: # des caracteres sans numeros [^0-9]* # un jour (?P<jour>3[0-1]|[1-2][0-9]|0?[1-9]) )? ,x", $texte, $regs ); if ($has_date) { $date = [ $regs["annee"], sprintf("%02d", $regs["mois"]), sprintf("%02d", $regs["jour"] ?? "01") ]; return implode("-", $date); } } </pre> ---- #SQUELETTE #SET{liste,#LISTE{ "Une date 2020 01", "Une date 2020 12 autre", "Une date 2020 autre 12 autre", "Une date 2021 12 01", "Une date 2021 12 00", "Une date 2021 12 31", "Une date 2021 12 32", "Une date 2021 autre 12 date 21", "En 2012 à l’orée du bois se trouvait 10 chevaux et 4 biches." }} <dl> <BOUCLE_extraire(DATA){source table, #GET{liste}}> <dt>#VALEUR</dt> <dd>[(#VALEUR|extraire_date)]</dd> </BOUCLE_extraire> </dl> ``` ---- Sortie : ``` Une date 2020 01 2020-01-01 Une date 2020 12 autre 2020-12-01 Une date 2020 autre 12 autre 2020-12-01 Une date 2021 12 01 2021-12-01 Une date 2021 12 00 2021-12-01 Une date 2021 12 31 2021-12-31 Une date 2021 12 32 2021-12-03 Une date 2021 autre 12 date 21 2021-12-21 En 2012 à l’orée du bois se trouvait 10 chevaux et 4 biches. 2012-10-04 ```
Owner

Il faut return "" ou null aussi si on trouve rien (la fonction ne le fait pas actuellement).

Il faut return "" ou null aussi si on trouve rien (la fonction ne le fait pas actuellement).
Owner
Une date 2021 12 32
    2021-12-03

Ça retourne une date "03" puisque 32 n'est pas un jour valide, mais 3 peut l'être.

``` Une date 2021 12 32 2021-12-03 ``` Ça retourne une date "03" puisque 32 n'est pas un jour valide, mais 3 peut l'être.
Poster

Donc dans le cas foireux "2021 12 32" tu préconises que ça renvoie quoi : une date ? laquelle ? ou "", ou null ?

Donc dans le cas foireux "2021 12 32" tu préconises que ça renvoie quoi : une date ? laquelle ? ou "", ou null ?
Poster

On peut la virer aussi...
OU lui définir une vraie fonctionnalité.

On peut la virer aussi... OU lui définir une vraie fonctionnalité.
Owner

J'ai fait un peu d'archéologie:

Elle a ensuite eu le droit à son PHPDoc et à être changée de fichier mais n'a plus jamais changée.

@marcimat pour remplacer le [^0-9]* je proposerais bien un [\s\/\-\.]* qui sera plus restrictif mais devrait couvrir tous les cas de la vie réelles en évitant ce qui n'est manifestement pas une date...

Et oui, si la fonction doit être remaniée, il faut lui écrire un test unitaire en même temps, c'est impératif !

J'ai fait un peu d'archéologie: - la fonction date de https://git.spip.net/spip/spip/commit/c8b0e3f740657bddb55b4ca9913c73840454f81d - améliorée ensuite par - https://git.spip.net/spip/spip/commit/c1bed3e3cac6b24d401818dd3484b0c23f40ae68 - https://git.spip.net/spip/spip/commit/11b18be76f100187ffa36b277c19a2d0d2dcdfbe Elle a ensuite eu le droit à son PHPDoc et à être changée de fichier mais n'a plus jamais changée. @marcimat pour remplacer le `[^0-9]*` je proposerais bien un `[\s\/\-\.]*` qui sera plus restrictif mais devrait couvrir tous les cas de la vie réelles en évitant ce qui n'est manifestement pas une date... Et oui, si la fonction doit être remaniée, il faut lui écrire un test unitaire en même temps, c'est impératif !
Poster

Là on sait pas ce que ça doit faire, ce que ça doit renvoyer et comment ça doit gérer les erreurs, car ... ya pas de besoin.
Pour faire simple on peut la virer ?

Là on sait pas ce que ça doit faire, ce que ça doit renvoyer et comment ça doit gérer les erreurs, car ... ya pas de besoin. Pour faire simple on peut la virer ?
Poster

Fil indique « C'est ce que le mdiplo utilise pour déterminer la date d'un numéro du journal à partir du titre de la rubrique correspondante. Si ça gêne il faut l'enlever et booz le remettra dans les plug-ins privés du diplo »

Fil indique « C'est ce que le mdiplo utilise pour déterminer la date d'un numéro du journal à partir du titre de la rubrique correspondante. Si ça gêne il faut l'enlever et booz le remettra dans les plug-ins privés du diplo »
Sign in to join this conversation.
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
There is no content yet.