où on passe une string contenant une date formatée d'une manière "speciale", et où on passe une string contenant le format a utilisé pour decoder cette date.
J'en ai besoin parce que je recoit un fichier ou les date sont formatée en YYYYMMDD (par exemple '19920519' pour le 19 mai 1992), et donc la fonction StrToDate ne fonctionne pas.
Etant donnée que le format de date peut changé, j'aimerais donc savoir si il existe une fonction telle que celle decrite çi-dessus.
Je sais pas si mes explications sont claires, mais si jamais vous avez une idée, je suis preneur!
florenth
Messages postés1023Date d'inscriptiondimanche 1 août 2004StatutMembreDernière intervention17 août 20083 11 janv. 2008 à 19:00
Salut !
La rapidité n'est pas fonction du nombre de lignes !!
D'ailleurs, la fonction la plus rapide que j'ai pu trouver est :
<hr size="2" width="100%" />function MyStrToDateTime(const S: string): TDateTime;
const
CDigits: array['0'..'9'] of Integer = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
var
Y, M, D: Integer;
begin
Y := CDigits[S[1]] * 1000
+ CDigits[S[2]] * 100
+ CDigits[S[3]] * 10
+ CDigits[S[4]];
M := CDigits[S[5]] * 10
+ CDigits[S[6]];
D := CDigits[S[7]] * 10
+ CDigits[S[8]];
Result := EncodeDate(Y, M, D);
end;
<hr size="2" width="100%" />
NB: il y a bien une gestion d'erreurs car la fonction déclenche un EBoundError si un des caractère n'est pas un chiffre ou si la chaîne est trop courte.
NB2: elle est 11 fois plus rapide que la version modifiée de Loda par japee et pourant... 11 fois plus longue (en lignes de code) !
Sat83
Messages postés166Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention13 octobre 2008 11 janv. 2008 à 13:53
En attendant de pouvoir trouver mieux je me suis fait une petite fonction:
function StrToDatePerso(date : string) : TDate;
var
y, m, d : integer;
begin
y := StrToInt(date[1])*1000
+ StrToInt(date[2])*100
+ StrToInt(date[3])*10
+ StrToInt(date[4]);
m := StrToInt(date[5])*10
+ StrToInt(date[6]);
d := StrToInt(date[7])*10
+ StrToInt(date[8]);
StrToDatePerso := EncodeDate( y, m, d );
end;
C'est une solution provisoire pour que je puisse continué à avancer dans mon projet, donc je suis toujours à l'ecoute d'eventuelle solution que vous auriez a proposer...
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 11 janv. 2008 à 17:11
salut,
c'est peut-être pas le plus "optimizé", mais ça marche:
function yyyymmddStrToDateTime(Str:String):TDateTime;
begin
//ajout des tests si tu veux (length, ...)
result:=EncodeDate(StrToInt(copy(str,0,4)),StrToInt(copy(str,5,2)),StrToInt(copy(str,7,2)));
end;
bon code,
Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
Sat83
Messages postés166Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention13 octobre 2008 11 janv. 2008 à 19:50
Merci pour ces reponses...
Je testerais vos propositions lundi!
Mais bon, le problème reste que ces fonctions sont spécifiques au format YYYYMMDD... (vous me direz c'est mieux que rien, et je suis d'accord!).
Dommage qu'il n'existe pas de solution 'miracle' existante permettant d'obtenir un TDate a partir de 2 string (une avec la date, l'autre avec le formatage).
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 12 janv. 2008 à 13:11
Salut,
voici une approche différente avec un résultat différent
elle pourra peut être servir ne serait-ce que sur un plan éducatif
En entré nous avons : '19920519' {String}
Et en sortie nous obtenons '19/05/1992' {String} utilisable avec StrToDate
Function ReverseDate(Const Str : String): String;
Var P, Pr : PChar;
L : Integer;
Y, M, D : String;
Begin
P := PChar(Str + #0);
L := Length(Str);
Pr := P;
Inc(Pr,
L-2); // on se place à la fin
de la chaine moins 2 caractères
D := Pr;
Pr^ := #0; // on déplace la fin de la
chaine et on recommence
Dec(Pr, 2);
M := Pr;
Pr^ := #0;
Dec(Pr, 4);
Y := Pr;
Result := Format('%s/%s/%s', [D, M, Y]);
End ;
<center>Highlighted with Pas2HTML </center>
@+
Cirec
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 12 janv. 2008 à 14:19
Hello,
Oh oui, Cirec, très très intéressant pour qui veut comprendre le fonctionnement des pointeurs sur les chaînes à 0 terminal.
Mais ne penses-tu pas qu'un seul PChar suffirait ?
Function ReverseDate(Const Str : String): String;
Var Pr : PChar;
L : Integer;
Y, M, D : String;
Begin
L := Length(Str);
Pr := PChar(Str + #0);
Inc(Pr, L-2); // on se place à la fin de la chaine moins 2 caractères
D := Pr;
Pr^ := #0; // on déplace la fin de la chaine et on recommence
Dec(Pr, 2);
M := Pr;
Pr^ := #0;
Dec(Pr, 4);
Y := Pr;
Result := Format('%s/%s/%s', [D, M, Y]);
End;
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 12 janv. 2008 à 14:44
Oui tu as entièrement raison
En fait le deuxième pointeur est un vestige de la première mouture,
j'avais l'intention d'utiliser un pointeur pour l'entrée (Str) et l'autre pour la sortie (Result) ... puis j'ai changer d'avis en oubliant d'éliminer le pointeur en trop ...
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 12 janv. 2008 à 15:04
Petite précision ... ce n'est une chaine à zéro terminal mais
une chaine à double zéro terminal c'est justement cette différence qui permet de déplacer la fin de la chaine ...
Pour s'en rendre compte il suffit de remplacer :
Pr := PChar(Str + #0);
Par
Pr := PChar(Str);
Pour obtenir une belle exception à la première instruction du type :
Pr^ := #0;
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 12 janv. 2008 à 16:20
Testé sous D7 aussi :
Voici ta fonction modifiée :
function ReverseDateT(const Str: string): string;
var
Pr : PChar;
Y, M, D : string;
begin
Pr := PChar(Str); // <- modif ici
Inc(Pr, Length(Str) - 2);
D := Pr;
Pr^ := #0; // <- pas d'exception
Dec(Pr, 2);
M := Pr;
Pr^ := #0; // <- pas d'exception
Dec(Pr, 4);
Y := Pr;
Result := Format('%s/%s/%s', [D, M, Y]);
end;
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 12 janv. 2008 à 17:43
Ouais, si quelqu'un pouvait être sympa et tester ça...
C'est facile, il faut juste :
- 1 TEdit,
- 1 TLabel,
- 1 TButton.
Le code :
function ReverseDateT(const Str: string): string;
var
Pr : PChar;
Y, M, D : string;
begin
Pr := PChar(Str);
Inc(Pr, Length(Str) - 2);
D := Pr;
Pr^ := #0;
Dec(Pr, 2);
M := Pr;
Pr^ := #0;
Dec(Pr, 4);
Y := Pr;
Result := Format('%s/%s/%s', [D, M, Y]);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
ADateTime: TDateTime;
begin
ADateTime := StrToDate(ReverseDateT(ComboBox1.Text));
Label1.Caption := DateTimeToStr(ADateTime);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.Text := '19920519';
end;
Voilà. Sinon j'en connais au moins 1 qui va avoir du mal à s'endormir ce soir...